mirror of
https://github.com/curl/curl.git
synced 2026-05-30 10:17:28 +03:00
quiche: return CURLE_HTTP3 on send to invalid stream
Prior to this change if a send failed on a stream in an invalid state (according to quiche) and not marked as closed (according to libcurl) then the send function would return CURLE_SEND_ERROR. We already have similar code for ngtcp2 to return CURLE_HTTP3 in this case. Caught by test test_07_upload.py: test_07_22_upload_parallel_fail. Fixes https://github.com/curl/curl/issues/12590 Closes https://github.com/curl/curl/pull/12597
This commit is contained in:
parent
373d34494c
commit
b83729a339
2 changed files with 29 additions and 14 deletions
|
|
@ -1894,6 +1894,8 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|||
sent = (ssize_t)len;
|
||||
goto out;
|
||||
}
|
||||
CURL_TRC_CF(data, cf, "[%" PRId64 "] send_body(len=%zu) "
|
||||
"-> stream closed", stream->id, len);
|
||||
*err = CURLE_HTTP3;
|
||||
sent = -1;
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -1078,6 +1078,28 @@ static ssize_t cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|||
goto out;
|
||||
stream = H3_STREAM_CTX(data);
|
||||
}
|
||||
else if(stream->closed) {
|
||||
if(stream->resp_hds_complete) {
|
||||
/* sending request body on a stream that has been closed by the
|
||||
* server. If the server has send us a final response, we should
|
||||
* silently discard the send data.
|
||||
* This happens for example on redirects where the server, instead
|
||||
* of reading the full request body just closed the stream after
|
||||
* sending the 30x response.
|
||||
* This is sort of a race: had the transfer loop called recv first,
|
||||
* it would see the response and stop/discard sending on its own- */
|
||||
CURL_TRC_CF(data, cf, "[%" PRId64 "] discarding data"
|
||||
"on closed stream with response", stream->id);
|
||||
*err = CURLE_OK;
|
||||
nwritten = (ssize_t)len;
|
||||
goto out;
|
||||
}
|
||||
CURL_TRC_CF(data, cf, "[%" PRId64 "] send_body(len=%zu) "
|
||||
"-> stream closed", stream->id, len);
|
||||
*err = CURLE_HTTP3;
|
||||
nwritten = -1;
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
bool eof = (stream->upload_left >= 0 &&
|
||||
(curl_off_t)len >= stream->upload_left);
|
||||
|
|
@ -1095,20 +1117,11 @@ static ssize_t cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|||
nwritten = -1;
|
||||
goto out;
|
||||
}
|
||||
else if(nwritten == QUICHE_H3_TRANSPORT_ERR_INVALID_STREAM_STATE &&
|
||||
stream->closed && stream->resp_hds_complete) {
|
||||
/* sending request body on a stream that has been closed by the
|
||||
* server. If the server has send us a final response, we should
|
||||
* silently discard the send data.
|
||||
* This happens for example on redirects where the server, instead
|
||||
* of reading the full request body just closed the stream after
|
||||
* sending the 30x response.
|
||||
* This is sort of a race: had the transfer loop called recv first,
|
||||
* it would see the response and stop/discard sending on its own- */
|
||||
CURL_TRC_CF(data, cf, "[%" PRId64 "] discarding data"
|
||||
"on closed stream with response", stream->id);
|
||||
*err = CURLE_OK;
|
||||
nwritten = (ssize_t)len;
|
||||
else if(nwritten == QUICHE_H3_TRANSPORT_ERR_INVALID_STREAM_STATE) {
|
||||
CURL_TRC_CF(data, cf, "[%" PRId64 "] send_body(len=%zu) "
|
||||
"-> invalid stream state", stream->id, len);
|
||||
*err = CURLE_HTTP3;
|
||||
nwritten = -1;
|
||||
goto out;
|
||||
}
|
||||
else if(nwritten == QUICHE_H3_TRANSPORT_ERR_FINAL_SIZE) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue