LibHTTP: first impression
2026-04-20
Pet stumbled across www.libhttp.org when tried to write a simple HTTP server in C.
Basically, the first impression was very positive, despite the documentation was outdated.
Anyway, pet implemented what it needed in no time.
But then pet looked into the code. The very first thing it looked at was a function that gets cookie from the request header, and the first thought was: "meow, WTF?"
At the moment pet was working on Charpter 5 of its "Programming in C for pets" and dissected that function as an example how not to write the code.
But LibHTTP was pretty good in general so pet thought "Why not to make it look better?"
That was a fatal thought, but pet got to the work: it forked LibHTTP as nghttp1.
Fucking ambitious for pet, but nghttp1_ prefix looked perfect.
Of course it would be great to make API in line with nghttp2, but that would require a lot of work
and pet has very limited resources and time for that.
Pet even dropped the repo, but in a few hours it thought:
"why not? The library does need some touches".
And pet forked it again.
The most annoying thing was new type names. Pet did not like them, as well as a few other things like always compiled-in websockets.
So pet did the following:
Dropped struct from types
Other option considered: drop _t suffix.
- Some humans
think that
_tin user-defined types is a bad practice. - Along with
_t,structis used which is already telling that's a type, so_tis redundand.
Almost reverted to original names
New names were pretty cryptic and confusing for pet.
Decision helper table:
┌──────────────────────────────────┬──────────────────────────────────┬───────────────────────────────┬─────────────────────────┬────────────────────────────┐
│ Original names │ Current names │ Pet's names with struct │ Pet's names with _t │ Pet's choice │
├──────────────────────────────────┼──────────────────────────────────┼───────────────────────────────┼─────────────────────────┼────────────────────────────┤
│ struct httplib_context │ struct lh_ctx_t │ struct http_context │ http_context_t │ nghttp1_context │
│ struct httplib_connection │ struct lh_con_t │ struct http_conn │ http_conn_t │ nghttp1_connection │
│ struct httplib_request_info; │ struct lh_rqi_t │ struct http_request │ http_request_t │ nghttp1_request │
│ struct httplib_client_options │ struct httplib_client_options │ struct http_client │ http_client_t │ nghttp1_client │
│ struct httplib_callbacks │ struct lh_clb_t │ struct http_callbacks │ http_callbacks_t │ nghttp1_callbacks │
│ struct httplib_option │ struct lh_opt_t │ struct http_options │ http_options_t │ nghttp1_options │
│ struct httplib_server_ports │ struct lh_slp_t │ struct http_server_port │ http_server_port_t │ nghttp1_server_port │
│ struct httplib_form_data_handler │ struct httplib_form_data_handler │ struct http_form_data_handler │ http_form_data_handler_t│ nghttp1_form_data_handler │
│ struct client_cert │ struct client_cert │ struct http_client_cert │ http_client_cert_t │ nghttp1_client_cert │
│ │ struct lh_ip_t │ struct http_ip_addr │ http_ip_addr_t │ nghttp1_ip_addr │
└──────────────────────────────────┴──────────────────────────────────┴───────────────────────────────┴─────────────────────────┴────────────────────────────┘But then... Then pet started revising the codebase, making documentation up to date. That helped to get familiar with the code, but the library is a huge pile of files.
Pet wasted two days and gave up.
Stupid pet should not have even started.