You could previously do this with evbuffer_peek() and some memcpys,
but it was a bit more work than most folks wanted to get into.
Closes sourceforge ticket 3108072
Instead of having a file segment born as one type and stay that way
forever, let them start out unmapped, but map themselves as needed
if they need to get written out on a non-drains_to_fd evbuffer.
The sendfile() implementation for evbuffer_add_file is potentially more
efficient, but it has a problem: you can only use it to send bytes over
a socket using sendfile(). If you are writing bytes via SSL_send() or
via a filter, or if you need to be able to inspect your buffer, it
doesn't work.
As an easy fix, this patch disables the sendfile-based implementation of
evbuffer_add_file on an evbuffer unless the user sets a new
EVBUFFER_FLAG_DRAINS_TO_FD flag on that evbuffer, indicating that the
evbuffer will not be inspected, but only written out via
evbuffer_write(), evbuffer_write_atmost(), or drained with stuff like
evbuffer_drain() or evbuffer_add_buffer(). This flag is off by
default, except for evbuffers used for output on bufferevent_socket.
In the future, it could be interesting to make a best-effort file
segment implementation that tries to send via sendfile, but mmaps on
demand. That's too much complexity for a stable release series, though.
Original message:
Solaris sendfile seems to fail when sending moderately large (<1GB)
files. Not a 32/64 problem, but a buffer problem.
Anyone else ever try this? It is definitely broken in http-server.c.
It seems to be broken in the following way:
When sendfile sends partial data (EAGAIN, would block), "res" is
always -1, rather than the amount sent.
Here's a patch that reads from the "offset" pointer instead to
discover what was sent. This seems to work:
The _internal.pos_in_chain field was uninitialized or set to different
values in different places returning the special "not found" pointer.
Signed-off-by: Nir Soffer <nirsof@gmail.com>
When searching for a CRLF, it would find an LF, then look for a
preceding CR if not at the start of the buffer. That's fine when
we're starting from the beginning of the buffer, but if we're starting
at (say) byte 100, and we have that byte == LF, we shouldn't check for
a CR at byte 99.
Our evbuffer_strchr() function [which was only used for
search_eol(EOL_LF) could give incorrect results if it found its answer
in the first chunk but didn't start searching from the front of the
chunk.
Also, this patch adds unit tests for evbuffer_search_eol, particularly
in those cases that evbuffer_readln() tests didn't exercise.
Instead of mapping enough bytes for each segment, we were failing to
take into account the slop created by rounding the segment position
down to the nearest page.
Should fix bug 3142394 found by Sebastian Hahn.