Showing posts with label servlets. Show all posts
Showing posts with label servlets. Show all posts

Tuesday, 23 November 2010

Yet Another... Web Framework (in C++)

What? YAWF - yet another web framework? But this is mine(!) ... and it's very small - a Simple Embeddable C++ Webframework for Qt!

1. The need


I have discussed this topic on this blog earlier*, so you shouldn't be surprised to hear about it again: a C++ web framework. You'd think there isn't such thing? Wrong! From my own research and from the comments of friendly internauts I collected a quite a list of possible frameworks:
And recently I found even another one:
  • CppCMS


    Do you see its cool logo? It says that programming in C++ is a good thing, as it isn't hard on the environment, and thus can maybe even stop the global warning ;). I must admit that I never seen C++ from that angle! Interesting point, isn't it? Ok, when you think of all that multicores and figths about cache lines then C++ does quite naturally comes to mind with its very direct memory control, doesn't it? Kind of "lean programming" :).
And don't forget the new kid on the block:

It's rather a wide range of possiblities, so you'd think the world doesn't need another framework, and least at all by yours truly. That's what I thought too, untill I stumbled upon a rather simple problem. Currently I develop a Qt application that runs in the background (call it demon, service, headless, etc.) and would like to have an admin interface for it. Of course I could write a standalone GUI client connecting to the application's command socket but that's so nineties! Only a web interface is fashionable these days. Thus I need a small webapp for the admin console.

So at first then, I thought I'd use some open source code from the above list. But all of them would either not integrate well with Qt events, or require 3rd party includes and dependencies, and gwan would even have to be started as an external server! Well, I didn't use gwan before and it does sound like a border case usage for it, just imagine all that debugging of its servlet compiler in run-time...

Then you may ask: isn't there any HTTP server in the Qt framework? Yes indeed, I found one, but it's an extension of the framework (they call it an option I think...) and it's running as Windows service, not as an additional interface to an existing binary. So we've got the same case as with gwan. BTW, why hasn't C++ a standard HTTP server class? Go has one, Python has one, Javascript has one, but C++ - nope! Well, that's not completely true, CINDER framework has one, and cpp-netlib got one as well, but I wanted to avoid big includes and dependencies like Boost.

But hey, Qt has a couple of HTTP support classes, so I thought: boy, that cannot be that hard! And I just hacked my own mini HTTP server.

2. The design

Of course that gives me an opportunity to design a web framework the way it should be always designed at last :-), because all the others seem to be somehow overcomplex or overcomplicated :-). So let's go down to the brass tacks then!

First we have to decide on the name - let simply try YAWF(4q), and in best software giant tradition I'll use an internal codename, for example "CutieW".

The design will be simple, plain and oldskool, as I need something working and that fast. Besides, never underestimate the power of KISS!

The basic ingredients are the Qt classes for TCP socket handling and HTTP request and response parsing. Then we'll have request handler objects with a process() method. The handler objects (kind of servlets for the Java minded) will have to be derived from a superclass (how uncool, I know) and statically instatiated, so that they can register themself with the server in the startup phase. They register with a name string**, for example "user" or "page", so they can be bound to an URI (see below for the example).

Let's sum it up: there will be a server executable, it will set the URL path configuration in startup phase, each path wil get its own handler. When a request arrives, a fresh instance of the handler will be created, this the handler classes need a clone() method for this.

The server will thus find the matching handler prototype for the URI, clone it, and then invoke its process() method. As you see, there's 1 to 1 relation betweem URI and the handler object in the current implementation, but an extension to "multiple dispatch" isn't difficult, and I'll program it when I have some spare time.

Now to the general usage pattern of YAWF4q. In Clojure you'd write the following:

  (defn display []
(html [:h1 "hello!"]))

(defroutes myroutes
(GET "/" [] (display)))

(defonce server (run-jetty #'myroutes
{:join? false
:port 8080}))
In cpp-netlib this:
  struct hello_world {
void operator()(server::request const &request,
server::response &response) {
// your code here ...
}
} handler;
  server server_(argv[1], argv[2], handler);
server_.run();
But in yawf4q it's all pretty plain, non-clever, and almost boring:
  #include "CuteHttpServer.hpp" // the cutie

