This document describes the AppWeb architecture and how it processes HTTP requests. It describes the main AppWeb components and the flow of processing.
- Portable runtime layer to isolate platform dependencies
- Modular architecture with dynamic module loading
- High performance multithreaded core
- Thread pool for fast thread allocation
- Safe programming layer to prevent buffer overrun exploits and sandboxing to limit resource consumption
- Efficient output data stream buffering
- Apache compatible configuration
- Extensive logging and debug trace
And for those who wish to rebuild AppWeb from source code, AppWeb can be highly optimized by using an an extensive set of compile time options to control what features are included.
Stand-alone HTTP Server
When using AppWeb as a stand-alone server, you can create web user interfaces using several innovative AppWeb technologies and existing standard technologies
- Embedded Server Pages™
- Embedded Gateway Interface™
- Open Modular Architecture
- Common Gateway Interface
The AppWeb server runs as a stand-alone program. On Windows, it runs as a system service and on Linux/Unix it runs as a system daemon.
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:
|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.
|Authorization handler. Supports Basic and Digest authorization on a per directory or virtual host basis.
|Static content handler. Serves HTML pages, graphics and other static content.
|Embedded Gateway Interface handler. In-process CGI.
|Common Gateway Interface handler.
|Embedded Server Pages handler. Serves dynamic content based on ESP pages.
|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.
|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.
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.
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
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.
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:
Some typical headers are:
|Authorization details including user name, realm, password digest and other authorization parameters to implement Basic and Digest authentication.
|Length of any addition data with a POST request.
|Mime types the client prefers to accept in response to this request.
|Cookie associated with the URL in the clients cookie cache.
|Name to the target host to serve the request. This specifies the host name when using virtual hosting.
|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.
|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.
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:
This will cause the myVideoHandler to respond to any URL that begins with /projects/myVideo after the http://site portion of the URL.
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.
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.
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.
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.