While mostly I agree with your comment, I suspect both darkhttpd and httpdito (linked above) are actually equipped to survive as a public service. httpdito is about 700 lines of code (in assembly); it handles these issues as follows:

1. Accepting connections starving established connections: this is mostly a problem for event-driven servers. httpdito runs each connection in its own child process, has a compiled-in limit of 2048 concurrent connections. Whenever it has 2048 live children, it blocks in waitpid() until at least one of them dies. Modern Linux does a fair enough job of scheduling that this seems to be sufficient in practice to keep the parent from hogging the whole machine and preventing the children from making progress, even if most of your incoming connections just close without sending an HTTP request or any bytes at all. Darkhttpd might have a problem with this or not, I haven't tried, but it seems to rely on OS ulimits to limit its number of concurrent connections. My guess is that with the default ulimit -n 1024 darkhttpd won't have any problem with this at all.

2. Whether events are distributed optimally among threads or CPUs: the real issue here is not optimality but stability, and again, this is mostly an issue for event-driven servers (or servers made of thread pools, etc.) The essential property for production is usually not that you're using the machine to within 0.1% or 10% of its capacity, but that you're not wasting 99+% of its capacity uselessly thrashing—or, at the other extreme, responding so fairly that you provide some service to every client, but not enough to actually ever complete a whole request successfully. Modern Linux does a good enough job of this that httpdito's very stupid approach of forking a new child for each request works reasonably well. darkhttpd avoids the problem in a different way by not having threads and not using multiple CPUs, which is clearly not optimal but also totally avoids any related stability concerns.

3. How the server behaves if a client sends one byte per frame, very slowly: in overload conditions, which is when this matters "to survive as a public service", Linux's TCP stack does a reasonably efficient job of consolidating the bytes until a particular server child gets a chance to run. httpdito does a super stupid O(N²) thing in these cases where it looks for the CRLFCRLF at every position in the buffer after every received chunk (potentially a single frame), but this is ameliorated not only by Linux's TCP stack but also by the fact that the request buffer size is only 1024 bytes, so in the worst case we spend 4084 instructions on an incoming packet the last time we run this loop for a given client, and only half that (2042 instructions) on average. This is still fast enough to handle somewhere in excess of 4 million packets per core and probably faster than Linux's TCP stack.

The flip side of that is that by sending data slowly in this way, or by not sending any data at all, a client can monopolize all 2048 concurrent connections, preventing other clients from connecting. This is a problem that cannot be solved in TCP/IP, only ameliorated. httpdito ameliorates it with a 32-second timeout, counted from when it accepts, so in the steady state it always accepts an average of at least 64 new connections per second, regardless of how fast or slowly the requests come in.

I haven't tested darkhttpd under these conditions but it has a 30-second idle timeout and a 4000-byte max request length. It kind of looks like it does the same O(N²) thing, but I've only glanced at the code. I don't know how long it allows for the client to slowloris the initial requests in one byte at a time.

4. How the server behaves if the client receives the response very slowly: I think the above covers this. However, extremely large files or extremely slow connections will whack into the 32-second timeout. At 9600 baud, for example, responses of more than about 30 kilobytes will get truncated. There's an unavoidable tradeoff between handling slow connections successfully (which requires many memory buffers), handling fast connections efficiently (which requires large memory buffers), and withstanding DoS attacks (which requires, among other things, limiting memory use).

5. Whether the process will run out of memory if a number of events happen suddenly: httpdito does all of its within-process memory allocation at compile time, so this isn't a thing that can happen within a process. Its limit of 2048 children works out to about 16 mebibytes of RAM typically, so it's not a problem systemwide either, unless you're running it on a Rio Receiver or something. darkhttpd does allocate memory, but at first glance it seems to be limited to a couple of allocations of less than 4000 bytes per concurrent connection, so I don't see a problem here either.

It's common for event-loop servers to handle overload events like these much more gracefully than multitasking servers; httpdito is kind of an outlier here because it uses about a thousandth the RAM of a normal multitasking server, and running on an OS whose task scheduling is less shitty than is typical, which allows it to get away with a lot. (The original slowloris README describes it as a DoS tool for threaded web servers.) By contrast, the usual overload problem event-loop systems have trouble with is where some event handler that usually takes a millisecond or a microsecond suddenly starts taking a second or a kilosecond, locking out everything else until it's done. Maybe you have an O(N³) algorithm in your HTTP content negotiation, but you never noticed because normal browsers send an Accept: header with five content types and so N³ means 125 iterations, and then some guy in Turkey with a screwed up browser configuration sends you an Accept: header with 1296 content-types and your whole server freezes for several seconds. Every three minutes.

You could hypothetically make an event-loop system immune to this kind of thing by doing a rigorous WCET analysis on every single event handler, as if it were jet engine control firmware. But that's a huge pain in the ass for any program of more than about 1000 machine instructions, so I've never heard of anybody doing this with an event-loop-driven network server. I've been toying with ideas for solving this problem over the years, including approaches like BPF and software transactional memory. Some of my notes on this are at https://dercuano.github.io/topics/transactions.html, while others are in Derctuo and Dernocua.

That said, I haven't tested darkhttpd at all, and I'm not running any public services on httpdito. It wouldn't surprise me if either or both had some kind of stability bug under overload conditions. But it would surprise me very much if fixing those bugs required adding thousands of lines of code.