Get the source file from http://hopf.math.northwestern.edu/
(U.S.) or http://www.wnserver.org/
(Europe) then uncompress it and untar it to make the
WN source directory hierarchy. The file must be uncompressed
with the GNU compression utility
The resulting file
wn.tar should be unpacked with the UNIX
utility using "
tar -xvf wn.tar". The top level of
the directory created by untarring this file contains several
If your system supports perl, the
quickest way to get your server configured is to run the perl program "
which is in the main source directory. Do this with the command:
This program will ask you various questions, like what version of UNIX
you are using and the path to the directory you want to be the
wnroot of your data hierarchy.
Default answers are printed in square brackets
[ ] so
you can simply press return to enter that value. You can quit at any
time by pressing
Ctrl-C and nothing should be changed. If
you want to try it once to see what the questions are, that is fine.
This program creates two files:
Makefile which are customized based on the answers you gave.
You may rerun this program as many times as you like. The first time you
run the program the default values are those in the file
times the default values for all question answers are taken from the most
config.h you have
produced (if it still exists in the top level directory).
An alternative to running this program is to copy the files
config.h respectively and edit
them manually. If you want to use some of the features which are not
turned on by default like multiple IP interfaces, you will have to edit
recommend starting with the perl
program and getting your server up and running. Then you can go back
see if there are things you want to change. If there are you will have
to recompile but that takes only a few minutes.
Here are some of the questions you will be asked when you run
configure. You will be given a list of supported operating
systems and asked to pick the one you are using, e.g.
LINUX, etc. You
will be asked the complete path name of your data directory. You will
also have to enter the names of the access and error
log files you wish to use (they can be the same file). If you don't
want logging or you want to use the UNIX
system utility (i.e. the
-S option) then these
should both be defined to be the empty string (i.e. a pair of double
quotes with nothing between them like
""). If you specify
the names of these log files then you must make sure that either these
two files exist and are writable by the server or that they are files in
a directory where the server has permission to create them.
Additional customizations in
config.h are possible but
should not be needed. These customizations require that you manually
config.h file. For
example, there is a
line in the
You may also customize the file
Makefile in the top level
directory. In particular you should do this if you wish to specify a C
compiler other than the UNIX
utility (e.g. gcc)
should be used for compiling. Also some systems require that special
libraries for sockets, or whatever, be mentioned in the compile command.
The configuration program attempts to do this, but I am working from user
reports since I do not have access to most of the UNIX variations. If
they are incorrect please let me
In the top level directory do a
to produce the server
wnd, the stand-alone version
wnsd and the utility wndex.
This utility is used to produce
index.cache files for use by
the server. If the
make proceeds without problem you should
next do a "
make install". This will strip the binaries
and place them in the top level
bin directory or whatever
directory you specified when you ran the
If you specified a log file name or error log file name when you ran the
configuration program or edited
config.h you will need to make
sure that these files exist and that they are writable by the user id
under which the server will run. The best way to do this is create the
touch wn.log"), then
change their ownership to the appropriate user
chown nobody wn.log") and finally set the
permissions appropriately ("
chmod 644 wn.log").
An alternative is to create a directory in which these files will reside
and make sure that the user
nobody has permission to create
files in this directory. Then the server will create the files with
proper ownership and permissions.
You can now either run the server as a stand-alone daemon, the
wnsd executable, or run under the UNIX
system utility, the
wnd executable. We first describe the
stand-alone version. Run this with the command:
wnsd -p port [other options] wnroot
port" is the number of the port on which you wish the
server to run. If this is a non-privileged port (i.e. > 1024) then
wnsd can be run as an ordinary user. However, for
privileged ports like 80 you must run the command above as
wnsd is run without the
-p option it will use port
80 by default. If
wnsd is run by
when it starts up it will change its user id to the one set when running
the configuration program or by editing the
config.h file line containing
Otherwise it will have all the permissions of the user who runs it.
The safest practice is to use the numeric UID of
USERID set in
config.h (this is the default)
and then start the server as
Note: on HPUX and perhaps other systems user
nobodycannot be used. In this case just create a new user, say "
www", with the fewest possible privileges and no shell.
The server needs to have
root permissions to connect to a
socket on a privileged port and listen for requests. But immediately
after doing so it will change its user id to that of
and have minimal access permissions. In this situation the user
nobody needs to have only read permission to your server
data and should not own or have have write permission. In particular
nobody should not have ownership or write access of the
index.cache database file described in the chapter "Creating Your WN Data Hierarchy" of
The other way to run the server is to use it under the UNIX
system utility. This is an efficient way to run the server if the load on
it is relatively light (a few thousand hits per day) and the host on
which it runs is used for other purposes. There are variations on how
inetd(8) works from system to system so you may need to look
at the man page for the UNIX
configuration file. Here's how it works under many systems (e.g. SunOS
4.1.3): Edit the file UNIX
configuration file and create the line:
80 by the port you wish to use. Then edit the
inetd.conf(5) and insert the line:
wnd stream tcp nowait nobody /path/wnd wnd
After the last
wnd you can have optional arguments to turn
on logging or use a different data directory. Some
limit the number of arguments you may use so I prefer to use a small
program in place of
wnd here. My
line looks like:
wnd stream tcp nowait nobody /path/wn.rc wn.rc
wn.rc contains only the two lines:
exec /path/wnd -t 202 -L /path2/logfile wnroot
It is important to run
nobody (the fifth
field in the
inetd.conf(5) line above) or some other user
with no special access privileges. If you are using an
inetd(8) with without the capability to set UID on startup
(e.g., Ultrix), you should define the group ID and user ID in
config.h so that the program is
not running as
root (look for the
#define USERID and
and set the values appropriately). It should never be
necessary to run
root and to do so would be a serious mistake for maintaining
security. Every attempt has been made to make
wnd as secure
as possible, even if it is run as
root, however, no program
accessible to remote users on the Internet can be assumed perfectly
secure. See the chapter "Security on the
WN Server" in this guide.
After editing the
files you should find the process id number of the
process and use the UNIX
utility to reload the configuration using
kill -HUP <process_id>". This must be done
root. You find the number
<process_id>" by using the UNIX
utility or by looking at the contents of the file (which you specified
when you ran the
configure program) in which
the server stores this number.
If the fully qualified domain name of your server is
you might like to have your server known as
some other "vanity" name. For most purposes this is simply a matter of
properly setting up Domain Name
Service (DNS) on your system so that the system responds to the
Note: To use multiple vanity names for different IP addresses on a single server see the chapter "Multi-homed or Virtual Servers on the WN Server" in this guide.
There are a few instances, however, where the WN server does use its own hostname. Ideally, in my opinion, the server should do nothing with its hostname and not even need to know it. This is not possible for two reasons.
First, the CGI/1.1 protocol requires the server to pass its hostname to CGI programs in an environmental variable whenever those programs are run. Secondly clients often implement redirection so that it cannot handle relative but only complete URLs. (This is a mistake in my view, but one we have to live with.) Thus when a server redirects to another local document it must supply its own hostname. These are the only places WN uses hostname.
For most cases then, WN only uses it hostname when a redirection
is done. This happens in several circumstances. The most common is when
a request is made for a directory any the trailing '
left off of the URL.
So how does WN know its hostname? When you run the
configure program you are
queried for the value you want or you have the option of using a system
call at the time the server is run. This value is placed into the
config.h header file and
compiled into your server. In the file
macro is set by default to the empty string. If this is not changed the
server will get its name from the UNIX
system call. If this is set to another string that string will be used.
If you are using WN as a multi-homed server then you need to set
different names for the different IP addresses. This is done in the file
wn/vhost.h which you edit to set up the correspondence
between IP addresses and
After compiling and setting up the software you can test it on a sample
directory provided with the distribution. To do this first make a
symbolic link in your
wnroot data directory to the
docs directory in the source distribution. The command
ln -s /your/src/dir/docs docs" executed in
wnroot directory should do this. If your system does
not support symbolic links you can copy this directory and its
subdirectories to your data directory temporarily.
Now you are ready to test your server installation on this directory. Try it with your favorite HTTP client. The URL should be:
If your are running under UNIX
system utility as described above then to shut down
the server first remove or comment out the line you created in the UNIX
configuration file. Then you should again find the process id number of
inetd(8) process and run the UNIX
utility using "
kill -HUP <process_id>" where
<process_id>" is the process id number of
inetd(8) just as you did to start WN.
If you are running
wnsd, the stand-alone version of
WN, you should find the process id number of the running
wnsd by using the UNIX
utility or by looking at the contents of the file (which you specified
when you ran the
configure program or by
-q option) in
which the server stores this number. Then you run the UNIX
kill(1) utility using
kill <process_id>" where
<process_id>" is the process id number of
wnsd. If you started the server as
root to kill it.
There are two ways to log WN transactions: dedicated log files
or using the UNIX
system utility. We first describe dedicated log files.
Normally when you use WN you will keep two log files. The first
is a log of all "normal" transactions and the second records error
conditions or items which might require your attention. For example, if
the server cannot find a file which your
indicates should be served it will log an error. The error log file can
be the same file used for the normal transaction log. In general the
difference between the two is that the error log gets information about
anything which might require attention of the maintainer while routine
transactions and errors which are simply user errors tend to go to the
regular log. The intent is that a conscientious maintainer should keep
an eye on the error log but need not read the (much larger) log of
There are two ways to tell the server the names of these files. The
first is by supplying the file names when you run the
configure program and then
compiling these into your server. And the second is by supplying the
file names on the command line when you execute the server. This is done
-L option and
-l option to specify
the transaction and error log files respectively.
For example, executing the command:
wnsd -L /path2/logfile -l /path3/error.log wnroot
will cause the server to use "
error.log" as the log file and error log respectively. Of
course, it is necessary for the server to have write permission to these
files and execute permission on the directory containing them.
A good way to achieve this if the server is running as
nobody is to create the files yourself and change their
ownership to the user
nobody. This can be done, for
example, with the commands:
/usr/etc/chown nobody logfile
chmod 600 logfile
root in the directory where the log file is to
reside. The first of these commands creates the file
logfile". The second makes
nobody the owner
and the third gives
nobody (and no one else except
root) permission to read and write this file. You might
want to allow others to read, but not write to the log file, or security
of the log file might not be a concern.
Thus a program executed by the UNIX
system utility to rotate log files might look like:
mv logfile logfile.old
chown nobody logfile
chmod 600 logfile
kill -HUP `/bin/cat /path/to/wn.pid`
chown maintainer logfile.old
chmod 600 logfile.old
/path/to/wn.pid is a file containing the processes id
of the server created by using the
-q option or by specifying
this filename when the
configure program is run.
If neither of these has been done the stand-alone server,
wnsd, will print its process id on the UNIX
stream when it is run. If you are using
there is no need to send the
-HUP signal as the server must
close this file after each transaction.
If you are using a system that supports the
program, it provides a good way to handle logs. Here is an excerpt
from a typical logrotate.conf file.
/usr/bin/killall -HUP wnsd
This causes the logs to be rotated daily. The command
/usr/bin/killall -HUP wnsd assumes that your
system supports the
killall command, in which
case it finds the process id of the wnsd process and sends it
the -HUP signal, as was done by the
in the script above.
There are three formats which the server can use in writing its log files, each with three options concerning how much DNS lookup to do for the remote host. The two most common formats are "verbose" and "common log format". The verbose mode is essentially the common log format but with the user-agent, referrer, HTTP cookie, and virtual server nickname appended to the line for that transaction as well as better transaction error messages if necessary.
You can chose between verbose and common log formats by answering the
relevant question when running the
configure program before
compilation (or by editing
To use the third format you need to use the
-v command line
option. When the server is invoked with the
-v option it will
write a log file in the format specified by the value of this
option. The legal values for this option are
ncsa". They cause the log file to be written in
the so-called common log format, or WN's verbose format
including user agent, referrer, X-Forwarded-For header, virtual
server nickname, and cookies, or in the NCSA extended format
which includes just referrer and user agent. When using verbose
logging the nickname (enclosed in angle brackets) will be the
last field of each log entry. If virtual hosting is not being used
this field will be omitted.
More precisely a verbose log line begins with a normal "common" log format line and then adds the following:
<(pid/count) msg1: msg2> <user_agent> <referrer> <cookie> <X-forwarded-for> <nickname>
The punctuation characters, i.e.,
< > ( ) and
:, will always be present in this order. The
msg1" and "
msg2" may contain
additional parentheses or colons. Hopefully none of the fields
will contain the character '
<' or the character
>', but "referrer", "cookie", "X-forwarded-for"
and "nickname" are provided by the browser or the server
maintainer so WN has no control over them.
The fields are as follows:
|pid||Process id of the process serving the transaction.|
|count||n if this is the nth transaction of this (keepalive) connection.|
|msg1||Description of transaction. May be sent to user.|
|msg2||Description of transaction. Information NOT sent to user.|
|user_agent||From the HTTP user agent header.|
|referrer||From the HTTP referer (sic) header.|
|cookie||From the client's cookie header.|
|X-forwarded-for||From the client's X-Forwarded-For header.|
|nickname||Value assigned this virtual host by the maintainer (omitted if virtual hosting is not used).|
The NCSA format will likely only be of interest if you want to use log
processing tools which expect this format. If the
-v option option is not
specified the server will default to either the common log format or the
WN verbose format depending on which was selected when the
configure program was run.
convert verbose log files to log files in the shorter common log format.
The WN server does not send the UNIX
stream output to the error log file, but leaves its default the terminal
from which the server is invoked. This allows the maintainer to set it
to a file of her choice, for example the error log, or leave it directed
to the console window in which
wnsd was invoked. To
redirect it to a file called
my.errs simply run
wnsd with a command like
wnsd <options> 2>my.errs" if you are
using a Borne-like shell like
sh(1). The server itself
sends very few things to
stderr(3) -- only errors which it
is impossible to put in the error log (like "Can't open error log file").
The real usefulness of redirecting
stderr(3) comes when you
are creating CGI/1.1
programs because their errors are typically sent to
stderr(3) so you can easily view them rather than have them
buried in a log file.
If things are not working as they should here are some tips to help you isolate the problems.
If the compilation was successful you can check the server itself by executing it from the command line. If you use the command:
it should run and pause for input. Type the line:
and in response
wnd should print the raw HTML of the
index.html file in your top level directory (perhaps along
with a message about not being able to open a log file). If instead you
(and you still have the
/docs subdirectory in your top level
directory) the overview document should be sent to your screen. If this
doesn't happen there should be an error message which may be helpful.
Better error messages are placed in the log file so you may want run
wnd again with the additional arguments
-L logfile" and then examine the contents of the log
file. Or if you run "
wnd -L /dev/tty" the log
entries will be printed to your screen instead of being put in a file. If
the server can't open a file, for example, the name of that file will be
recorded in the log file. Check its permissions. Remember that all files
wnd serves must be world readable. More serious errors
are put in a separate error log. So you might want to try the command
wnd -L file -l file2" and then type the
GET requests described above.
If this succeeds you should run the server for real, either under
inetd(8) or stand-alone. In order to use port 80 the server
must be started by
root. It will then switch to user
nobody. It does this immediately after connecting to port
80, before it does anything else including opening its log file. If you
get a message that the server cannot open its log file then either you
have specified putting the log file in a directory where user
nobody does not have permission to create files or you have
specified an existing file which the server does not have permission to
After starting the server a useful test is to use the UNIX
utility to connect to your server at port on which you are running. You
should get a connection message and a pause for input. If you get a
Connection refused" message and you are running under
inetd(8), it is likely there is a problem with your
inetd(8) setup or for some reason your system can't find or
can't execute the
wnd binary. If you are using
wnsd this message means that
wnsd is not in
If you still have problems feel free to ask questions on the WN list server. There are many helpful people there. But it is a good idea to try the steps above first and to include the relevant log file messages with your request.