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.
|
PHP4 Handler
|
PHP4 handler. Supports PHP version 4.X.X.
|
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.