PDEPP Webserver pre 0.3.1
Copyright (C) 2001 by Christian Hoenig & Gunter Ohrner
<pdepp@CustomCDROM.de>
PDEPP Webserver comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. For more details see the GNU General Public License Version 2 (http://www.gnu.org/copyleft/gpl.html).
One major goal while designing the PDepp Webserver was to keep the whole program as modular as possible, with well defined, consistent interfaces and with each module knowing the least possible about any other module. It should be possible to replace the server's protocol parser or network layer with no changes to other parts of the server.
Furthermore it should be possible for several alternative implementations of a given module to coexist and for the "right" implementation to be selected dynamically at runtime (eg. choosing a different request handler depending on the URLs path prefix or file extension, details see below), however this has not been implemented yet. Adding it should not be too hard and would mainly consist of wrapping the existing module interfaces into structs (using function pointers) to allow them beeing put in lists.
Most modules are ADTs, very closely resembling the the structure of classes in object oriented programming languages. This way we tried to achieve the neccessary level of abstraction and data encapsulation.
Key Features From The Programmer's / Contributor's Point Of View
autoconf
to be easily adaptable for new platforms./configure
-able for memory debugging and profiling0.3 Gargle Blaster
Syntactical Programming Conventions
Altough we understand that there is a myriad of ways to write syntactically correct code and many of these may be help- and / or useful in some cases it is of extreme importance that only exactly ONE is used within one specific program. There are only very few things worse than mixed coding styles in one program...
The following rules and conventions are used within PDepp Webserver's code.
Naming Conventions:
functionNames
/ methodNames
start with a lower-case letter, do exclusively contain letters and digits and the first letter of any distinct word in a composite name must be upper case.variable_names
are all lower case, several distinct words joined into one name are separated by underscores.DatatypeNames
/ StructNames
are all lower case - except of the very first and the first letters in of each distinct word in a composite name which must be capital letters - and consist only of letters and digits.file_names
are all lower case but may contain underscores.The PDepp Webserver's architecture is based on several independant layers. Each layer has (or at least should have ;-) a well-defined interface and task scope. Each layer does only know about and communicate with it's direct neighbours and is designed to be easily replaceable by an alternate implementation without affecting any other layer it's communicating to.
The server's basic structure can be seen best in the following overview diagram. The "layers" are aligned from the left to the right as we simply could not agree on the Server Core being top or bottom of the architecture ;-). Having this diagram's layout in mind we will refer to a layer's "left neighbour" and "right neighbour" throughout the rest of the manual.
PDepp Webserver's layered architecture
Each layer has a predefined set's of methods it must implement. Unfortunately C has nothing resembling C++'s pure virtual classes or Java's Interfaces which would be a nice way to enforce a consistent interface so in our case it's completely up to the Layer's programmer to stick to the standard.
An important thing to note is that the right neighbour of ANY layer is passive - it waits for a request or notification from its left neighbour before doing anything. In this context the Client could be seen as the Server Core's left neighbour.
Each Layer has to provide the following methods (the Server Core being a slight exception as its "left neighbour" is non-standard as well by design):
Init
Receive
Send
Process
IsDataPending
Terminate
The Server Core is the connection multiplexer part of the PDepp Webserver. It listens for and accepts new connections, creating a new Connection Handler object to manage it. Additionally it waits for data arriving for currently active connections or for active sockets ready to send data and informs the corresponding Connection Handler by calling its chReceive
or chSend
functions.
The Server Core's interface is declared in server.h
. Its currently only implementation resides in server.c
, supports TCP/IP sockets and has not yet been converted to an ADT.
A Connection Handler represents a single connection to a client. It's responsible for non-blocking reads into the receive buffer and for writing chunks from the send buffer to the client. A connection handler associates a connection with a protocol Handler.
The Connection Handler's interface is declared in conn_handler.h
. Its currently only implementation resides in conn_handler.c
and supports client connections through file descriptors.
A Protocol Handler is responsible for "understanding" the client's requests and giving the right answers (ofter with the help of a Request Handler). The whole protocol parser / generator code is encapsulated in modules belonging to this layer.
The Protocol Handler's interface is currently declared in http.h
. Its currently only implementation resides in http.c
, supports a subset of the HTTP 1.0 protocol and virtually no HTTP 1.1 extensions.
Possible alternative implementations could include a Protocol Handler supporting the FTP protocol or similar (NNTP, ...).
A Request Handler is responsible for actually executing the request of the client as understood by the Protocol Handler and returning the data resulting from processing the request.
The Request Handler's interface is currently declared in reqhandler_file.h
. Its currently only implementation resides in reqhandler_file.c
and supports reading static files from disk.
Possible alternative implementations could include a Request Handler supporting CGI scripts or database querys.
Other Modules / Non-Layer Modules
All additional modules in alphabetical order:
buffer.h
/ buffer.c
buflist.h
/ buflist.c
char_xhash.h
/ char_xhash.c
chrlist.h
/ chrlist.c
conftable.h
/ conftable.c
conn_handler_list.h
/ conn_handler_list.c
intlist.h
/ intlist.c
keylist.h
/ keylist.c
logger.h
/ logger.c
logger_list.h
/ logger_list.c
mime.h
/ mime.c
misc.h
/ misc.c
signal_handler.h
/ signal_handler.c
tmpl_common.h
xmalloc.h
/ xmalloc.c
mlist_tmpl_h.inc
/ mlist_tmpl_c.inc
xhash_tmpl_h.inc
/ xhash_tmpl_c.inc