Commit Graph

80 Commits

Author SHA1 Message Date
Christopher Faulet
9c66b980fa MINOR: htx: Store start-line block's position instead of address of its payload
Nothing much to say. This change is just mandatory to consider 1xx informational
messages as part of a response.
2019-05-28 07:42:12 +02:00
Christopher Faulet
28f29c7eea MINOR: htx: Store the head position instead of the wrap one
The head of an HTX message is heavily used whereas the wrap position is only
used when a block is added or removed. So it is more logical to store the head
position in the HTX message instead of the wrap one. The wrap position can be
easily deduced. To get it, the new function htx_get_wrap() may be used.
2019-05-28 07:42:12 +02:00
Christopher Faulet
b8fd4c031c BUG/MINOR: htx: Remove a forgotten while loop in htx_defrag()
Fortunately, this loop does nothing. Otherwise it would have led to an infinite
loop. It was probably forgotten during a refactoring, in the early stage of the
HTX.

This patch must be backported to 1.9.
2019-05-24 09:11:10 +02:00
Christopher Faulet
6f3cb1801b MINOR: htx: Remove support for unused OOB HTX blocks
This type of block was introduced in the early design of the HTX and it is not
used anymore. So, just remove it.

This patch may be backported to 1.9.
2019-05-07 22:16:41 +02:00
Christopher Faulet
6177509eb7 MINOR: htx: Don't try to append a trailer block with the previous one
In H1 and H2, one and only one trailer block is emitted during the HTTP
parsing. So it is useless to try to append this block with the previous one,
like for data block.

This patch may be backported to 1.9.
2019-05-07 22:16:41 +02:00
Christopher Faulet
bc5770b91e MINOR: htx: Split on DATA blocks only when blocks are moved to an HTX message
When htx_xfer_blks() is called to move blocks from an HTX message to another
one, most of blocks must be transferred atomically. But some may be splitted if
there is not enough space to move all the block. This was true for DATA and TLR
blocks. But it is a bad idea to split trailers. During HTTP parsing, only one
TLR block is emitted. It simplifies the processing of trailers to keep the block
untouched.

This patch must be backported to 1.9 because some fixes may depend on it.
2019-05-07 22:16:41 +02:00
Christopher Faulet
cc5060217e BUG/MINOR: htx: Never transfer more than expected in htx_xfer_blks()
When the maximum free space available for data in the HTX message is compared to
the number of bytes to transfer, we must take into account the amount of data
already transferred. Otherwise we may move more data than expected.

This patch must be backported to 1.9.
2019-05-07 22:16:41 +02:00
Christopher Faulet
f1449b785e BUG/MEDIUM: htx: Don't crush blocks payload when append is done on a data block
If there is a data block when a header block is added in a HTX message, its
payload will be inserted after the data block payload. But its index will be
moved before the EOH block. So at this stage, if a new data block is added, we
will try to append its payload to the last data block (because it is also the
tail). Thus the payload of the further header block will be crushed.

This cannot happens if the payloads wrap thanks to the previous fix. But it
happens when the tail is not the front too. So now, in this case, we add a new
block instead of appending.

This patch must be backported in 1.9.
2019-04-12 22:06:45 +02:00
Christopher Faulet
05aab64b06 BUG/MEDIUM: htx: Defrag if blocks position is changed and the payloads wrap
When a header is added or when a data block is added before another one, the
blocks position may be changed (but not their payloads position). For instance,
when a header is added, we move the block just before the EOH, if any. When the
payloads wraps, it is pretty annoying because we loose the last inserted
block. It is neither the tail nor the head. And it is not the front either.

It is a design problem. Waiting for fixing this problem, we force a
defragmentation in such case. Anyway, it should be pretty rare, so it's not
really critical.

