MINOR: stconn: Add two fields in sedesc to replace the HTX extra value

For now, the HTX extra value is used to specify the known part, in bytes, of
the HTTP payload we will receive. It may concerne the full payload if a
content-length is specified or the current chunk for a chunk-encoded
message. The main purpose of this value is to be used on the opposite side
to be able to announce chunks bigger than a buffer. It can also be used to
check the validity of the payload on the sending path, to properly detect
too big or too short payload.

However, setting this information in the HTX message itself is not really
appropriate because the information is lost when the HTX message is consumed
and the underlying buffer released. So the producer must take care to always
add it in all HTX messages. it is especially an issue when the payload is
altered by a filter.

So to fix this design issue, the information will be moved in the sedesc. It
is a persistent area to save the information. In addition, to avoid the
ambiguity between what the producer say and what the consumer see, the
information will be splitted in two fields. In this patch, the fields are
added:

 * kip : The known input payload length
 * kop : The known output payload lenght

The producer will be responsible to set <kip> value. The stream will be
responsible to decrement <kip> and increment <kop> accordingly. And the
consumer will be responsible to remove consumed bytes from <kop>.
This commit is contained in:
Christopher Faulet 2025-09-17 17:30:32 +02:00
parent 586511c278
commit c0b6db2830
3 changed files with 33 additions and 0 deletions

View File

@ -311,6 +311,27 @@ struct se_abort_info {
* NOTE: <lra> and <fsb> must only be used via the SC api to compute read/write
* expiration date.
*
* <kip> is the known input payload length. It is set by the stream endpoint
* that produce data and decremented once consumed by the app
* loyer. Depending on the enpoint, this value may be unset. It may be set
* only once if the payload lenght is fully known from the begining (a
* HTTP message with a content-length for instance), or incremented
* periodically when more data are expected (a chunk-encoded HTTP message
* for instance). On the app side, this value is decremented when data are
* scheduled to be forwarded to the other side and <kop> is incremented
* accordingly.
*
* <kop> is the known output payload length still expected from the app
* layer. It is set by the app layer, when data are forwarded to the
* stream endpoint and decremented when the endpoint the value was
* processed (for instance when a size of the next chunk is emitted).
*
* NOTE: <kip> and <kop> act like communicating vessels and are just used as an
* information from the producer side to allow optimisations on the
* consumer side. These value may be unset by the producer or just never
* used by the consumer. When set, these values reflect the data already
* present in the channel buffer, and those which will come soon.
*
*/
struct sedesc {
void *se; /* the stream endpoint, i.e. the mux stream or the appctx */
@ -323,6 +344,9 @@ struct sedesc {
unsigned int lra; /* the last read activity */
unsigned int fsb; /* the first send blocked */
struct xref xref; /* cross reference with the opposite SC */
unsigned long long kip; /* Known input payload length (see above) */
unsigned long long kop; /* Known outgoing payload length (see above) */
};
/* sc_app_ops describes the application layer's operations and notification

View File

@ -148,6 +148,12 @@ static inline struct sedesc *se_opposite(struct sedesc *se)
return seo;
}
static inline void se_fwd_kip(struct sedesc *se)
{
se->kop += se->kip;
se->kip = 0;
}
/* stream connector version */
static forceinline void sc_ep_zero(struct stconn *sc)
{

View File

@ -109,6 +109,9 @@ void sedesc_init(struct sedesc *sedesc)
sedesc->iobuf.buf = NULL;
sedesc->iobuf.offset = sedesc->iobuf.data = 0;
sedesc->iobuf.flags = IOBUF_FL_NONE;
sedesc->kip = 0;
sedesc->kop = 0;
}
/* Tries to alloc an endpoint and initialize it. Returns NULL on failure. */