Updated 12/10/99
I started this project to better understand the HTTP protocol specification
and how a server actually works.
This is a limited, though functional server ( thus the name Decaf )
that will support multiple users and respond to basic HTML requests. All
of the source code for the project is included here.
Running the Server
To run, download the Server ZIP file to a root directory you want the program to run in (I used /INET )and unzip. If you're using PKZIP use the -d option to save the directories.
Format of the ZIP file is :
--------------------------------------------------------------------------
/root
Server class files
password file
readme file
defaults.ini file
/root/java-bin
Example java CGI scripts
/root/wwwroot
example html files and main "home" location
/root/wwwroot/images
various images for examples
/root/wwwroot/private
Example directory for password authorization request
/root/webserverSourse
source for all the server classes
/root/java-source
source for all the cgi script classes
---------------------------------------------------------------------------
I assume you have the java runtime on your computer. if not, get it
at JavaSoft.com
go to the root directory where you unzipped the files and type java
-classpath %classpath%;d:/inet/java-bin Server . The response
should be " Decaf WebServer Ver 2.01".
NOTE:
The classpath assignment above is so that the scripts located in /java-bin/
can be found. Modify the command depending on where your Root is located
. In the example above I am running from the directory D:/Inet
( this works on NT, I assume it works on Windows 95/98 )
If you are running under JDK ver 1.1 enter the above line as
jre -cp %classpath%;d:/inet/java-bin Server
Launch your browser and connect to the server using the loop back
address http://127.0.0.1/ If you are logging in from another
machine replace the loop back address with the real IP address of your
server machine . You should now see the Index.html page which is
the default page if no URL is requested.
All your pages must reside within or under the directory wwwRoot.
Optionally, you can pass a parameter on the command line to set
the base html page location somewhere else.
java -classpath %classpath%;d:/homepage/java-bin Server
d:/homepage will make the server treat e:/homepage as the default directory.
Your server classes may reside somewhere else if you use this option.
A file called defaults.ini should exist in the \root directory.
Defaults are added to the properties list for use by scripts and the server.
Modify them to meet your needs.Current defaults are:
DEFAULT_URL | HTML file for normal home (typically INDEX.HTML) |
PASSWORD_FILE | Name of the password file ( defaults to password.ini ) |
ERROR_URL | File name of HTML document when no page found |
RESTRICTED_DIR | Restricted directories. Server will request a password Authorization if an attempt is made to enter these directories. |
SERVER_SOFTWARE | Response String to SSI request for server_software |
SERVER_NAME | Response String to SSI request for server_software |
SSI | Extension of documents containing SSI commands. Defaults to SHTML |
CGI_EXT | valid extensions for CGI Scripts. Currently only support classes ( .cl ) |
VERSION | Software version level |
MAIL_SERVER | Your mail servers SMTP address |
MAIL_ADDRESS | Your Email Address |
What this server doesn't support completly
The following #echo commands are recognized by the server. An example HTML file is included called ssi.shtml
<!--#echo var="LAST_MODIFIED" -->
<!--#echo var="REMOTE_HOST" -->
<!--#echo var="HTTP_USER_AGENT" -->
<!--#echo var="DOCUMENT_URI" -->
<!--#echo var="SERVER_NAME" -->
<!--#echo var="SERVER_SOFTWARE" -->
<!--#echo var="REMOTE_ADDR" -->
The Virtual command is supported for simple file includes :
<! #include virtual = "filename" -->
Complex includes that run scripts are not supported. An example would be an include to display hit counts which would require a script to run on the server.
Note: for efficiency, any file that contains SSI's
must end with a .SHTML extention. This restriction is an entry in the defaults.ini
file and may be changed to allow all HTML files if required. There will
be a performance hit if all files must be parsed.
Server.class
Sets up a socket connection to port 80 and waits for data. When detected,
an instance of the Connection class is created to handle the input and
output for this data stream. Check for password.txt file. It not
there, create one. Load all user default properties located in the defaults.ini
file.
HTTPConnection.class
This is an abstract class who's methods do most of the work. It is
extended by Connection.
Connection.class
The Connection class extends HTTPConnection and calls the appropriate
methods to process the clients request. The connection object also spawns
the CGI script through the runObj method and passes myProperties
to the script. It redirects all output from the script object back to the
clients browser.
GetFileDate.class
Utility object for Connection to manipulate time and date functions.
SSIParser.class
Methods to handle all the Server Side Include functionality
showDirectoryTree.class
One methed called showTree() which displays a sever directory
in a tree format to the browser. Method is called only if no URL
or index file located in the approproate directory.
runObj.class
Based on the string supplies, it attempts to locate a class and create
an object of that class with the Constructor public MyScript (Hashtable
myProperties) {}
used for CGI scripts.
Codecs.class
Does a Base64 Encode on a string. This is used to verify the password
returned from the client exists in the passwords database.
Cookie.class
The cookie class handles the password Authorization for restricted
directories.
mail.class
Class that handles SMTP protocols. A example script called processMailForm.cl
shows how to let the user send an email back to You in responce to filling
out a form.
Note: PLEASE !!! , If you try this script, modify the defaults.ini
file so that the mail goes to you, not me !!.
getCGI.class
Parses the Query_String parameter and breaks the result into <key><value>
pairs. Includes methods to query the resulting hashtable for information
to be used by the java CGI scripts. ALL scripts must extend this
class.
How CGI Scripts are excecuted
Scripts are evoked by parsing the POST header from the client and extracting the script name ( i.e. showProperties.cl ) . Using the Object and Contructor classes, we can instantiate an object based on a String name. The runObj class accomplishes this. The runObj class attempts to locate a contruction with the following parameters :
public class testCGI {
public testCGI( Hashtable myProperties )
{
}
}
myProperties is a list of properties that the script may require, including
the Query_String Data from the POST Operation. It is passed to the script
automatically by the Connection class.
All scripts must follow this convention and the entire script must
be run within the Constructor. The runObj class can not locate or run any
methods within the Script class.
Data Passed to the Scripts
myProperties Contains the following data to be used by the scripts . Not shown, but also included, are all the system properties that are typically generated by the System.getProperties() method . Values are examples from show.html based on my server:
CONTENT-LENGTH = 33
DEFAULT_URL = index.html
DOCUMENT_EXT = cl
DOCUMENT = showProperties
DOCUMENT_URI = http://127.0.0.1/show.html
ERROR_URL = error.html
HOME_ROOT = D:\JAVA\FinalApplets\server
HOST_ADDR = 216.166.44.229
HTTP_USER_AGENT = Mozilla/4.7,[en],(WinNT;,U)
REMOTE_HOST = localhost
REMOTE_ADDR = 127.0.0.1
RESTRICTED_DIR = /java-bin/
SERVER_NAME = Decaf WebServer
SERVER_SOFTWARE = Decaf ver 2.0
SSI = SHTML
QUERY_STRING = password=admin&user=administrator
WWW_ROOT = e:\inet\wwwRoot
Example Scripts reside in the /java-source subdirectory.
How passwords are implemented
User passwords exist in the file passwords.ini . The format for this file is :
real name , username, password, accesslevel
Accesslevel is currently not supported but the intent is that
normal users have a level of 2. Administrators have a level of 1
If the client requests a file located in the RESTRICTED_DIR location,
the server will challenge the user with
HTTP/1.0 401 Authorization Required
WWW-Authenticate: Basic
The browser will detect this and automatically bring up a password prompt
to the user.
If the username and password match an entry in the passwords.txt file
then the user is allowed entry to the requested directory. The password
is good for the entire clients session.
Example Script files
showprops.html
Simple script example that reads the System Properties list and returns
it back to the client thru the showProperties.cl script.
uses showProperties.cl
ssi.shtml
Returns SSI processed data back to the user.
showmail.html
This is an example of using the mail class. If allows the user to enter
a simple form and send the result back to you.
uses emailForm.cl and processMailForm.cl
show.html
User enters data in a form. The server parses the Query_String parameters
and returns the results back the the user.
uses showForm.cl