14 ms·
Httpserver.h: Single header library for writing non-blocking HTTP servers in C
- anon9001 7y agoNeat, but why? Is it just the novelty that it can be done? I thought it was poor form to have a lot of code in headers. This seems like it'd be better served as a small C http library.
- foota 7y agoI think the main reason is simplicity. No need to muck around with custom make files if you can just include the header and call it a day.
- sigjuice 7y agoA makefile will most likely already have a list of .c files. Why not add one more .c file to that list and call that a day?
- astrodust 7y agoFor tiny things like this I'd prefer a single header file over something that's a compiled dependency.
- rcfox 7y ago> I thought it was poor form to have a lot of code in headers. It is mostly because it makes it harder to reuse compiled objects when you make a change and rebuild. For a drop-in library that you're probably not editing, this shouldn't be an issue.
- downerending 7y agoI can see it either way, but for a tiny program this could be handy. For a larger program that already has multiple source files, it seems like it'd be better to keep it in a separate file (to make the git diffs easier to follow, for example). It would be better if it was namespace'd in some way, at least by using a common unusual prefix for all of the non-local symbols. It wouldn't be hard to clash with the chosen names.
- Chabs 7y agoIt traditionally leads to bigger executables and longer compile times. With modern compilers, both of these are non-issues for "most" reasonably-sized projects.
- deleted 7y ago[deleted]
- giancarlostoro 7y agoI like this. I've become a huge fan of using Go for web stuff since it's baked in to the language and I can get solutions really quickly. I'm more likely to go through this code though because it looks interesting.
- jonny383 7y agoGo compilers are anywhere near as universally available as C compilers...
- giancarlostoro 7y agoTechnically if you can compile once on one arch a Go binary will run on any distro from what I've heard. You can also cross compile. There's also gccgo and I'm sure other efforts. A decent number of Go projects are advertised to run on a Raspberry Pi. I think that's good enough. I've gone as far as compiling Go from my Android phone. Edit here's someone else running Termux with Go: http://rafalgolarz.com/blog/2017/01/15/running_golang_on_android/ http://rafalgolarz.com/blog/2017/01/15/running_golang_on_and...
- jonny383 7y agoWow awesome. I never knew. Thanks!
- giancarlostoro 7y agoNo problem, I tried out Termux mostly to test it out, and I was impressed. I was able to run a Web Server in Python... and Go was a similar story. You could open it up on your browser and all. I'm convinced all one needs to hack into any system is a good Android device with enough storage, or iOS device with their Linux emulator.
- app4soft 7y agoOh man, I remember that 10 years ago I used my Symbian (Nokia 3230, later N82) smartphones as web server.[0] [0] http://www.allaboutsymbian.com/news/item/4192_Raccoon_Apache_web_server_for_.php http://www.allaboutsymbian.com/news/item/4192_Raccoon_Apache...
- _bxg1 7y agoQuestion: I thought any given C code could go in either headers or c files (or rather, split between headers and c files), and that the difference was only a build concern. So why wouldn't a given library be available in both forms, unless one of them just makes no sense at all? Put differently: why isn't this just "Minimal library for writing non-blocking HTTP servers in C" which people understand to mean "this might make sense to put in a header"?
- zelly 7y agoShort term convenience Long term technical debt
- noobermin 7y agoHow much of that comparison ignoring the time sink that is setting up linkers and dealing with that whole lotta mess. Header only works for some things (particularly things that require no globals, singletons, etc) and that's a valid concern. Saying header-only = long term technical debt always (or even most of the time) feels like an assertion because I've only heard hypotheticals around why it is bad.
- zelly 7y agoIs it really a time sink? You have to have a build system anyway to link together your project itself, assuming it's bigger than a single-file hello world. One extra line in your build system should be the least time consuming part of adding a new foreign dependency--you still have to vet the code for security and figure out how to use it. Unless you're using C++20 modules, you also have to deal with possibly including the header multiple times (slowing down builds), namespacing, macros potentially defined by the header, or a bunch of external/internal linkage edge cases. You only ever find out about these problems once it's too late to remove that library for a different one.
- doliveira 7y ago> One extra line in your build system should be the least time consuming part of adding a new foreign dependency Could, should. IRL Docker became a thing mostly because of the hassle it is to do so in C.
- jacob019 7y agoMight go well with embeded hardware
- maxk42 7y agoh2o [1] is a web server and C library that not only supports http 1 & 2, but also usually tops the TechEmpower benchmarks [2]. [1] https://github.com/h2o/h2o https://github.com/h2o/h2o [2] https://www.techempower.com/benchmarks/ https://www.techempower.com/benchmarks/
- noobermin 7y agobrundolf is asking a similar yet different question, so I'll ask mine: I've heard about modules coming to C++. What are the concerns with headers exactly? I'm aware of the issues with duplication in object files and ballooning build times, but are there other issues? Is it then something that primarily affect very large code bases?
- Gibbon1 7y agoNot a C++ monkey but headers in C/C++ have the problem that you can't parse them independently of the source file they are included in because of the predecessor. Which means you need to re-parse them each and every time they are included in a project.
- celticmusic 7y agoI think you meant preprocessor, not predecessor, lol. I had to reread that a time or two. I knew what you were trying to say and I still got confused by it.
- Gibbon1 7y agod'oh!
- shakna 7y agoHowever, every modern C compiler and tools like cmake allow you to use precompiled headers to avoid that step if it is what you want to do.
- ratww 7y agoI think different people will have different answers. The biggest complaint is that this slows down builds, of course, but it also requires hacks to avoid re-including the same header twice when you have complex header hierarchies [1][2], bleed-trough of macros and pragmas, and of course you have to write forward declarations for everything you intend to publicly expose, as opposed to using a "public" keyword. Honestly I dislike them because they're a redundant pain in the ass. I tried other solutions before (at one job I had 15 years ago we had automatic header code generation, ooof), and although modules are not that ready for primetime [3] (dependency resolution need to be done by an external program), I think they'll be the bees knees. [1] https://en.wikipedia.org/wiki/Include_guard https://en.wikipedia.org/wiki/Include_guard [2] (some people will be quick to note that can be solved by pragmas) [3] https://vector-of-bool.github.io/2019/01/27/modules-doa.html https://vector-of-bool.github.io/2019/01/27/modules-doa.html (but he wrote a follow up: https://vector-of-bool.github.io/2019/03/04/modules-doa-2.html https://vector-of-bool.github.io/2019/03/04/modules-doa-2.ht... )
- ebeip90 7y ago1100+ lines and barely a comment after the initial block. It also defines some buffer size names that are likely also declared in other libraries, like `BUF_SIZE`, and will need to be `#undef`ed.
- jonny383 7y agoTo be fair, most of the actual code doesn't warrant comments, and there's no point of writing comments for the sake of writing comments or repeating what the code is already telling you explicitly what it does.
- noobermin 7y agoEchoing the reply saying comments aren't always warranted but making more verbose yet safer macro names might be a good recommendation.
- sedatk 7y agoThis kind of thing is the reason that header files should die and a new module system should emerge in the world of C/C++. "Header-only" should stop being a novelty. Distributing or consuming libraries should be much more straightforward and easy as with modern languages. I'm not sure C++20 modules are the solution, but this certainly isn't.
- jonny383 7y agoThis is C, not JavaScript. Does anyone really want an npm of the C world? Header files work. They've worked for many decades. Yes, they require software authors to _do more work_, but they also help to eliminate a lib/ directory with 10,000 interdependent libraries that quickly becomes untrusted and frankly, ridiculous.
- rat9988 7y agoI'm not sure what you are criticizing really. npm is by far better than what we have in the C world, and why npm in particular? Because it's easy to bash?
- mschuster91 7y agoFar better? Lol nope. In the C world the OS distributions and the general nastiness of shipping libraries outside of an OS distro at least turn away the newbies who think that the world needs yet another module that pads a string to X length. The hardness of C is its weakness but also its strength. C programmers at least tend to know basic programming and OS management skills while JS programmers... oh hell I'm happy I got out of the mess that is "modern" frontend development.
- jiofih 7y agoYou still haven’t said a single word about package management.
- mschuster91 7y ago
- jsd1982 7y agoIt's non-blocking for its own http request/response handling but will it allow you integrate with its event loop and register your own events to react to? Can your request handler make its own network connections as a client to other servers in a non-blocking way?
- nemasu 7y agoYeah I was thinking this too, it doesn't seem like it. It's still blocking on http_server_listen.
- gigel82 7y agoYou forgot to add "for Linux/BSD".
- app4soft 7y ago"for *nix/BSD/Mac"
- z3t4 7y agoI like that it looks like Node.js http module. But I'm too scared to use C with pointers and malloc, so I'll stick to Node.js. I'm however jealous of people that are competent in C, assembly or any other low level systems language.
- koolba 7y agoTry it out! It’s not that complicated to pick up and even a basic understanding of how memory allocation works goes a long way to making you a better programmer.
- wwright 7y agoimo it is not memory allocation that is the problem, but pointer ownership, which C neither helps you understand nor implement
- Gibbon1 7y agoPointers to long lived objects on the heap aren't a big deal in C. Pointer arithmetic and pointers to ephemeral objects is what sucks.
- deleted 7y ago[deleted]
- tom_ 7y agoWhat about Windows? You can get a 3-for-1 with this kind of library by having a libuv implementation.
- zamadatix 7y agoThe point is "add header, done". If you're going to be using libraries then there are better options to choose from already.
- ludamad 7y agoAny sort of static analysis to argue this doesn't have undefined behaviour bugs? It's cool, I just don't know a lot of cases where I would want/need an HTTP server and wouldn't want something more weathered
- jeremycw 7y agoNo, but by virtue of being a single header library it will run through whatever static analysis you have set up on your project. If an http server like NGINX solves your problem then, please, use that, because this is not an http server. It's a library for creating http servers. I would also love if someone wanted to contribute fuzz testing or other static analysis to the project. PRs are welcome.
- bullen 7y agoAt first glance this doesn't seem to handle large amounts of body data? Also I find no handling of slow connections. This is definitely a toy.
- cryptonector 7y ago^Fchunked No chunked support. Well, if ever I use this (and... I do have a pressing use for something like this), that will be a PR I'll send in, probably using async.h[0] to allow handlers to be asynchronous. Also, it's no fair to compare this server's performance to nginx if this server has no TLS support: you'll have to setup a reverse proxy, and then what will that be? The lack of URI parsing is not a big deal for me, but it'd be nice. [0] https://github.com/naasking/async.h https://github.com/naasking/async.h
- jeremycw 7y agoYes, there are some pieces missing that are on my radar like chunked support, uri/query parsing and sendfile.
- numlock86 7y ago> [...] some pieces missing that are on my radar like chunked support, uri/query parsing and sendfile I like the idea. Keep it up. The "some things" that are missing are really the basics of any HTTP server. Now it's more like something you could build a minimal REST API on. (With the need of a "real" server as proxy)
- jeremycw 7y agoThe goal is definitely not to replace NGINX or Apache or the like. I don't see handling TLS ever being a goal of this project, same with HTTP2 support. Although allowing the user to plug something in to handle HTTPS may not be out of the question.
- numlock86 7y agoThen I'd actually consider renaming your project to better transport your target scope. What you have in mind more sounds like a minimal library for writing non blocking REST APIs or HTTP based handlers, and not (full featured, as usually expected) HTTP servers. I really like it, though.
- 7y ago
- tus88 7y agoSecurely?
- amq 7y agoSurprised to see no CI.
- CommieDetector 7y agostruct http_response_s* response = http_response_init(); Is just C++ with extra steps
- castratikron 7y agoI had good luck with microhttpd. I wrote a little json web service as part of an existing C application for an embedded platform. Was very DIY but this is C after all.
- mark_l_watson 7y agoI now use mostly Lisp languages (or Haskell), but back in the day I wrote C++ books, acted as a C++ trainer and tech lead. My last professional use of C++ was in the 1990s doing entertainment game, VR, and game AI for SAIC, Nintendo, and Disney. I then went back to using plain C for awhile, and after the complexity of C++, C was so much fun to use. Anyway, I enjoyed reading through this C header file, and it took me back. But, I am sticking with Lisp because for me it is such a higher productivity language.
- thr0w__4w4y 7y agoGreat job. For me, checks all the boxes: . C (could have been C++... embedded MCU platform) . compiles cleanly out of the box . demo is simple, works out of the box, simple to verify I contrast this with my experience a few days ago with the "Space Invaders in C" post (too lazy to reference it or find the exact title). I do development on my Mac all the time (command-line, C++, clang/gcc). Tried building Space Invaders. One problem after the next. Gave up after about 20-25 minutes. Cliché as it is, the importance of the "out of box" experience is so important. Especially for a commercial product, which I realize this isn't.