Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C or C++ HTTP daemon in a thread?

Tags:

c++

http

I'm starting up a new embedded system design using FreeRTOS. My last one used eCos, which has a built-in HTTP server that's really lightweight, especially since I didn't have a filesystem. The way it worked, in short, was that every page was a CGI-like C function that got called when needed by the HTTP daemon. Specifically, you would write a function of the form:

int MyWebPage(FILE* resp, const char* page, const char* params, void* uData);

where page was the page part of the url, params were any form parameters (only GET was supported, not POST, which prevented file uploads and thus made burning the flash a pain), uData is a token passed in that was set when you registered the function, so you could have the same function serve multiple URLs or ranges with different data, and resp is a file handle that you write the HTTP response (headers and all) out to.

Then you registered the function with:

CYG_HTTPD_TABLE_ENTRY(www_myPage, "/", MyWebPage, 0);

where CYG_HTTPD_TABLE_ENTRY is a macro where the first parameter was a variable name, the second was a page URL (the * wildcard is allowed; hence page getting passed to MyWebPage()), third is the function pointer, and last is the uData value.

So a simple example:

int HelloWorldPage(FILE* resp, const char*, const char* params, void*)
{
    fprintf("Content-Type: text/html;\n\n");
    fprintf("<html><head><title>Hello World!</title></head>\n");
    fprintf("<body>\n");
    fprintf("<h1>Hello, World!</h1>\n");
    fprintf("<p>You passed in: %s</p>\n", params);
    fprintf("</body></html>\n");
}
CYG_HTTPD_TABLE_ENTRY(www_hello, "/", HelloWorldPage, 0);

(Actually, params would be passed through a function to escape the HTML magic characters, and I'd use another couple functions to split the params and make a <ul> out of it, but I left that out for clarity.)

The server itself just ran as a task (i.e. thread) and didn't get in the way as long as it had a lower priority than the critical tasks.

Needless to say, having this proved invaluable for testing and debugging. (One problem with embedded work is that you generally can't toss up an XTerm to use as a log.) So when Supreme Programmer reflexively blamed me for something not working (path of least resistance, I guess), I could pull up the web page and show that he had sent me bad parameters. Saved a lot of debug time in integration.

So anyway... I'm wondering, is there something like this available as an independent library? Something that I can link in, register my callbacks, spawn a thread, and let it do the magic? Or do I need to crank out my own? I'd prefer C++, but can probably use a C library as well.

EDIT: Since I'm putting a bounty on it, I need to clarify that the library would need to be under an open-source license.

like image 490
Mike DeSimone Avatar asked Feb 26 '10 16:02

Mike DeSimone


2 Answers

I suggest you have a look at libmicrohttpd, the embedded web server:

  • http://www.gnu.org/software/libmicrohttpd/

It is small and fast, has a simple C API, supports multithreading, is suitable for embedded systems, supports POST, optionally supports SSL/TLS, and is available under either the LGPL or eCos license (depending). I believe this fulfils all your requirements. It would be trivial to wrapper in C++ if you preferred.

like image 136
gavinb Avatar answered Nov 06 '22 18:11

gavinb


Mongoose is licensed under GPLv2 and is lightweight (just one C file so easy to include into a new project). It will run in a separate thread and support callbacks.

like image 2
Zitrax Avatar answered Nov 06 '22 19:11

Zitrax