This patch must be backported to 1.9.
2019-04-12 21:34:30 +02:00
Willy Tarreau
90caa07935 BUG/MEDIUM: htx: fix random premature abort of data transfers
It can happen in some cases that the last block of an H2 transfer over
HTX is truncated. This was tracked down to a leftover of an earlier
implementation of htx_xfer_blks() causing the computed size of a block
to be incorrectly calculated if a data block doesn't completely fit into
the target buffer. In practice it causes the EOM block to be attempted to
be emitted with a wrong size and the message to be truncated. One way to
reproduce this is to chain two haproxy instances in h1->h2->h1 with
httpterm as the server and h2load as the client, making many requests
between 8 and 10kB over a single connection. Usually one of the very
first requests will fail.

This fix must be backported to 1.9.
2019-04-09 16:30:20 +02:00
Christopher Faulet
549822f0a1 MINOR: htx: Add function to drain data from an HTX message
The function htx_drain() can now be used to drain data from an HTX message.

It will be used by other commits to fix bugs, so it must be backported to 1.9.
2019-02-26 14:04:23 +01:00
Willy Tarreau
2bf0c13261 BUG/MEDIUM: htx: count the amount of copied data towards the final count
Currently htx_xfer_blks() respects the <count> limit for each block
instead of for the sum of the transfered blocks. This causes it to
return slightly more than requested when both headers and data are
present in the source buffer, which happens early in the transfer
when the reserve is still active. Thus with large enough headers,
the reserve will not be respected.

Note that this function is only called from h2_rcv_buf() thus this only
affects data entering over H2 (H2 requests or H2 responses).

This fix must be backported to 1.9.
2019-02-21 17:13:07 +01:00
Christopher Faulet
00cf697215 MINOR: htx: Add a function to truncate all blocks after a specific offset
This function will be used to truncate all incoming data in a channel, keeping
outgoing ones.

This may be backported to 1.9.
2019-01-08 12:06:55 +01:00
Willy Tarreau
52610e905d MINOR: htx: add a new function to add a block without filling it
htx_add_blk_type_size() creates a block of a specified type and size
and returns it. The caller can then fill it.
2019-01-03 18:45:38 +01:00
Christopher Faulet
200f895cca BUG/MAJOR: htx: Return the good block address after a defrag
When an HTX structure is defragmented, it is possible to retrieve the new block
corresponding to an old one. This is useful to do a defrag during a loop on
blocks, to be sure to continue looping on the good block. But, instead of
returning the address of the new block in the HTX structure, the one in the
temporary structure used to do the defrag was returned, leading to unexpected
behaviours.

This patch must be backported to 1.9.
2019-01-02 20:14:31 +01:00
Willy Tarreau
b96b77ed6e REORG: htx: merge types+proto into common/htx.h
All the HTX definition is self-contained and doesn't really depend on
anything external since it's a mostly protocol. In addition, some
external similar files (like h2) also placed in common used to rely
on it, making it a bit awkward.

This patch moves the two htx.h files into a single self-contained one.
The historical dependency on sample.h could be also removed since it
used to be there only for http_meth_t which is now in http.h.
2018-12-11 17:15:04 +01:00
Christopher Faulet
e97f3baa66 BUG/MEDIUM: htx: Always do a defrag if a block value is replace by a bigger one
Otherwise, after such replaces, the HTX message appears to wrap but the head
block address is not necessarily the first one. So adding new blocks will
override data of old ones.
2018-12-10 20:51:41 +01:00
Willy Tarreau
c706cd73a5 BUG/MEDIUM: htx: fix typo in htx_replace_stline() making it fail all the time
A typo in the block type check makes this function fail all the time,
which has impact on anything rewriting a start line (set-uri, set-path
etc).

No backport needed.
2018-12-07 17:12:22 +01:00
Willy Tarreau
ed00e345e2 MEDIUM: ist: always turn header names to lower case
HTTP/2 and above require header names to be lower cased, while HTTP/1
doesn't care. By making lower case the standard way to store header
names in HTX, we can significantly simplify all operations applying to
header names retrieved from HTX (including, but not limited to, lookups
and lower case checks which are not needed anymore).

As a side effect of replacing memcpy() with ist2bin_lc(), a small increase
of the request rate performance of about 0.5-1% was noticed on keep-alive
traffic, very likely due to memcpy() being overkill for tiny strings.

