C or C++ HTTP daemon in a thread? - c++

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:
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.

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.

http://www.ibm.com/developerworks/systems/library/es-nweb/index.html
Seems exactly what you are after. You my need to do a small amount of re-writing to get it to run under FreeRTOS but its a very small, very lightweight web server.

I'm not familiar with FreeRTOS and how it supports TCP/IP and sockets, so I can't say for sure but you might want to take a look at the GoAhead web server. http://embedthis.com/goahead/

Related

When to use httptest.Server and httptest.ResponseRecorder

As title, when to use httptest.Server and httptest.ResponseRecorder?
It seems to me that I can also test my handlers to return correct response using httptest.Server. I can simply start a httptest.Server given with my implementation of handlers, then do validations on the response's body.
Please correct if I'm wrong, I am learning Go + TDD
When you just want to check, if your http.Handler does what it should, you don't need to use httptest.Server. Just call your handler with an httptest.ResponseRecorder instance and check the output as in the example.
The possible uses of httptest.Server are numerous, so here are just a couple that come to my mind:
If your code depends on some external services and APIs, you can use a test server to emulate them. (Although I personally would isolate all code dealing with external data sources and then use them through interfaces, so that I could easily create fake objects for my tests.)
If you work on a client-server application, you can use a test server to emulate the server-side when testing the client-side.

NPAPI plugin - Pass instance of xulrunner component (nsCOMptr)

I couldn't find a solution here after searching so I have to ask! Please excuse my language, because I'm pretty new in the NPAPI business.
What I have, is an existing plugin which receives data in a cycle of about 100ms out of a local running xulrunner application comming out of a nsComponent (the dataCreator). The result looks pretty well and the xul app is stable so far. But if I increase the occurance of data (which I have to), the xul app needs too long for reaction and this ends up in xul crashes. I think a XUL->Plugin I/O is a bit expensive!?
What I have learned until now, is that the plugin is able to create a new instance of a component:
// inside myPlugin.cpp
nsresult rv;
nsCOMptr< myCompClass > _myComPtr ;
_myComPtr = do_CreateInstance( "#myDomain.org/DIR/MYCOMPONENT;1", &rv ) ;
The function
do_CreateInstance( ) ;
comes from nsComponentManagerUtlis.h which is out of the xulrunner SDK, but it has nothing like
do_giveMeTheRunningInstanceOf( "#myDomain.org/DIR/MYDATACREATOR;1", &rv ) ;
My intuition now is to use the
nsScriptablePeer::Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result )
method to pass a nsCOMptr of the running dataCreator into the plugin, make direct communication possible and reduce the xul<-->plugin I/O to a minimum.
Creating another instance of the dataCreator is definitely not an option!
To be honest: I've no idea how to "convert" the NPVariant (args[0]) into the needed nsCOMptr, did you? Or is there another possibility to receive the pointer inside the plugin?
Thanks for your help
There is no way that I am aware of to interact with the xulrunner sdk directly from a npapi plugin, as they use totally different APIs. NPVariants cannot pass a xulrunner object or other native pointer type.
This is a total brainstorm and I have no idea if it would work, but if you could somehow combine a xulrunner extension and a npapi plugin into the same module, you could probably use a global map and an id from the plugin to get shared memory, but I have no idea if that's possible or not.
You are correct that interfacing with javascript has a cost; really, though, it's the individual calls that have the most cost because they end up being cross-process. Often you can minimize this by using more efficient calls. Faster than 100ms should definitely not be an issue.

Passing arguments to a program using another program

I have created two executables that accept command line arguments. Now, I want to pass arguments to available executables using C++ (executing on Windows). What is the best way of doing it?
I have used CreateProcess(); it's working fine for static input but I want to input dynamically through CLI.
The command-line (with arguments) is one of the parameters to CreateProcess(). Just put whatever arguments you want to pass on to the child executable in there.
What problems are you having with non-static input?
I usually use system(const char*) and it works for me :)
You pass over a string which contains the command as you type it in the command line. In your case it means the path to the exe file and the arguments it takes, with just spaces in between. It runs the specified process as if it was run from command-line.
For more information: http://www.cplusplus.com/reference/cstdlib/system/
It sounds as though you already understand that string arguments can be sent via CreateProcess at launch time. If you want to continue to send data at run time, you have a couple options.
Use console redirection. Since you are already using the Win32 API, it is not too far of a stretch to write to cin of the child process after you have launched it. See this MSDN article. I think this might be what you mean by "input dynamically through CLI"
Use some sort of IPC. There are Win32 ways of doing this such as message queues, and more platform independent methods such as Protocol Buffers, Thrift, or Boost.Interprocess.
There is really more than one way to skin a cat when it comes to IPC and your goal is to do your research and make sure you have made the correct design decisions early on for how your processes will communicate.
If you do decide to use a more full-blown IPC rather than something like console redirection to solve a smaller problem, some questions you should ask yourself are:
Will I be able to send all the types of data using this type of IPC?
Will this communication ever need to cross network boundaries?
And, the two big questions that always show up are:
How maintainable will this be in the future?
Will this code ever have to run on another platform?
Hopefully this response is not overkill for your question.

How to use c++ module with yaws

I don't have experience in using c++ with apache or other web server. But now want to use it with yaws to generate pdf from passed data. May be somebody has experience in doing so. Please any link. I havent found any. May be better to not use executable file but library and call its functions from yaws module.
Since you included the cgi tag on your question, one way to do this is to use the Yaws CGI capabilities. You'd simply run your C++ program as a CGI program. Yaws also supports FCGI, which lets you avoid starting a new instance of your C++ program for every request and instead have a dedicated TCP connection between Yaws and a daemon instance of your program.
Another way to do this is to write a Yaws appmod exporting an out/1 function. The argument to this will be an #arg record detailing all the information of the request being served. Your out/1 function could then call into an Erlang NIF written in C++, passing whatever information from the request it needs, and then taking replies and giving them back to Yaws as responses. PDF data could be returned from your NIF as Erlang binaries. With this approach, your C++ code runs in the same OS process as Yaws, so you have to be careful that your code never crashes else it will take the whole Erlang VM down with it, but aside from that this approach would be more efficient than FCGI or CGI.

how to get trusted time in an app, ntp maybe?

My app will need to periodically access a trusted time source, so can not rely on system time since this one can be modified easily by user or batery failure etc. My first idea is to statically link to libntp (from ntp.org) and use its functions, is this a good idea?
Libntp looks a bit complex framework, is there some simpler, client implementation (preferably ANSI C since the app needs to be for different platforms... though can be also Cpp if can be compiled with gcc / MS VS)?
Is there some other alternative to ntp?
Thanks!!
Edit: Just to add some more info... it is important that the trusted-time-server values can not be modified (lets say, attacker modifies the trusted-time-server response and app accepts fake time). I started looking at ntp and see that it takes care of that issue. The question is now should i use ntp sources from ntp.org as a starting point or there are some simple client-only implementatios? Ideally, some pointer to which module / source files from ntp.org sources should I use for client-only implementation and which header file shows the API I need to use, like for example a call getTrustedTime()... etc.
If you can rely on there being a network connection, your application could ask a remote server for the time, perhaps also over a signed or encrypted connection.
If you are using Boost you could use this