int main(int argc, char* argv[])
{
// your application:
QApplication* qtAppl = new QApplication(argc, argv);

// the webserver on port 3100
ibkrj::yawf4q::CuteHttpServer testServer(3100);
string error;

if(!testServer.start(error))
return -1;

// run Qt
qtAppl->exec();
}
The server just starts, finds the config file (using a default, hardcoded name), sets the routes, and waits for requests. If you don't define any handlers, a simple "I'm alive" response is sent back.

3. The example


How to write your handlers? Look, you have to derive them from the TestHandlerBase class. First let us implement the handler of the index page:
  class TestHandlerBase
: public MiniHttpHandler
{
public:
TestHandlerBase()
: MiniHttpHandler("TestHandlerBase") {};
// base overrides
virtual MiniHttpHandler* clone() { return new TestHandlerBase; }
virtual void process(AnalyzerRequest& reqData, std::string& respData);
} g_handler1;
OK that's rather much boilerplate, as we need to supply the name string plus the clone() and process() methods, so maybe I should provide a macro like this:
  // --- OR maybe a MACRO?:
class TestHandlerBase
: public MiniHttpHandler
{
public:
BASE_TEST_HANDLER_FUNC(TestHandlerBase)

... your functions ...
} g_xxx;
I don't know, as a matter of fact I hate macros in frameworks! But as an alternative maybe it isn't that bad. Another possibility would be using CRTP, as to automatically add the clone() method, but wouldn't you say this would be somehow too clever when compared with the rest of the design?

And here is the processing method:
  void TestHandlerBase::process(AnalyzerRequest& reqData, std::string& respData)
{
respData = " TestHandlerBase alive!!!! ";

respData =
"<html><head>"
"<title>TestHandlerBase is alive!</title>"
"</head><body>"
;

respData.append("<h1> Input your user data: </h1><p></p>");
respData.append(testform); // HTTP form for UserName, UserMail and Text, action="person"

respData += "</body></html>";
}
OK this doesn't look very cool, but the view component isn't yet there, wait a little. What this handler does is to ask for some user data. Now the second handler follows, which will processes the submitted user data:
  class TestHandlerPerson
: public MiniHttpHandler
{
public:
BASE_TEST_HANDLER_FUNC(TestHandlerPerson); // here process() is already defined

} g_handler2;

///////////// impl:
void TestHandlerPerson::process(AnalyzerRequest& reqData, std::string& respData)
{
respData =
"<html><head>"
"<title>TestHandlerBase is alive!</title>"
"</head><body>"
;

respData.append("<h2> Thank you for your data! </h2>");

// parse the data for display:
map<string,string>& data = reqData.formularData;
map<string,string>::iterator iter;

respData.append(
"<table border=\"1\" width=\"70%\"><tr>"
        "<th><b>Field</b></th><th><b>Value</b></th>"
"</tr>"
);

for(iter = data.begin(); iter != data.end(); iter )
{
respData.append("<tr><td>").append(iter->first).append("</td>");
respData.append("<td>").append(iter->second).append("</td></tr>");
}

respData.append("</table>");
respData.append("<p></p> <a href=\"/index.html\">Back</a><br>");

respData += "</body></html>";
}

Rather grotty servlet or .jsp style here, isn't it? Mixing presentation with code?!