This trivial patch was marked medium because it may have a visible end-user
impact (e.g. non-HTTP compliant agent, etc).
2018-12-07 13:25:59 +01:00
Christopher Faulet
174bfb163c BUG/MEDIUM: htx: Set the right start-line offset after a defrag
The offset was always wrong after an HTX defragmentation because the wrong
address was used and because the update could occcur several time on the same
defragmentation.
2018-12-06 15:01:40 +01:00
Christopher Faulet
aa75b3d2d5 CLEANUP: htx: Fix indentation here and there in HTX files 2018-12-05 17:33:14 +01:00
Christopher Faulet
27ba2dc6d6 MEDIUM: htx: Rework conversion from a buffer to an htx structure
Now, the function htx_from_buf() will set the buffer's length to its size
automatically. In return, the caller should call htx_to_buf() at the end to be
sure to leave the buffer hosting the HTX message in the right state. When the
caller can use the function htxbuf() to get the HTX message without any update
on the underlying buffer.
2018-12-05 17:10:16 +01:00
Christopher Faulet
1e7af46aae BUG/MINOR: htx: Force HTTP/1.1 on H1 formatting when version is 1.1 or above
This only happens for connections using the h1 mux. We must be sure to force the
version to HTTP/1.1 when the version of the message is 1.1 or above. It is
important for H2 messages to not send an invalid version string (HTTP/2.0) to
peers.
2018-12-04 05:51:39 +01:00
Christopher Faulet
c59ff23804 MINOR: htx: Rename functions htx_*_to_str() to be H1 specific
"_to_h1" suffix is now used because these function produce H1 strings. It avoids
any ambiguity on the output format.
2018-12-04 05:51:37 +01:00
Christopher Faulet
f1ba18d7b3 MEDIUM: htx: Don't rely on h1_sl anymore except during H1 header parsing
Instead, we now use the htx_sl coming from the HTX message. It avoids to have
too H1 specific code in version-agnostic parts. Of course, the concept of the
start-line is higly influenced by the H1, but the structure htx_sl can be
adapted, if necessary. And many things depend on a start-line during HTTP
analyzis. Using the structure htx_sl also avoid boring conversions between HTX
version and H1 version.
2018-12-01 17:37:27 +01:00
Christopher Faulet
54483df5ba MINOR: htx: Add the start-line offset for the HTX message in the HTX structure
If there is no start-line, this offset is set to -1. Otherwise, it is the
relative address where the start-line is stored in the data block. When the
start-line is added, replaced or removed, this offset is updated accordingly. On
remove, if the start-line is no set and if the next block is a start-line, the
offset is updated. Finally, when an HTX structure is defragmented, the offset is
also updated accordingly.
2018-12-01 17:37:27 +01:00
Christopher Faulet
570d1614fa MEDIUM: htx: Change htx_sl to be a struct instead of an union
The HTX start-line is now a struct. It will be easier to extend, if needed. Same
info can be found, of course. In addition it is now possible to set flags on
it. It will be used to set some infos about the message.

Some macros and functions have been added in proto/htx.h to help accessing
different parts of the start-line.
2018-12-01 17:37:27 +01:00
Christopher Faulet
24ed835129 MINOR: htx: Add function to add an HTX block just before another one
The function htx_add_data_before() can be used to add an HTX block before
another one. For instance, it could be used to add some data before the
end-of-message marker.
2018-12-01 17:37:27 +01:00
Christopher Faulet
53ad16a0ef BUG/MINOR: htx: Fix block size calculation when a start-line is added/replaced
What we store in the buffer is a union htx_sl, not an h1_sl, so the
computed size was not correct.
2018-12-01 17:20:36 +01:00
Christopher Faulet
a3d2a16fad MEDIUM: htx: Add API to deal with the internal representation of HTTP messages
The internal representation of an HTTP message, called HTX, is a structured
representation, unlike the old one which is a raw representation of
messages. Idea is to have a version-agnostic representation of the HTTP
messages, which can be easily used by to handle HTTP/1, HTTP/2 and hopefully
QUIC messages, and communication from one of them to another.

In this patch, we add types to define the internal representation itself and the
main functions to manipulate them.
2018-11-18 22:08:53 +01:00