7 ms·
This is neat. Honestly, in addition, I'd like to see something like Rack for C. The "gateway interfaces" for C are too implementation-specific (CGI, FastCGI, S
by rbranson 16y ago
This is neat.
Honestly, in addition, I'd like to see something like Rack for C. The "gateway interfaces" for C are too implementation-specific (CGI, FastCGI, SCGI, web server extensions/modules, etc). It would be something more abstract that would run on-top of a web server interface.
void application_main(web_request *request, web_response *response)
{
char body[1024];
snprintf(body, sizeof(body), "Hello, %s", request->param("username"));
response->status(200);
response->header("Content-Type", "text/html");
response->write(body);
response->end();
}
- roel_v 16y agoRather: response_set_status(200); response_set_header("Content-Type", "text/html"); response_write(body); response_end(); The awkwardness of which, to me, demonstrates the superiority of C++ in this regard.
- rbranson 16y agoYeah that's what I get for being in the OOP world for the daily grind. I think a C API is still definitely for the best. Perhaps a nice shortcut API for this would be something like: response_complete(200, body, response_header("Content-Type", "text/html"));
- jerf 16y agoThat implies some global state somewhere being updated, and now you've given up on threading. This may be OK, but it's still dangerous and leaky even if you give up on threading. There are various solutions that still allow you to pass a set of closures without being particularly more ugly than anything else is in C, for instance, see http://library.gnome.org/devel/gobject/stable/chapter-signal.html#closure http://library.gnome.org/devel/gobject/stable/chapter-signal... . C++ still ends up nicer, my point is just that you can do good things in C and there are libraries that implement the stuff for you. That said, if I were really going this route I probably would try to go with some sort of minimal C++. Then again, my opinion is suspect, as I would never go this route anyhow. Web developers writing in languages that don't permit buffer overflows write software that has all the security of a colander; adding the ability to write good, solid buffer overflows as well hardly seems like a step up. You can write secure C code, but you can write secure PHP code, too. Existence proofs of secure code aren't very interesting.
- DanWaterworth 16y agoYou're right, web developers already write software with all the security of a colander. You can go one of two ways, 1.) you can devise a language that can't express an insecure application or 2.) you can teach people about security. I know which option I prefer.
- jerf 16y agoI assume you mean #2? Because here we are in year, oh, 17 or 18 or so of web development give or take a couple of years and that's worked out so well, hasn't it? It's a beautiful sentiment. It hasn't worked. Handing them new vectors to screw up in is not going to solve the problem. It also doesn't matter. Hand a developer a tool that requires them to continuously pay attention to an issue and no matter how good they are, at some point they will slip, because they're human. We've tried "teach them about security" a couple hundred times, maybe it's time we try "devise a language that can't trivially express an insecure application". C will not be the language that implements that, it completely lacks any of the necessary primitives, by design.
- tptacek 16y agoOverly reductive. There is an actual security benefit to using environments that minimize memory corruption. Educating devs helps, but educated devs do not reliably avoid memory corruption.
- bdonlan 16y agoThey don't have to be global state - they can be updating thread local state, for example, in what is essentially dynamic scope. Depending on the OS, the efficiency of such TLS accesses can be quite good - on Linux, for example, it's just an extra pointer indirect or two with a segment selector (assuming the code is statically linked; it's very slightly more expensive in a solib).
- jerf 16y agoTouche. It's still an API design that's going to prove problematic, though.
- tptacek 16y agoYou're only a couple function pointers away from the syntactic sugar of the -> operator.
- VladRussian 16y agoin correct functional style shouldn't it rather be : response_set_status(response, 200); no issues with global state, threading (if correctly mutexed), etc...
- rubashov 16y agoAll the pieces to do the whole framework are already in POCO and other libraries, with ssl and cookies etc. http://pocoproject.org/docs/Poco.Net.HTTPResponse.html http://pocoproject.org/docs/Poco.Net.HTTPResponse.html http://pocoproject.org/docs/Poco.Net.html http://pocoproject.org/docs/Poco.Net.html Doing this in C seems silly to me.
- roel_v 16y agoWell yes it should have been response_set_status(handle, 200); My point was that the syntax in the example was C++.
- DanWaterworth 16y agoIt would be possible to support other gateway interfaces in raphters. The abstractions already exist.
- sigil 16y ago> The "gateway interfaces" for C are too implementation-specific (CGI, FastCGI, SCGI, web server extensions/modules, etc). It would be something more abstract that would run on-top of a web server interface. Yes. My preference in web apps (esp in C) is also to deal directly with http requests and responses. Although I wouldn't necessarily call that the "more abstract" approach. To an extent, each of these gateway interfaces is a different leaky abstraction for http.
- tptacek 16y agoAs an illustration of why C kind of sucks for web apps, that code is obviously insecure† (it's reflected XSS). To get around that while preserving natural syntax, you want: char *hsafe(const char *input); But where does hsafe get the memory for the string from? It can't use input (the filtered result is larger than the input). Does it malloc? Now you have to free the result. Does it do the inet_ntoa() thing with the static variable? Now you can't chain it (or use threads, but you wouldn't want to do that anyways). Maybe you can do an arena for each connection, so it's: char *hsafe(request_t *r, char *str) But that's still sort of painful. † In an admittedly artificial way.
- nkurz 16y agoI'm not seeing this a problem with C, but perhaps I misunderstand. Your goal is avoid including anything executable in the page. The filtered result is only larger than the input if you need the ability to faithfully quote the potentially malicious code. In this particular contrived example, you could "just" strip it out and make it shorter, or even error out if you see anything suspicious. Which is to say it's only a problem if you are doing it by hand on a per field basis. Which leads to your next point: > Maybe you can do an arena for each connection, so it's: > char *hsafe(request_t *r, char *str) > But that's still sort of painful. This is only painful if you are doing it by hand every time you use the parameter. If the framework handles it for you, so that you always get the sanitized result, it strikes me as no different than any other language. r->param("input"); // presanitized, lazily created, pooled in r r->param_raw("input"); // if you want to live dangerously Why is this worse in straight C than in something like Python that is doing the same thing but with an interpreted layer between you and the C?
- tptacek 16y agoYou need to convert < into <. That's the price of entry. You can't redefine the problem to "web framework that simply strips < out of inputs". Your framework would then be immediately inferior to every other framework which does output quoting.
- 16y ago
- rch 16y agoYou might look here before starting from scratch in C: http://okws.org http://okws.org (C++)