\chapter{Setting Up A Web Server\label{chap:webserver}}

You have learned how to develop CGI scripts with Perl. It is not very practical to test 
CGI scripts with the Perl interpreter alone, because you cannot easily reproduce an
environment resembling a real Web server. There are several Perl-enabled free web hosting 
services on the Internet. You may wish to test your scripts there, or on a paid web hosting
account that you own. However, that is still inconvenient having to upload and test every 
time you would like to test your scripts. Also, using a third party server for script 
testing is dangerous. First, if your script goes astray and locks itself in an infinite 
loop (this is far more easier to occur than you think), it would become a never-ending
process that sits there wasting CPU time and system resources. Every invocation of the
script concerned increases one faulty process. It does not require many clicks before the
server would eventually be brought down. Although you may start to wonder your script
has gone into an infinite loop, you cannot do anything because the processes are executed
as a system user (on a Unix system, quite likely it's a pseudo user ``nobody'') instead of 
you and, even if you have shell access to the Web server, you don't have the privilege to
terminate these faulty processes. Helplessly, a few hours you receive a furious letter
from the Web host administrator about locking up your account or so. It's not a story. This
was a pathetic experience of mine in my early years of Perl script development. Also, 
don't forget free web hosts usually don't give you access to error logs, so you would
get no clue why your scripts do not function as expected. A testing Web server comes to
rescue. In fact, you can set up an entirely free Web server in less than half an hour.
In this appendix, I would give you some instructions that guide you through setting up
a basic Perl-enabled Web server that you can use to test your CGI scripts offline. The
instructions were tested on my system, namely Windows 2000 Professional and Debian Linux
3.0 (woody). \\

\section{Apache}

You can download the latest version of Apache Web server from \link{http://httpd.apache.org}{Apache}.
For your convenience, the link to the latest version as of this writing is provided below: \\

\link{http://www.apache.org/dist/httpd/binaries/win32/apache\_2.0.47-win32-x86-no\_ssl.msi}{Apache 2.0.47 (Windows binary)} \\
\link{http://www.apache.org/dist/httpd/httpd-2.0.47.tar.gz}{Apache 2.0.47 (Unix source)} \\

\subsection{Microsoft Windows}

Note that the installation file uses the Microsoft Installer for installation. If your
Windows version is ME or 2000, you are ready to execute the installation program. If you 
use Windows XP, you need to install Windows XP Service Pack 1 first if you haven't installed
it yet. If you have older versions of Windows, you may need to install MSI Installer.
Double click on the .msi file just downloaded. If that doesn't work, you don't have MSI 
installer set up yet and need to install it first. Please search the Microsoft Web site for the
download link. \\

You should be logged in as a user whose privilege allows installation of software, say administrator.
The installation program should start. You should disable any firewall software on your 
system before proceeding with the installation. Also, if you have any other Web servers
running which binds to port 80 you should disable them first. On Windows 2000, go to the
Services window. Right click over the entry ``World Wide Web Publishing Service'' and select ``Stop''. \\ %You
%may also want to select the ``Properties'' popup menu and in the configuration window that
%appears, change the startup type of the IIS WWW service to ``manual''. 
%Alternatively, to have
%IIS and Apache running concurrently your Apache needs to bind to a different port, say 8000. 
%After Apache is successfully installed, modify the port

After you have agreed to the terms of the license
agreement and press ``next'', specify the network domain, server name and administrator's
email address. If a domain name is available on your network, enter it into ``network domain''.
Otherwise, put \mono{localhost} for both ``network domain'' and ``server name'' like I do.
You can change these settings later on in the Apache configuration file manually, so the settings
that I specify in the screenshot is generally adequate. \\ 

% apacheconfig.png
\image{!hbt}{0.9\textwidth}{!}{images/apacheconfig.eps}{Apache Installation Options}{fig:apacheconfig}

Then select installation type. Choose ``Typical'' here which is generally sufficient, unless you
would like to compile modules on your own later on (quite rare on a Windows system). Then 
choose the installation folder. The default value is usually acceptable. Installation then
begins. When installation is completed successfully, Apache should have already been started 
as a service. \\

Test your Web server by accessing http://localhost. You should see the default Apache test file, as 
shown (the language of the page may differ, but you should see a similar page with the Apache logo). \\

\image{!hbt}{0.9\textwidth}{!}{images/apachetest.eps}{Apache Default Index File}{fig:apachetest}

Now you can edit the configuration file. Go to the Start Menu $>>$ 
Apache HTTP Server 2.0.47 $>>$ Configure Apache Server $>>$ Edit the Apache httpd.conf Configuration
file. Notepad appears containing the configuration file. \\

If you would like to run IIS and Apache concurrently, search for the two lines like

\begin{lstlisting}[numbers=none,backgroundcolor=\color{CodeBackground}]
Listen 80
ServerName localhost:80
\end{lstlisting}

They are at different locations in the file and I just put them here together for convenience. 
Change the two lines to \\

\begin{lstlisting}[numbers=none,backgroundcolor=\color{CodeBackground}]
Listen 8000
ServerName localhost:8000
\end{lstlisting}

which instructs Apache to bind to port 8000 instead of port 80. IIS still gets port 80. If you don't need
(or don't have) IIS, you don't need this step. \\

Now we add in support for CGI. Find the line \\

\begin{lstlisting}[numbers=none,backgroundcolor=\color{CodeBackground}]
#AddHandler cgi-script .cgi
\end{lstlisting}

and change it to \\

\begin{lstlisting}[numbers=none,backgroundcolor=\color{CodeBackground}]
AddHandler cgi-script .cgi .pl
\end{lstlisting}

That is, remove the \# at the front and add ``.pl'' at the end. This makes Apache recognize
this file extension as CGI scripts. \\

Now enable CGI scripts to execute in a specific directory you prefer. On Windows NT-series 
(including 2000 and XP) operating systems you are recommended to put your scripts under your 
own ``My Documents'' folder for easy access. Very likely you already have a ``My Webs'' folder
in it that has already been created for you by your Windows installation that you can use. 
Find out a section like \\

\begin{lstlisting}[numbers=none,backgroundcolor=\color{CodeBackground}]
UserDir "My Documents/My Website"

#<Directory "C:/Documents and Settings/*/My Documents/My Website">
#    AllowOverride FileInfo AuthConfig Limit
#    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
#    <Limit GET POST OPTIONS PROPFIND>
#        Order allow,deny
#        Allow from all
#    </Limit>
#    <LimitExcept GET POST OPTIONS PROPFIND>
#        Order deny,allow
#        Deny from all
#    </LimitExcept>
#</Directory>
\end{lstlisting}

Remove the \# as shown below and correct the path (for example the drive
label on my system is F: instead of C:, and the folder containing the
scripts and HTML files is changed from the default ``My Website'' to 
``My Webs''). Change the ``Options'' line
as shown below, and add the ScriptInterpreterSource directive, which
instructs Apache to find the path to Perl from the Windows Registry 
instead of from the shebang line: \\

\begin{lstlisting}[numbers=none,backgroundcolor=\color{CodeBackground}]
UserDir "My Documents/My Webs"

<Directory "F:/Documents and Settings/*/My Documents/My Webs">
    AllowOverride FileInfo AuthConfig Limit
    Options MultiViews Indexes SymLinksIfOwnerMatch Includes ExecCGI
    <Limit GET POST OPTIONS PROPFIND>
        Order allow,deny
        Allow from all
    </Limit>
    <LimitExcept GET POST OPTIONS PROPFIND>
        Order deny,allow
        Deny from all
    </LimitExcept>
</Directory>

ScriptInterpreterSource Registry-strict
\end{lstlisting}

We would like to use the Registry to resolve the Perl installation path because most
Perl scripts (especially third-party scripts) today simply use the Unix-style 
\mono{\#!/usr/bin/perl} shebang line and in order to use these scripts you will need
to correct all the shebang lines to the correct Perl path, which is not convenient.
If the Perl path is resolved from the Registry, then the path on the shebang is 
ignored. This is generally recommended unless you are not confident with editing 
the Registry yourself. If you don't feel comfortable editing the Registry, then 
comment out (put a \# in front of) the ScriptInterpreterSource line above. Then, 
you will need to edit the shebang line of all your scripts to reflect the path 
to your Perl interpreter, e.g. \\

\begin{lstlisting}[numbers=none,backgroundcolor=\color{CodeBackground}]
#!F:/Perl/bin/perl.exe
\end{lstlisting}

or, if your interpreter is on the PATH, you can use instead \\

\begin{lstlisting}[numbers=none,backgroundcolor=\color{CodeBackground}]
#!perl
\end{lstlisting}

Now save the Apache configuration file and restart the Web server by Start Menu $>>$ 
Apache HTTP Server 2.0.47 $>>$ Control Apache Server $>>$ Restart. \\

At last, you will need to edit the Windows Registry. This is dangerous if you did it
improperly as proper functioning of your Windows system relies on the integrity of the
Registry. Always stop and think before you commit your action because Registry operations
are irreversible! To run the Registry Editor, select Start Menu $>>$ Run and in the
box type \mono{regedit.exe}, and press Enter. \\

Data entries in the Windows Registry are arranged in a tree, rather like a directory
structure of a filesystem. The left pane contains a tree containing a hierarchy of
keys. When you click on a key in the left pane, the right pane contains a list of
values associated with that key. \\

In the left pane, under ``My Computer'' you would find a number of nodes (keys).
In earlier versions of Windows you would not find a ``My Computer'' root node, but that does not matter.
Now expand the ``HKEY\_CLASSES\_ROOT'' node and find the ``.pl'' node below. If 
Activestate Perl is installed, the key should be there. Then right click on the ``.pl'' 
node and choose ``New'' $>>$ ``Key''. A new key is created under ``.pl''. Type ``Shell'' for the name.
Similarly, create ``ExecCGI'' under ``Shell'', and ``Command'' under ``ExecCGI''.
Click on ``Command'', and in the right pane double click on the text ``(Default)'' 
and enter "F:\textbackslash Perl\textbackslash bin\textbackslash perl.exe" "\%1",
don't forget to update the path to the Perl executable if this is not correct, and 
click OK. \\ 

When finished, the Registry Editor should look like Figure~\ref{fig:registry}, with all the
nodes expanded. \\

% registry.png
\image{!hbt}{0.9\textwidth}{!}{images/registry.eps}{Registry After Modification}{fig:registry}

You can now close the Registry Editor. Create a simple Perl CGI script: \\

\begin{lstlisting}[backgroundcolor=\color{CodeBackground}]
#!/usr/bin/perl 

# You should update the shebang line above if you don't have 
# the necessary Registry entry or have not added the line
# ScriptInterpreterSource Registry-Script to httpd.conf

print "Content-Type: text/html\n\n";

print "<html>
	<head><title>Test script</title></head>
	<body>
		<h1>Hello World</h1>
	</body>
</html>";
\end{lstlisting}

Recall Apache have been configured to allow execution of Perl CGI scripts in the 
``My Webs'' folder in your ``My Documents'' folder. Save your file there with a ``.pl'' extension, for example
on my system it's F:\textbackslash Documents and Settings\textbackslash Administrator\textbackslash My Documents\textbackslash My Webs\textbackslash test.pl. \\

Now, access http://localhost/$\sim$administrator/test.pl. Replace ``administrator'' with the 
username. If you have adhered to this tutorial, it would be ``administrator''. If you have
changed the Apache port number to 8000 replace ``localhost'' with ``localhost:8000'' in the URL. 
You should see the ``Hello World'' text in the browser window. Congratulations! Your Web server has 
been set up! \\

If you have disabled IIS temporarily and changed the Apache port number to anything other than 80, 
you can now restart IIS if you would like to. \\

\subsection{Unix}

By far the only uniform way to install Apache on nearly all Unix platforms is to 
install a source distribution. Binaries for different Unix variants are not interoperable,
and are installed in a different manner. For example, if you are on mainstream Linux
distributions you may be able to find RPMs (RPM Package Manager) compiled for your
distribution. Debian Linux also has its own package manager. FreeBSD also has a port
system. Therefore, you should possibly check the documentation on your system to
see if binaries are available. However, binaries are usually slightly out of date
because you need to wait until packagers package a software into binaries suitable
for your platform. Installation instructions for binary packages are not described
here. \\

You can extract the package by the command \mono{tar xvzf httpd-2.0.47.tar.gz}. If
your version of tar(1) does not support `z' switch, you will need to try 
\mono{zcat httpd-2.0.47.tar.gz | tar xvf -}. After the package is extracted,
change to the directory containing the extracted sources on the command line
using the \mono{cd} command. First, we set up the configuration options of
Apache by the \mono{configure} shell script. Use this command: \\

\begin{lstlisting}[numbers=none,backgroundcolor=\color{CodeBackground}]
./configure --enable-mods-shared=all --prefix=/usr/local
\end{lstlisting}

which installs Apache using the installation prefix /usr/local. 
All modules are enabled and compiled as shared libraries, instead of linking
them into the main Apache executable. In this way, we only dynamically load
a module when it is needed. The CGI module is one of the modules that would
be compiled. You may specify additional options if you like. Type
\mono{./configure --help} for a list of configuration options that can be applied.
If you don't see any errors at the end of the messages, then 
you should be fine. Now compile and install it. \\

\begin{lstlisting}[numbers=none,backgroundcolor=\color{CodeBackground}]
make
make install
\end{lstlisting}

If no error messages appear which causes the compilation to stop, then you
are lucky. Now Apache should be installed. Here I outline the changes to be
made to the Apache configuration file. If you adhere to this tutorial the
configuration file should be at /usr/local/etc/httpd.conf. 
Because this is similar to that of in the previous section I'm not going to
explain the options that have been covered there. This is the original 
configuration: \\

\begin{lstlisting}[numbers=none,backgroundcolor=\color{CodeBackground}]
User nobody
Group #-1

ServerAdmin you@your.address
#ServerName new.host.name:80

#<Directory /home/*/public_html>
#    AllowOverride FileInfo AuthConfig Limit Indexes
#    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
#    <Limit GET POST OPTIONS PROPFIND>
#        Order allow,deny
#        Allow from all
#    </Limit>
#    <LimitExcept GET POST OPTIONS PROPFIND>
#        Order deny,allow
#        Deny from all
#    </LimitExcept>
#</Directory>

#AddHandler cgi-script .cgi
\end{lstlisting}

My modifications are as follows (please read the description below before making
your changes): \\

\begin{lstlisting}[numbers=none,backgroundcolor=\color{CodeBackground}]
User www
Group www

ServerAdmin abc@def.com
ServerName 127.0.0.1:80

<Directory /home/*/public_html>
    AllowOverride FileInfo AuthConfig Limit Indexes
    Options MultiViews Indexes SymLinksIfOwnerMatch Includes ExecCGI
    <Limit GET POST OPTIONS PROPFIND>
        Order allow,deny
        Allow from all
    </Limit>
    <LimitExcept GET POST OPTIONS PROPFIND>
        Order deny,allow
        Deny from all
    </LimitExcept>
</Directory>

AddHandler cgi-script .cgi .pl
\end{lstlisting}

On Unix, although Apache has to be executed as root in order to bind to port 80 
(as a side note: you can also install Apache in a user account by modifying the
installation prefix \mono{--prefix} during configuration to somewhere inside your
home directory but you need to set the port number to be larger than 1024 because
port numbers below 1024 are so called \term{privileged ports} that by Unix convention
can only be bound to by the root user), in most installations once Apache has 
started up it would drop its root privilege through the \mono{chroot()} system call
and run as a pseudo user like ``www''
or ``nobody'' that has limited privileges to do much harm to the system should
intrusions occur. This is a measure to minimize the security risks involved. An
appropriate user and group may have been created for you by your operating system 
installation already. If not, you will need
to create them. See the adduser(8) and addgroup(8) manpages for more information.
On my system, a ``www'' user and group has been created and I just use it here. \\

You should specify the email address of the administrator. In Windows this information
is already set up by the installation program, but on Unix you will need to set it here.
Similarly is the case for ServerName. \\

With this configuration, you should be able to execute CGI scripts inside the 
``public\_html'' directory. Now start the Apache Web server by \\

\begin{lstlisting}[numbers=none,backgroundcolor=\color{CodeBackground}]
/usr/local/bin/apachectl start
\end{lstlisting}
