Quick Nav
OverviewHandlerService
Handler Class
Creating Handlers
See Also
Embedding Appweb
Using EGI
Pages from ROM
Programming Paradigms
Appweb Samples
Creating Appweb Modules
Creating Appweb Handlers
Creating Appweb URL Handlers
Embedthis Appweb supports extension handlers that can process any kind of HTTP content. The core Appweb
HTTP server cannot serve any pages or documents by itself. It relies on URL handlers delivered as modules
to actually serve HTTP requests. Appweb is itself comprised of 7 different handlers which serve all the
content provided by an Appweb server.
This document describes the Appweb URL Handler Interface and how to create Appweb handlers. Handlers are
usually delivered as stand-alone loadable modules. In this manner, users can decide for themselves if the
functionality provided by the handler is needed or not. But the Appweb Module interface is only a delivery
option. Handlers can be statically linked and do not rely on the module mechanism to operate.
Overview
To create an Appweb handler, you need to create an instance of a subclass of the MaHandlerService class and insert the instance into the Http service. This MaHandlerService class is the factory to create instances of your actual handler in response to incoming HTTP client requests. When a new HTTP request arrives, the newHandler method is called for the factory class to create a new MaHandler instance to process the request.If the handler is being packages as an Appweb Module, it is often most convenient to create a new instance of the MaHandlerService class in the Module constructor.
HandlerService
The class definition for an Appweb Handler is described below. Note the start and stop methods are optional.
class MyHandlerService : public MaHandlerService {
public:
MyHandlerService();
~MyHandlerService();
MaHandler *newHandler(MaServer *server, MaHost *host, char *ext);
int start();
int stop();
};
The follow code demonstrates an Appweb Module constructor that creates the handler
service and inserts it into the applications Http service. Note that while Appweb Handler services are
global to the application, you can specify on a per server or virtual host basis whether the handler is
active or not vi Appweb configuration file directives.
MyHandlerModule::MyHandlerModule(void *handle) : MaModule("MyHandler", handle)
{
mprLog(0, "In MyHandlerModule()\n");
//
// Create the handler service (one per application) and insert into
// the HTTP service.
//
myHandlerService = new MyHandlerService();
maGetHttp()->insertHandlerService(myHandlerService);
}
Handler Class
Once the MaHandlerService instance is created it will be instances of the MaHandler
class that will run actually service the HTTP client requests. The following is the class definition for
our MyHandler class.
class MyHandler : public MaHandler {
public:
MyHandler(char *extensions);
~MyHandler();
MaHandler *cloneHandler();
int matchRequest(MaRequest *rq, char *uri, int uriLen);
void postData(MaRequest *rq, char *buf, int buflen);
int run(MaRequest *rq);
int setup(MaRequest *rq);
};
The MaHandler class can optionally provide several methods which are run a various
stages of the HTTP request processing. The matchRequest method is run to determine if the handler should be
called to examine or process the request. If the handler matchRequest method returns TRUE, the run method
will be called later to process the request. After matching the request, the setup method is called to
allow the handler to do any required initialization.
For maximum speed, the cloneHandler method is provided to allow the quick creating of
new handler instances of the same configuration as the curren thandler instance.
The postData method is called (may be prior to the run method), to process any incoming
POST data. It is up to the handler to decide what to do with the data. The run method is
called to actually process the request. If the handler is a terminalhandler, then it is
responsible for returning the resulting data back to the client's browser. If the handler is a non-terminal
handler, then it must either abort the request by calling rq->requestError or it should zero to allow
other handlers to process the request.
Creating Handlers
A handler specifies whether it is terminal or non-terminal when it is constructed. The
constructor for MaHandler takes an options flag that can take the following values:
| Flag
|
Description
|
| MPR_HANDLER_DELETE
|
The handler supports the HTTP DELETE method.
|
| MPR_HANDLER_GET
|
The handler supports the HTTP GET method. |
| MPR_HANDLER_HEAD
|
The handler supports the HTTP HEAD method. |
| MPR_HANDLER_OPTIONS
|
The handler supports the HTTP OPTIONS method. |
| MPR_HANDLER_POST
|
The handler supports the HTTP POST method. |
| MPR_HANDLER_PUT
|
The handler supports the HTTP PUT method. |
| MPR_HANDLER_TRACE
|
The handler supports the HTTP TRACE method. |
| MPR_HANDLER_NEEDS_ENV
|
The handler want to have a hashed symbol table created with CGI style variables defined.
|
| MPR_HANDLER_ALWAYS
|
The handler always matches incoming requests and does not call the matchRequest method.
|
| MPR_HANDLER_MAP_VIRTUAL
|
Don't map the URL onto physical storage.
|
| MPR_HANDLER_ALL
|
All the above
|
For example, the following code fragment will configure a handler to be a terminal handler supporting the
GET and POST methods.
MyHandler::MyHandler(char *extensions) : MaHandler("MyHandler", extensions,
MPR_HANDLER_GET | MPR_HANDLER_POST | MPR_HANDLER_NEED_ENV | MPR_HANDLER_TERMINAL)
{
// Code here
}
The Handler sample and the handlers provided in the Appweb
source code demonstrate many other variations on how to create and use handlers.