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.
I suggest you have a look at libmicrohttpd, the embedded web server:
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With