Witty is great for creating complex web applications as it simplifies and automates a lot of the necessary back-end work. However, when all you need is simple HTTP request and response, things need to be modified slightly to have it work correctly. This is what happened when we needed some low-level access to the underlying web server.
When we create a standard Witty application, we typically use Wt::WServer::addEntryPoint()
to add a specified application to the web-server at a specified base URL. This function takes the ‘type’ of entry point as the first parameter.
The standard type is of Wt::Application that results in Witty spitting out more than 100kB of data on a HTTP connection. It spits out a whole bunch of HTML and Javascript to prepare the underlying application layers for use. This will not do when we need low-level access.
The other type is of Wt::WidgetSet that results in Witty spitting out a bunch of Javascript, which is meant to set up the widget as an independent plugin for other applications. This is when I learned that Witty 3.3.2 ships with JQuery 1.7.1 instead of 1.4 as I previously thought.
Neither of these methods worked.
However, the other method is to actually use Wt::WServer::addResource()
to add a ‘resource’ at a specified base URL. This function takes a Wt::WResource class as a parameter.
What is a resource? It is essentially a file. As far as the client is concerned, it is merely accessing any other regular web resource. However, what it does on the server end is expose a Wt::WResource::handleRequest() virtual function that is called whenever this resource is requested.
This virtual function contains two parameters, a Request and Response object. This is what we need to get low-level HTTP access to the underlying server. However, we are still not completely free to do anything that we want as the underlying server still maintains some security.
For example, when I tried to perform a GET request with an attached body payload, contrary to what a GET request is supposed to do, the underlying server blocked the request and never fired the related virtual function. However, when I use POST/PUT, it would fire the related virtual function.
The same goes with responses. When I tried to set some custom response status such as 599, the underlying server refused to let me set it and changed it to the more benign 500 instead. So, the underlying server still does some filtering of both requests and responses.
While all we need to get underlying data is to use Wt::WResource there are many specialised child classes that are more suitable for everyday use. One such class is the Wt::WStreamResource and Wt::WFileResource classes that have build in functions for transmitting any C++ stream or file-system file.
Anyway, this is all very useful in the end and I thought that I should share it.
0 Comments