Don't despair, you can use a template. Yes, let's be modern! I chose the mustache :{{ template syntax. I decided for mustache, well, because it's pretty new, generates much buzz, and isn't looking too bad. For those who don't know mustache, it is a simple HTML templating syntax with values encoded like this:

  {{value}}
and sections, which can be rendered multiple times, if they receive a list as input data:
  {{#section_X}}
{{value1}} => {{value2}}
{{/section_X}}
So there's no need to code anly loops in the template. YAWF contains an implementation of mustache :{{, which seems to render correctly all the examples I found in the online mustache docs. The implementation is based on a simple idea: the template is parsed into a linear sequence of "nodes", and the data items passed to the template take care of rendering and walking the node list. Have a look at the source code*** if you want.

So our response handler would now look like this:
  // using templating:
#include "CuteMstchData.hpp"
void TestHandlerPerson::process(CuteSrvRequest& reqData, std::string& respData)
{
string templ =
"<html><head><title>TestHandlerBase is alive!</title>"
"</head> <body> <h2> Thank you for your data! </h2>"
"<table border=\"1\" width=\"70%\">"
"<tr><th><b>Field</b></th> <th><b>Value</b></th></tr>"
"{{#datatable}}"
"<tr><td> {{field}} </td> <td> {{value}} </td></tr>"
"{{/datatable}}"
"</table><p></p>"
"<a href=\"/index.html\">Back</a><br>"
"</body></html>";


// convert data to JSON represenation:
map<string,string>& inpData = reqData.formularData;
map<string,string>::iterator iter;
int i;
ibkrj::yawf4q::CuteMstchValMap templData;

for(iter = inpData.begin(), i = 0; iter != inpData.end(); iter++, i++)
{
templData.addToList("datatable", i, "field", iter->first);
templData.addToList("datatable", i, "value", iter->second);
}

// display page with data (the View of MVC)
respData = CuteHttpHandler::renderThis(templData, templ);
}
It maybe doesn't look much better than the plain HTML code, but here we could save the template in file, and read it in at the runtime. And we've got the View part of the MVC pattern. The handler objects stand for "C", but so far don't have support for "M" in YAWF4q.

Now, as last part of the puzzle, we have to configure the server paths, but this is simple:
#
# test configuration
#

index.html$ :: TestHandlerBase
person/.*$ :: TestHandlerPerson

You see, regular expressions are supported. Now let it run baby! The first handler gives us:


















Then we willingly give our data:



















And see the results:













4. Summing up

At the moment the code*** is only very basic, as I haven't got time to work on it a much as I'd like. I wrote it on my private time, as my customer did decide in favor of a general, grand-scheme, system management solution. So as for today, I wrote only a single test, that one which was described above, and tested it with Visual C++ on Windows. YAWF isn't more than a toy just now as many features are simply missing, for example I'd like to have a built in support for configurable error pages to round the things off. And as next thing, I'd like to add the Model component using my CuteWorkers framework (I hope I'll come to write a post about Qt-workers too).

But there's much more that could done, like:

- HTTPS support in the sever (that shouldn't be very difficult as Qt offers QSslSocket and other classes)
- cookies and session data handling
- dynamic loading and caching of the templates
- dynamic loading of the servelts vial DLL (kind of what ASP is doing)
- a "Clojure example" like dynamic interface

and so on, and so on. Look at my TODO list in the github repository. Nonetheless it's simple (KISS!), it's pluggable, it doesn't have any dependecies other than Qt. Requirements fullfilled!

--
* check out these previous posts: servlets-in-c.html, c-servlets-again.html, c-server-pages.html

** we cannot forget that C++ hasn't much to offer in terms of introspection. But we won't give up automatic registration and detection of handler prototypes!

*** You can find the code at Github: https://github.com/mrkkrj/yawf4q


Wednesday, 18 February 2009

C++ Server Pages

In my prevoius blogs I wondered if there is/could be a C++ implementation of the Java's Servlet interface(s)*, and recently a friendly fellow blogger** pointed out to me that there already is one, viz the CPPSERV: http://www.total-knowledge.com/progs/cppserv/!

Can you see C++ it its logo?

I cite*:

CPPSERV is a web application server that provides Servlet-like API and JSP-like functionality to C++ programmers.
...
CSP (C++ Server pages), the JSP equivalent for CPPSERV, are currently implemented as a precompiler that converts CSP source to C++ source of a servlet, which, in turn needs to be compiled into CPPSERV servlet
.
...
Current CSP implementation supports basic parsing, as well as compile-time taglibs.

Well, that's it! Or perhaps not? What we have is the equivalent of the Java's JSPs, which generally suck, and standing alone are too week a framework for serious work. But hey, it's not that bad, as we have got some choices: the CPPSERV for the oldskool JSP-like programming, the late Bobcat for more of the same, or the Wt framework*** for more modern, GWT-like work!

And with some discipline (I mean the model 1 ;-))) servlets, do you remember???) it's possible to get working application in C++ quickly! And all that Java frameworks out there are only trying to hide the JSP processing model, and they aren't that beautiful themselves. So for smaller things a JSP-like solution will be probably sufficient, and for more modern applications (including AJAX support) I'd choose the Wt framework.

There remains the question of the OO-Relational mapping, an the creators of CPPSERV suggest using their SPTK classes****, but it seems to be only a JDBC-like DB access layer. I suppose, I'd rather take Qt's DB classes for that, but on the other side, they are somehow heavyweight. But the OO-Relational thing for C++ is a different question in itself. But JDBC style access isn't that horrible either, and in a whole I think there are some viable options for C++ web applications out there!

Now I guess, I should try out the 2 frameworks, but ... ehm ... you know, so little time, so many books...

PS (07 Oct. 2009): meanwhile I have detected two another C++ and C "Servlets". Well they aren't really Servlets, but are rather one step back on the evolutionary path, and are somehow JSP-equivalent. The first of them is named KLone and allows you to include C scripts in the HTML page in the exact JSP manner. The other is GWAN - it's free and it allows you to write "servlet" scripts in C, which will be executed by the server and generate the HTML output - so in this case we are almost there, except for the very limited set of functions you can use in the script. Nonetheless, very interesting!

--
* see: http://ib-krajewski.blogspot.com/2008/10/c-servlets-again.html
** Gavino, unfortunately his profile isn't available :-(((, but nonetheless, thanks bloke!
*** The Wt-framework ("witty" - http://www.webtoolkit.eu/wt/)
**** SPTK: mainly a GUI framework, but it has some DB access support as well: http://www.sptk.net/index.php


Tuesday, 7 October 2008

C++ servlets - again

It looks like it's getting to be a new hobby of mine: collecting C++ web application frameworks. After the first one* (a simple HTTP server and session classes) and the modern one (Wt aka witty)**, now the "missing link" was found: the classic Java-like Servlet container implementation in C++! This was made possible by a friendly fellow blogger Eduardo Zea.

Eduado was kind enough to give me a link to the DDJ article describing such an implementation by Rogue Wave named Bobcat***. It's quite old (by SW-industry standards) and the link to evaluation downloads doesn't work anymore, so I think, it didn't quite catch on. But it's another one in my collection! So the actual counters are C++=3, Java=googol.

PS: To be more precise, Bobcat functionality is now part of the Hydra Express****, a Rogue Wave's SOA publishing framework. So are we all going SOAP?

---
* see: http://ib-krajewski.blogspot.com/2007/09/servlets-in-c.html
** The Wt-framework: http://www.webtoolkit.eu/wt/
*** John Hinke, Implementing C++ Servlet Containers, April 01, 2002: http://www.ddj.com/184405023
**** http://www.roguewave.com/blog/so-what-is-it-with-rogue-wave-and-xml-soa/

Tuesday, 26 February 2008

Rentree plus Some Comments on Google-Solvers & Co

Hi everybody! I'm back from my travels and can write some more blog-gobbledegook again (which I'll gladly do). I was away for some serious off-piste skiing in St.Anton, descending some pretty steep, big faces, and taking my first pinwheel tumble on a 40 degrees, Alaska-like, highly exposed, rock-fringed slope. Whow! And then I was back in town, and procuring my next project in just 2 days, taking a head-first plunge here as well ;-).

