Confused by what is happening with sendFile() and sendFileAll()

Hi everybody,

I am write a webserver directly on top of a TCP socket and using Arch BTW. And want to understand how to properly use .sendFile(). Got that idea from from [this]( Zig Vs C - Minimal HTTP server ) blogpost.

However, I found two issues while using it:

  1. .sendFile() (Somewhere in ./zig/0.15.2/lib/std/net.zig:2304) would write 0 bytes anything unless I would flush() before.
  2. While debugging through .sendFileAll(), which didn’t require a flush() before itself, I think I saw the contents of the file copied in a buffer somewhere, which is what I wanted to avoid by using .sendFileAll() and .sendFile() in the first place. I didn’t really understood what happened there. Maybe the buffer was old, now that I think of it.

Could someone elaborate on this two points? Thanks in advance.

define ‘would not work’.

the net.Stream.Writer (on not windows, which I assume is true) wraps a File.Writer, and calls sendFileHeader. Which allows it to pass an extra slice of data to be written before the sendFile, in this case the stream writer is passing its own buffered data (not to be confused with the file writer’s buffered data).

If the file writers buffer has enough unused space, it will copy the header slice into the file writers buffer, this allows it to immediately call sendFile as it is supposed to write the buffered data before doing its file sending magic.

If that is not possible, then sendFileHeader will fall back to doing a normal write of the header as well as the file readers buffer because it’s available, why not try.

If by ‘not work’ above, you meant it did a normal write instead of file sending magic, then you just encountered the case where the streams buffer is too big to be put into the file writers buffer. This explains why you had to flush as that will empty the buffer allowing the file sending magic.

sendFileAll didnt require you to flush because it just calls sendFile in a loop. It still falls back to a normal write, untill the all the buffered data is written, then it does the file sending magic.

3 Likes

.sendFile() reported that 0 bytes have been written. Also flushing after didn’t do anything.

Using Linux :slight_smile: (Updated both points in the orignal message)

I think this explains it. Thanks.

I am still getting accustomed to stepping through Zig’s standard library and miss the big picture quite often.

the buffered bytes don’t get counted, as they are already counted when they get put into the buffer.

The number returned only accounts for the actual send file operation, which will not happen under the circumstance I outlined earlier.