After some experimentation, I found that the sendfile(2) support did not
really save any time compared to just write(2) from an already
memory-mapped file.
After some reading, I think open/sendfile is supposed to be slightly
more efficient than open/mmap/write — but if we already did the mmap
step, then it doesn't save us much.
Moreover, the code to support sendfile(2) is a bit icky, and also forces
us to close the HTTP connection after serving a file.
We now support single part ranges, as per:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests#Single_part_ranges
Multi-part ranges are not implemented because there have been far too
many bugs in this area.
It interacts with compression by selecting a byte range from the
compressed stream. Since the compressed stream is fixed, the results are
consistent.
Having done a bit more research on exactly how to use sendfile()
effectively with Go's own event loop, we can now leave the HTTP socket
in non-blocking mode and correctly integrate with the event loop to wait
for the socket to be writeable once more.