emikulic / darkhttpd

When you need a web server in a hurry.
https://unix4lyfe.org/darkhttpd/
ISC License
1.03k stars 83 forks source link

darkhttp possibly logs incorrect size for requests. #32

Open TurtleWilly opened 1 year ago

TurtleWilly commented 1 year ago

When darkhttp logs a request inside the logged entry the size of the object (the entry after the status code) is inflated. It seems darkhttp logs the object size including the headers, which seems to be non-standard. In fact it confused me when I wondered why it send the file with the wrong size (possibly something went wrong with the trasnfer?). So I investigated…

How to replicate:

$ mkdir test
$ echo "foobar789" >test/test.txt  # that's an 10 byte file
$ cd test
$ sudo /usr/local/sbin/darkhttpd . -port 48480  --chroot --uid _www --gid _www

Then, e.g. via curl:
# check file size (10 bytes, OK)
$ curl http://0.0.0.0:48480/test.txt 2>/dev/null | wc -c
      10
# record headers size:
$ curl -I http://0.0.0.0:48480/test.txt 2>/dev/null | wc -c
     227

Now back to darkhttp, see what it has logged:

127.0.0.1 - - [19/Aug/2023:14:34:27 +0200] "GET /test.txt HTTP/1.1" 200 237 "" "curl/8.2.1"
127.0.0.1 - - [19/Aug/2023:14:34:58 +0200] "HEAD /test.txt HTTP/1.1" 200 227 "" "curl/8.2.1"

For the first request it has logged 237 bytes (that's 10 bytes + 227 headers). What I expected to see here was an object size of "10" (for the file itself). For the second request (HEAD) I would expect to see "-" as result (no body). Compare with what Apache's httpd is doing there:

::1 - - [19/Aug/2023:14:28:17 +0200] "GET /test.txt HTTP/1.1" 200 10 "-" "curl/8.2.1"
::1 - - [19/Aug/2023:14:37:19 +0200] "HEAD /test.txt HTTP/1.1" 200 - "-" "curl/8.2.1"

According to Apache's log format documentation the Common Log Format (CLF)'s last entry "indicates the size of the object returned to the client, not including the response headers. If no content was returned to the client, this value will be '-'." (see: https://httpd.apache.org/docs/2.4/logs.html). Also nginx seems to prefer the actual file size (body) and not include headers (see: https://docs.nginx.com/nginx/admin-guide/monitoring/logging/ -> $body_bytes_sent)

I'm not saying darkhttp does it wrong (I can see the benefit of logging the whole amount of data sent in a request), but surprising to me it certainly does things a bit different here than the more well-known web servers.