So let me start my rentree into the blogosphere with something less exciting, i.e. some comments on my previous posts. In fact, I wanted to comment on the Google-Solvers post for quite a long time, so it suits me fine.

Commenting on Java vs. C++


As some of you maybe remember, in a previous post* I compared the perfomance of Python, Perl, Java and C++ (admittedly in a rather ad-hoc manner), and made at first the error of not using the optimization switch of my C++ compiler. Me, a die-hard C++ hacker!!! This resulted in Java and C++ being on par performance-wise. So you can imagine my amazement some time ago when I saw in Uncle Bob's blog these statements**:

You can blame this on the non-optimized gcc compiler I was using (cygwin) but again: Oh boo hoo!. If there are any C++ programmers out there who smirk at the supposed slowness of Java, I think you'd better reconsider.
...
I'll grant you that the JVM can be large. However, if you assume it's already there, then the size of the bytecodes for the application itself need not be very large at all. And the heap can be constrained to a relatively small size to prevent virtual memory thrashing. So, if _engineered_ a java app should give a C++ app a run for it's money in most cases. -UB

Well, this started me thinkig. When you are looking for information concerning Java performance, you can see some typical quotes like this on the web ***:

John Davies: It is just the main reason why there are still diehards that stick with C/C++ because you can guarantee performance, not necessarily faster, but it just guarantees the performance and we will run something in Java, it will run quite frequently faster on C [he means JVM] than it would have done in C/C++, but every now and then it will just pause and that pause can be extremely expensive.
If you'll allow a small comment (hypothesis?, heresy?) from yours truly: what if all those measurements are done without the -O2 switch? It's an all to easy trap to fall into (see my own sufferings*) and an excellent opportunity for the marketing people to use some techniques from the seminal book "How to Lie with Statistics" ;-). Becuse you really can't explain to me that a language which is: 1. interpreted, 2. relies heavily on dynamic memory allocation, and 3. supports garbage collection, can be faster than one which doesn't do it, no matter how much optimization you throw at it! Or can you? If you've read the "Discipline of Programming" book of E. Dijkstra, you know that the first law he establishes there is the "there-are-no-miracles law" :-). So you may guess my position on this.

