Awesome! I used to think (well, I still do) that getting a barebones service up and running using the system APIs at the lowest level like this is so satisfying. It's sort of magical, really. And to see it serve real traffic! I'm kind of surprised that the vanilla poll() can put up numbers like you were seeing, but I guess it's been a while since I've had to do anything event related/benchmark at that level.
I love the connection-specific functions and related structs and arrays for your connection bookkeeping, as well as the poll fd arrays. It's very reminiscent of how it's done in lots of other open source packages known for high throughput numbers, like nginx, redis, memcached.
Appreciated indeed. I happened to want to mess around with the C11 concurrency API and write a server of sorts, mostly as a curiosity of how those constructs work out in C coming from C++.
Don’t get me wrong this is an awesome project but if you really care about this kind of thing in a production scenario and you’re serving mostly static content… just use a CDN. It’ll pretty much always outperform just about anything you write. It’s just boring.
This sort of trivializes the effort and the fun of a project like this, doesn't it? Yes, you'll want to put all of your ducks in a row when you go to full production and you've reached full virality and your project is taking 5 million RPS globally and offloading all of that onto a CDN and making sure your clients requests are well respected in terms of cache control and making it secure and putting requests through a waf and and and and and. Yes we know. Lighten up. The comment you're replying to was meant to be lighthearted.
If you're hosting static data, shouldn't HTTP cache flags be enough in most cases? Read-only cacheable data shouldn't be toppling even a modest server. Even without an explicit CDN, various nodes along the chain will be caching it.
(though I confess it's been some years since I've worked in this area)
Uhh… doesn’t the link go to GitHub? I’m a little confused by this comment. I mean the project is neat and cool. But I imagine most folks go to GitHub and don’t go to the link showing the webpage. Am I missing something?
> As of 2024, the althttpd instance for sqlite.org answers more than 500,000 HTTP requests per day (about 5 or 6 per second) delivering about 200GB of content per day (about 18 megabits/second) on a $40/month Linode. The load average on this machine normally stays around 0.5. About 19% of the HTTP requests are CGI to various Fossil source-code repositories.
As with much of HN, this is fun, a good thing to learn while making and reading about... but it likely needs the caveat that doing this is production isn't a good idea (although in this case the author does not appear to encourage production usage).
I'd assume most people would know that? But if they still put random code that someone wrote just for fun into a (serious) production system, then WAT.
Edit: And sure, if the author is lucky, then maybe a handful of people will gather around the code and try to make it "production ready". But since the README doesn't say anything about the topic at all, just let people have fun and learn things along the way?
Http/1.1 is dead simple if you ignore most of the spec. If you only take get requests and set content-length on response you will be good for 99% of user agents. It’s not much more code to handle the transfer-encoding and byte-range headers. HTTPS is just http over a tls socket which is the level of abstraction you should have if you don’t roll your own crypto.
Yeah I’ve done this for embedded devices. A website can be presented with nothing more than a raw socket and sending back a text string of http headers and html in a single text string when people connect to it.
Hell if you’re really lazy you can forgo responding with the http headers and just socket.write(“hello world”) as the response and all the major browsers will render “hello world” to the user. Properly formatted http headers are just a text string extra and the html is just text. There’s not much to it.
It feels about right to me. OpenBSD's httpd(8) [1] currently clocks in at just below 15,000 lines when you include its documentation. Take away a few features, make a few assumptions , and I would not be surprised we are in the 5,000 lines territory like this project.
Nice. I've done this in the past. But I feel like attempting to make a file serving http server is like adding preservants and high fructose corn syrup to home made baked goods.
You have the opportunity to really make something custom and of high quality, hard code the paths of your files and avoid a whole class of vulnerabilities for example.
Configuration files? That makes sense when programmer and sysadmin are distinct, you can just modify variables and recompile.
Once at a certain level of complexity, e.g. having several hundred/thousand resources, then you start automating your hardcoded paths, and then you still can get bitten.
vs just putting things in a subfolder of your repo or whatever and having the default handling not accept `..` path components
I love the connection-specific functions and related structs and arrays for your connection bookkeeping, as well as the poll fd arrays. It's very reminiscent of how it's done in lots of other open source packages known for high throughput numbers, like nginx, redis, memcached.
Great work!
reply