This document describes the Appweb architecture and how it processes HTTP requests. It
describes the main Appweb components and the flow of processing.
The Appweb HTTP servers has a modular architecture where components may be dynamically
loaded at runtime depending on the desired configuration. The key components of Appweb are:
Component
|
Description
|
Mbedthis Portable Runtime
|
Cross-platform, multithreaded portable runtime. Includes services
for memory allocation, dynamic module loading, safe string handling, socket
communications, threads, thread synchronization, thread-pool, tasks, timers and
debug trace and logging.
|
Appweb HTTP Server
|
Core HTTP server. Includes services for initialization, HTTP
protocol handling, socket connection management, logging, virtual hosts, directory
and location blocks, data stream output buffering and background flushing.
|
Auth Handler
|
Authorization handler. Supports Basic and Digest authorization on a
per directory or virtual host basis.
|
Static Handler
|
Static content handler. Serves HTML pages, graphics and other static
content.
|
EGI Handler
|
Embedded Gateway Interface handler. In-process CGI.
|
CGI Handler
|
Common Gateway Interface handler.
|
EJS Module
|
Embedded JavaScript module.
|
ESP Handler
|
Embedded Server Pages handler. Serves dynamic content based on ESP
pages.
|
PHP5 Handler
|
PHP5 handler. Supports PHP version 5.X.X
|
SSL Module
|
Secure Sockets Module. Implements an SSL provider interface so
different SSL protocol stacks can be loaded from 3rd party vendors.
|
| Open SSL Module |
OpenSSL Secure Socket Layer protocol stack.
|
Matrix SSL Module
|
Peersec Matrix Secure Sockets Layer protocol stack.
|
Admin Handler
|
Administration handler for management of Appweb.
|
Mbedthis Portable Runtime (MPR)
The Appweb HTTP Server is built upon a portability layer called the Mbedthis Portable
Runtime (MPR) runtime. This insulates the rest of the product from the underlying platform and
allows it to be highly portable to new operating systems or platforms. The MPR also provides a
suite of services that facilitate the creation of high performance, multithreaded management
and server applications, including: thread and communications management, dynamic module
loading, timers, tasks and logging.
The MPR also provides a safer environment in which to program as it replaces C APIs that are
prone to buffer overflows and other similar security exploits. The MPR includes a high
performance, safe string library that supports a secure programming style.
The MPR event processing mechanism can be easily integrated into existing applications. It
supports single and multithreaded architectures, polled or async event notification, POSIX
select waiting and Windows message loops. When coupled with C and C++ APIs, API web can be
easily integrated into most C/C++ applications.
Appweb HTTP
Server
The core Appweb HTTP server is relatively one of the smaller components of the
Appweb product when compared to the dynamic modules that run atop it. The core server provides
a set of services for the handlers to use when serving content to clients. The goal is to
centralize any facilities that handles might need so the code will not be replicated in each
handler. These services include: the main HTTP processing and socket communications,
initialization and parsing the Apache style configuration file, buffering, server, virtual host
and directory authorization management.
The core server also configures and enforces any sandbox resource
limits that have been requested in the configuration file. The include thread limits and HTTP
and URL request size limitations. This enables Appweb to be deterministic in its use of system
resources and to be a good system citizen. The core Appweb server can be configured to execute
single or multithreaded and with appropriate sandbox limits, it can scale to serve thousands of
requests per second if required.
Handler Processing
By using the dynamic module
capability of the MPR, Appweb provides a suite of loadable handlers that serve specialized
content for clients.
HTTP Request
Processing
This section describes the flow of processing with the Appweb server. While this
is not essential information, having a background understanding of how Appweb works may assist
you to better utilize Appweb in your applications.
Initialization
Appweb uses a one-pass traversal of the configuration file. This means
that the order of directives in the file does matter. In contrast, Apache uses a two pass
parser. While parsing the configuration file,
LoadModule
directives will cause the specified loadable modules to be added to Appweb. The
AddHandler directives
will cause the specified URL handlers to be activated and configured for service. The Listen directives will
cause Appweb to open and bind to the specified IP addresses for incoming HTTP requests. The
StartThread and ThreadLimit
directives will cause Appweb to preallocate the number of threads specified by StartThread and
to configure the MPR thread pool not to exceed the ThreadLimit.
During configuration, Appweb pre-creates handler instances for all active handlers. When
requests arrive, these pristine instances are cloned for rapid initialization of the required
handlers to service the request.
After performing some security checks and validation tests, the Appweb server writes the
configuration to the error log and then waits for incoming requests.
Request Acceptance
When a HTTP request arrives, the Appweb server will examine the
network interface on which the request arrived and if it is assigned to an IP based virtual
host, Appweb will route the request to be handled by that virtual host. NOTE: this is all
internal to Appweb. If name based virtual hosting is being used, the determination of which
virtual host will process the request must be deferred until the HTTP header has been parsed
and the default server is used to initially parse the request. See the Virtual Hosts for more information.
HTTP Header Parsing
According to the HTTP protocol, Appweb will read the first line of
the HTTP request which specifies the operation method to use, requested URL and the variant of
the HTTP protocol to use. This typically looks like this:
GET /index.html HTTP/1.1
This example is asking for the /index.html document via the GET
method using the HTTP/1.1 protocol. Appweb then proceeds to read the HTTP headers. Typically there are 5-15 headers
which specify further information to help the server process the request. Headers are of the format:
Header: value
Some typical headers are:
Header
|
Description
|
AUTHORIZATION
|
Authorization details including user name, realm, password digest
and other authorization parameters to implement Basic and Digest authentication.
|
CONTENT_LENGTH
|
Length of any addition data with a POST request.
|
CONTENT_TYPE
|
Mime types the client prefers to accept in response to this request.
|
COOKIE
|
Cookie associated with the URL in the clients cookie cache.
|
HOST
|
Name to the target host to serve the request. This specifies the
host name when using virtual hosting.
|
IF_MODIFIED_SINCE
|
Only return the content if it has been modified since the date
specified. Clients who have cached copies of a document (or graphics) use this
header to allow the server to skip copying the document if it has not changed.
|
KEEP-ALIVE
|
Request the server to keep the connection alive so that subsequent
requests can reuse the connection. |
Appweb stores the values of all the HTTP headers in a hash lookup table for fast access. When
all the headers have been read and parsed, Appweb proceed to do handler matching. This will
occur before any associated POST data has been read from the client. POST data may be form data
submitted by the client or it may be a file upload using the PUT method.
Handler Matching
Appweb has a powerful handler matching algorithm that adaptable to
most requirements. Handlers may match requests based on the URL extension or on the leading
portion of a URL (called prefix matching). Both forms are specified per handler in the Appweb
configuration file.
To associate a handler to a given extension, use the AddHandler directive. For example:
AddHandler espHandler .myDoc
This will cause the espHandler to respond to any URL that has a ".myDoc" extension.
To associate a handler to a URL prefix, use the Location directive. For example:
<Location /projects/myVideo>
SetHandler myVideoHandler
</Location>
This will cause the myVideoHandler to respond to any URL that begins with /projects/myVideo after the http://site portion of the URL.
Running Handlers
Multiple handlers may match a URL. In this case they are applied in the order they are
specified in the Appweb configuration file. In the default configuration, the copyHandler is
specified last without any extension and it thus becomes a catch-all. It will process any
document not matched by other handlers and it will return the document without processing back
to the client.
Once the handlers have been matched, they are run in order. The first hander to either
successfully process the request or to abort processing the request will terminate the running
of subsequent handlers. A handler may rewrite the request and it may re-execute or even rematch
the handlers. This is used to handle redirects internally where permissible.
The authHandler
Appweb configures the authHandler first without an extension so it will match every document
and will always run first. If the accessing user is not authorized, the authHandler will will
terminate processing of the request and return an authorization error back to the client. If
the user is authorized, the authHandler will do nothing further. Appweb will then run
subsequent matching handlers until a handler processes the request.
Output Buffering
The various handlers have quite different output buffering needs. The
copyHandler needs to be able to copy static content from the file system back to the client.
The espHandler needs to be able to buffer generated output to compute a content length and then
flush the buffer. Other custom handlers may need to write large volumes of unbuffered data. The
problem is that the Appweb HTTP server needs a uniform way to manage this variety of output
data.
Appweb solves this problem by providing a DataStream interface for output buffering. The
DataStream interface supports all these output needs with one interface.
Request Completion
When the handler has completed processing the request and the output
data has been flushed, the Appweb server will determine if HTTP Keep-Alive can be used.
Keep-Alive allows a socket connection to be reused for subsequent requests which typically
boosts throughput performance by 50% or more. To use Keep-Alive the length of the generated
content must be known and the client must have not stipulated to not use Keep-Alive.
Secure Sockets Layer
The SSL handler implements an open SSL provider interface so that
SSL provider handlers such as openSslHandler and matrixSslHandler can be selected at run-time.