HTTP Server Custom Handler

How to create your custom server (dynamic server, streaming server...) ?

You may wish to create your custom request handler. Here is how it's done.

Handler class Structure

class SimpleHandler : public HTTPRequestHandler
{
public:
  SimpleHandler(const char* rootPath, const char* path, TCPSocket* pTcpSocket);
  virtual ~SimpleHandler();

protected:
  static inline HTTPRequestHandler* inst(const char* rootPath, const char* path, TCPSocket* pTcpSocket) { return new SimpleHandler(rootPath, path, pTcpSocket); } 

  virtual void doGet();
  virtual void doPost();
  virtual void doHead();
  
  virtual void onReadable(); //Data has been read
  virtual void onWriteable(); //Data has been written & buf is free
  virtual void onClose(); //Connection is closing
};

This is the SimpleHandler class header. As you can see, there are a few functions inherited from HTTPRequestHandler that you have to implement.

You must provide a static inst() method which returns a new instance of this class so that the dispatcher can instanciate your handler dynamically.

How does it work?

This handler is event based, so here is how it is going to work:

When a request is dispatched to your handler, the headers are read and stored in the reqHeaders() dictionary. You can access any of these headers like that :

string type = reqHeaders()["Content-Type"];

You can also get the body data length, the path of the request or the constant root path that leads to your handler:

int len = dataLen();
string path = path();
string rootPath = rootPath();

The doXxx() method is called accordingly to the request (e.g. doGet(), doPost() or doHead()).

At this stage there might be some data to be read. Use the readData() function:

int readData(char* buf, int len); //Returns number of bytes read

Should more data be read afterwards, the onReadable() function would be called.

You can send your response using the writeData() function. Before that, be sure that you have set all your response headers information, with the respHeaders() accessor:

respHeaders()["Connection"] = "close";

You can also set the body data length with the setContentLen() function. Should you return an error code different than 200, be sure to set it as well.

setContentLen(100);
setErrCode(404);

int writeData(const char* buf, int len); //Returns number of bytes written

When a packet has been sent an you can write more data, the onWriteable() function is called.

If the remote host closes the connection or on timeout, the onClose() function is called. If you want to close the connection yourself, use the close() function.

Examples

Be sure to check the existing implementations, from the basic SimpleHandler to the more advanced RpcHandler and FSHandler.





7 comments:

14 Oct 2010

Where can I find these SimpleHandler, RpcHandler, and FSHandler implementations?

29 Oct 2010

You clould find the code here, but I don't know if it is up to date: http://mbed.org/users/iva2k/programs/iva2k_NetHttpServerTcpSockets/5yr3a/docs/files.html Yann

09 Feb 2011

When I tried creating my own handler it failed to compile with this error message:

Function "MyHandler::inst" (declared at line 12 of "httpserver_test/myhandler.h") is inaccessible (E265-D)

I solved the problem by making the static inst() function public instead of protected.

18 Oct 2011

There is a big-ass bug in the stack somewhere that causes pages to be truncated at the packet boundary. I am limited to 1530+someodd bytes and then I gotta call onWritable(). When I do that, the leftovers get written out like 4 times. WTF.

01 Jun 2012

Hi all. I need to do little modification to SimpleHandler class. I right-click on HttpServer library and select edit library but I could only see the source files (.h). How can I modify the definition of a method in the .cpp file, and recompile the library? Thanks in advance for your help. Darío

01 Jun 2012

You could try removing the networking library that you currently have linked in and use this one instead:

It should have the same functionality but with bug fixes and the sources should come down when you Edit the library.

04 Jun 2012

Thanks Adam.