
Httpserver.h: Single header library for writing non-blocking HTTP servers in C - jeremycw
https://github.com/jeremycw/httpserver.h
======
_bxg1
Question: 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"?

~~~
ddevault
You're right. "Header only" libraries are an anti-pattern in C and the fastest
way for me to close the tab when considering a new library. Just put it in two
files and it's still dead easy to incorporate into a project.

~~~
jeremycw
I don't really understand what your criticisms are. There is literally no
functional code difference between a single header library and a two file
library. Your aversion is as arbitrary as saying you don't consider libraries
if the API uses camel case.

~~~
Athas
Can you compile a header to an object file so that its definitions don't have
to be recompiled every time the including file is recompiled?

~~~
shakna
Eh... Yes?

GCC [0], Clang [1] and others [2] have supported for compiled headers. Cmake
also has support for precompiled headers [3].

I would say both the tool and architecture to do that is well supported.

[0] [https://gcc.gnu.org/onlinedocs/gcc/Precompiled-
Headers.html](https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html)

[1]
[https://clang.llvm.org/docs/PCHInternals.html](https://clang.llvm.org/docs/PCHInternals.html)

[2]
[https://www.qnx.com/developers/docs/6.3.2/neutrino/utilities...](https://www.qnx.com/developers/docs/6.3.2/neutrino/utilities/i/icc.html)
(-pch flag)

[3]
[https://cmake.org/cmake/help/latest/command/target_precompil...](https://cmake.org/cmake/help/latest/command/target_precompile_headers.html)

------
maxk42
h2o [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/)

~~~
ksec
Is H20 being used in production?

~~~
maxk42
I believe Fastly CDN sponsors some of the development [citation needed]. Not
sure if that means they use it in production or not, but I've been playing
with it on some of my dev servers and so far it's amazingly stable and
configurable.

------
ebeip90
1100+ 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
To 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.

------
cryptonector
^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
Yes, there are some pieces missing that are on my radar like chunked support,
uri/query parsing and sendfile.

~~~
numlock86
> [...] 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
The 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
Then 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.

------
giancarlostoro
I 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
Go compilers are anywhere near as universally available as C compilers...

~~~
giancarlostoro
Technically 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_and...](http://rafalgolarz.com/blog/2017/01/15/running_golang_on_android/)

~~~
jonny383
Wow awesome. I never knew. Thanks!

~~~
giancarlostoro
No 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
Oh 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...](http://www.allaboutsymbian.com/news/item/4192_Raccoon_Apache_web_server_for_.php)

------
castratikron
I 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.

------
jsd1982
It'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
Yeah I was thinking this too, it doesn't seem like it. It's still blocking on
http_server_listen.

------
ludamad
Any 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
No, 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.

------
anon9001
Neat, 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
I 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
A 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?

------
bullen
At 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.

------
jacob019
Might go well with embeded hardware

------
gigel82
You forgot to add "for Linux/BSD".

~~~
app4soft
"for *nix/BSD/Mac"

------
thr0w__4w4y
Great 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.

------
mark_l_watson
I 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.

------
z3t4
I 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
Try 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
imo it is not memory allocation that is the problem, but pointer ownership,
which C neither helps you understand nor implement

------
tom_
What about Windows?

You can get a 3-for-1 with this kind of library by having a libuv
implementation.

~~~
zamadatix
The point is "add header, done". If you're going to be using libraries then
there are better options to choose from already.

------
noobermin
brundolf 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
Not 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
I 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
d'oh!

------
tus88
Securely?

------
amq
Surprised to see no CI.

------
sedatk
This 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
This 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
I'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
Far 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
You still haven’t said a single word about package management.

~~~
mschuster91
oh I do have: the easier it is to publish code/packages, the more newbies and
morons will flood your environment, to the point of unusability (or at least
inability to do any sort of audit).

