The HTTP proxy read each request into a buffer of 64 KB of its own,
cleared it with memset, and read the answer's headers into it again;
the header lines were copied there one by one from clibuf or srvbuf.
Now the header block of a request is read whole into clibuf, and that
of an answer into srvbuf, and worked on where it is (hdrread()):
- the block is moved to one byte into the buffer, and its lines, as
they are kept, are moved down to its start, so the line being worked
on, and the 0 written after it, never reach the next one; headers
taken out are left behind;
- HDRRESERVE is left free after it, for the headers this proxy adds,
before whatever came after it, a body or another request, from
where the connection is read on;
- the buffer is grown only for a block bigger than it, up to the
limits there were (512 KB for a request, 64 KB for an answer);
- the headers are copied to a buffer of their own only when they need
more room than that, when a filter hands back one, when a body is to
be read whole into the same buffer for a data filter, and for an ftp
listing, which is written where the headers were.
Whether buf is the headers' own buffer is kept with it (bufown), not
found from where it points: the side's buffer may be a bigger one by
then let go of. filterswap() leaves alone a buffer in either side's
buffer, which may be one grown by malloc, not only their fixed arrays.
What took buf for a buffer of LINESIZE does no longer: the request is
logged from a copy of its line, and the rest of a request refused
before its headers were all read is drained through a small buffer of
its own, keeping track of where its lines begin.
Tests: a POST whose body comes in the same packet as its headers,
which are rewritten, with a header added and one taken out; 45 KB of
request headers; two requests pipelined in one packet; empty lines
before a request; an answer with a 30 KB header; a 600 KB header block
refused, the proxy answering after it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>