The client connects to the Apache web server and makes an HTTP
request. Apache receives the request and prepares to handle it; that
is, it begins to determine how it will send back a response to the
request.
Apache goes through several request handling phases which
handle different parts of the response. When configured for use with
SkunkWeb, Apache will do nothing for most of these request handling
phases. When Apache reaches the main request handling phase, it
uses a extension module from the Skunk software to handle the request.
This extension module is called mod_skunkweb. This means
that the request will be passed back to SkunkWeb, and that all the
needed information about the request will be passed to SkunkWeb in the
same general way that Apache would pass request information to CGI
programs.
The mod_skunkweb module then handles the request. The
first thing it does is to take all of the environment variables
available, including the variables set by Apache to include request
information. (For instance, the environment variable REMOTE_ADDR will
contain the IP address of the client making the request. There are
many other environment variables that contain request information, and
mod_skunkweb gathers them all together. At this point it
also gathers the HTTP request body also.
mod_skunkweb then encodes all of the environment
variables and request body into a special format that the SkunkWeb
server will understand (see the Developers Manual for details).
mod_skunkweb then opens a connection to the SkunkWeb
server. The Apache configuration will tell mod_skunkweb on
which host and on which port number the SkunkWeb server is
running. The typical configuration has the SkunkWeb listening on
the localhost port 9888.
If the connection succeeds, mod_skunkweb then sends
the encoded environment variables over the connection, and waits for
SkunkWeb to return a response that can be sent back to the Web
client. If the connection fails, mod_skunkweb will retry the
connection a few times (utilizing the socket addresses listed in the
SkunkWebFailoverHosts configuration variable). If the retries
also fail, mod_skunkweb will return a customizable error
page, with a 500 Server Error status, as the response to the client.
SkunkWeb, like Apache version 1, runs as a pool of
processes. The SkunkWeb parent process does not listen for
connections from mod_skunkweb; its only job is to create
child processes that will do all the listening and request
handling. (The amount of child processes it creates, as well as other
important things, are configurable in SkunkWeb's configuration files.)
Thus when we say that ``SkunkWeb is running'', we mean that the SkunkWeb
parent process is running and has created one or more child processes
that are listening for connections from mod_skunkweb.
An SkunkWeb child process, then, accepts the connection from
mod_skunkweb and receives the encoded environment variables
containing all of the request information. It then decodes the
variables and checks that they are OK.
SkunkWeb then builds a CONNECTION object. It fills the
CONNECTION object with request information from the environment
variables, including an entire copy of the environment variables. The
CONNECTION object also provides data and operations for the subsequent
web application to create a well-formed HTTP response to be sent back
to the client.
SkunkWeb then does request pre-processing. Depending on its
configuration, SkunkWeb can run one or more customized functions to do
common things with the request, such as authentication, rewriting of
URLs, and other modifications of information in the
CONNECTION object.
SkunkWeb then looks at the URI of the document requested by the
client, for example /index.html. SkunkWeb tries to find this
document in its documentRoot, that is, its document
filesystem. If SkunkWeb cannot find the document, it generates a
customizable 404 Not Found response, returns it to
mod_skunkweb, and closes the connection.
If SkunkWeb does find the requested document, SkunkWeb then
looks at the MIME type of the document to determine if the document
is static, and should be sent as-is with no modification. If the
document is static, SkunkWeb reads the contents of the document file,
makes an HTTP response out of it, and sends it back to
mod_skunkweb.
If the requested document is not static, it is considered
dynamic, which means that the document contains programming code
that should be executed to generate the HTTP response. There are two
kinds of dynamic programming languages supported: the Python
programming language, and a tag-based programming language called
STML, or Skunk Template Markup Language. As a rule, files ending in
.py can contain Python code, and files ending in .html, .txt, and
other common text formats can contain STML tag code.
SkunkWeb then runs the dynamic documents contents through a
compiler, which will turn the document and its programmming
instructions into executable code. The resulting code is executable
Python code; SkunkWeb is written in the Python language. SkunkWeb
keeps a cache of compiled Python code for each dynamic document so
that it does not have to compile the same documents repeatedly.
Now that SkunkWeb has executable code for the dynamic document,
it sets up a special execution environment for the code. It includes
the CONNECTION object, helpful utility functions and modules, and
special objects that monitor the executable code and capture the
response output that the code generates. SkunkWeb then executes the
code.
Dynamic documents often make use of a powerful feature in
SkunkWeb: they can use other special dynamic documents to help
generate the needed output. These special documents are called
components: they cannot be requested by mod_skunkweb, but
they can be used as building blocks by dynamic documents and
assembled together on the fly. Components can be programmed in
straight Python or as text with STML tag code embedded in the
text. Components also can accept arguments from the dynamic
documents, just as a function can receive arguments from the code that
calls the function.
SkunkWeb keeps track of all the components that a dynamic
document tries to use. If an error occurs in any code, or if a
component is asked for by a dynamic document but does not exist,
SkunkWeb will catch the error, generate a customizable error page,
and return a 500 Server Error response to mod_skunkweb.
SkunkWeb also offers a powerful feature for components: caching
of component output. Components may indicate in their program code
whether their output should be cached by SkunkWeb, and for how long.
When a component whose output is cached is called, SkunkWeb does not
even bother executing the component's code; SkunkWeb simply retrieves
the component's output from the cache and proceeds. The component
output cache is one of SkunkWeb's most important features, and it also
has the most impact of server administration and performance.
Once all of the dynamic document's code has executed (as well as
all of the components the document used) and no errors have occurred,
SkunkWeb gathers all of the response output generated by the
document's code, puts it in the CONNECTION object, and
prepares to send the response back to mod_skunkweb.
SkunkWeb examines the CONNECTION object, extracting the
needed information and creating a well-formed HTTP response, with
headers and everything. SkunkWeb then sends the HTTP response over the
connection to mod_skunkweb, and then closes the connection.
mod_skunkweb receives the HTTP response, tells Apache
about the response, and finishes its job.
Apache, which now has the response generated by SkunkWeb,
performs any post-processing on the response that it feels is
necessary, and returns the response to the client that requested it.