mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-01 17:52:03 +00:00
BUG/MINOR: mux-h2: send a CANCEL instead of ES on truncated writes
If a POST upload is cancelled after having advertised a content-length, or a response body is truncated after a content-length, we're not allowed to send ES because in this case the total body length must exactly match the advertised value. Till now that's what we were doing, and that was causing the other side (possibly haproxy) to respond with an RST_STREAM PROTOCOL_ERROR due to "ES on DATA frame before content-length". We can behave a bit cleaner here. Let's detect that we haven't sent everything, and send an RST_STREAM(CANCEL) instead, which is designed exactly for this purpose. This patch could be backported to older versions but only a little bit of exposure to make sure it doesn't wake up a bad behavior somewhere. It relies on the following previous commit: "MINOR: mux-h2: make streams know if they need to send more data"
This commit is contained in:
parent
4877045f1d
commit
473e0e54f5
15
src/mux_h2.c
15
src/mux_h2.c
@ -4604,9 +4604,11 @@ static void h2_do_shutw(struct h2s *h2s)
|
||||
|
||||
TRACE_ENTER(H2_EV_STRM_SHUT, h2c->conn, h2s);
|
||||
|
||||
if (h2s->st != H2_SS_ERROR && (h2s->flags & H2_SF_HEADERS_SENT)) {
|
||||
/* we can cleanly close using an empty data frame only after headers */
|
||||
|
||||
if (h2s->st != H2_SS_ERROR &&
|
||||
(h2s->flags & (H2_SF_HEADERS_SENT | H2_SF_MORE_HTX_DATA)) == H2_SF_HEADERS_SENT) {
|
||||
/* we can cleanly close using an empty data frame only after headers
|
||||
* and if no more data is expected to be sent.
|
||||
*/
|
||||
if (!(h2s->flags & (H2_SF_ES_SENT|H2_SF_RST_SENT)) &&
|
||||
h2_send_empty_data_es(h2s) <= 0)
|
||||
goto add_to_list;
|
||||
@ -4627,6 +4629,13 @@ static void h2_do_shutw(struct h2s *h2s)
|
||||
h2c_error(h2c, H2_ERR_ENHANCE_YOUR_CALM);
|
||||
h2s_error(h2s, H2_ERR_ENHANCE_YOUR_CALM);
|
||||
}
|
||||
else if (h2s->flags & H2_SF_MORE_HTX_DATA) {
|
||||
/* some unsent data were pending (e.g. abort during an upload),
|
||||
* let's send a CANCEL.
|
||||
*/
|
||||
TRACE_STATE("shutw before end of data, sending CANCEL", H2_EV_STRM_SHUT, h2c->conn, h2s);
|
||||
h2s_error(h2s, H2_ERR_CANCEL);
|
||||
}
|
||||
else {
|
||||
/* Nothing was never sent for this stream, so reset with
|
||||
* REFUSED_STREAM error to let the client retry the
|
||||
|
Loading…
Reference in New Issue
Block a user