BTW, maybe I (or someone else) should email Mr. Stroustrup on this one, and see what he's got to say. It would be interesting, I guess, so maybe I'll do it anyway.

And now more comments


Let's continue in the commenting vein: sometime ago I was looking for web-frameworks in C++, and wanted even reimplement Java's Servlet classes in C++ (well, I didn't...). But in the last DDJ I saw an article**** about a C++ web-framework at last! Fortunately, I didn't implement the C++ servlet classes, because it was a really stupid idea! The Wt-framework ("witty" - http://www.webtoolkit.eu/wt/) seems to be rather like modern Java frameworks - GWT, ThinWire or Wicket - you define your application classes in C++, and the HTML rendering comes from the framework! In contrast to the Servlet specification, which is very low level and which nobody uses directly now! Thank God I was lazy! I'll have to try Wt out, perhaps there is an C++ alternative for web-programming anyway.

---
* http://ib-krajewski.blogspot.com/2007/07/google-solvers.html
** here he did basically the same but with Ruby in place of Python: http://butunclebob.com/ArticleS.UncleBob.SpeedOfJavaCppRuby
*** "Improving JVM scalability and performance": http://blog.chinaunix.net/u1/45382/showart_356477.html or http://go.techtarget.com/r/1950475/6108168
**** "Wt: A Web Toolkit": http://www.ddj.com/cpp/206401952

Sunday, 2 September 2007

servlets in C++ or 2 small C++ ideas

As I was recently reading the article of Stefan Wörthmüller "C++ Versus JEE"*. Basically Stefan argues that:

"If you want to write a server application, you need control. Maybe even control about your failures. But you need control."
And that of course is what C++ will give you. For the details refer to the article. However another sentence got stuck in my mind:
"I still wonder why there are so few approaches for Web frameworks/toolkits or application servers written in C++. C++ is made for such a task."
So I've got that big ;-) idea: why shouldn't I take the Servlet specification, restate the interfaces in C++ and code the Servlet classes and (perhaps) a servlet container! Why not use the language which is known to me (and many other server-side programmers) and combine it with an iterface which is known to many web-developers (i.e. Java programmers) to get the best of the two worlds? This will be a big success!!! Ok, I tell you why: no spare time.

But I still think this idea is not bad. It goes in the same vein as my other idea about C++: why should I use scripting languages for scripting? I can do everything just as well in C++. Ok, not everything, I would have to write some template libraries to plug the holes, but in principle I could. I didn't pursue this idea very long, but after some time I found the same reasoning explained more lucidly in the rationale of Boost's "Filesystem" library:
"The motivation for the library is the need to perform portable script-like operations from within C++ programs. The intent is not to compete with Python, Perl, or shell languages, but rather to provide portable filesystem operations when C++ is already the language of choice."
Then there is the Boost::String library which makes possible the Perl-like manipulations of strings... We are almost there.

But end of digression! The main theme of this entry are C++ servlets! So back to the web programming.

For some time I tried to find some C++ web frameworks by googling, but nothing useful emerged. So I a sort of gave up. Till today. I was googling for documentation of the OSE RTOS by Enea when I stumbled upon the OSE library. OSE, whassat? Never heard of it! Another legacy do-it-all framework? It turned out that this library was long time popular in Australia, and more: it has a HTTP Servlet support! At last!! It supports HTTP Session objects, XML, and its HTTP Daemon class seems to be a sort of servlet container. From what I've seen, its interface is different form Java's HTTPServlet class, but it is a start! Maybe one could combine it with a non-JSF view technology (Velocity?) to enhance it further? So maybe I will be able to pursue my idea nonetheless? But is it worth the candle? I would be only a copy of an existing technonogy, certainly not an "killer app" and not a new approach. Or maybe not?

----
* Dr. Dobb's Journal Jun 21, 2007, http://www.ddj.com/dept/cpp/199905990