From 265f7f42f678db4157e7d6f7f987aba01e71cfeb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 24 Jun 2019 11:21:26 +0200 Subject: http2: call done_sending on end of upload To make sure a HTTP/2 stream registers the end of stream. Bug #4043 made me find this problem but this fix doesn't correct the reported issue. Closes #4068 --- lib/http.c | 4 +++- lib/http2.c | 6 +++++- lib/transfer.c | 8 ++++---- lib/transfer.h | 3 +++ 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/http.c b/lib/http.c index a80e80157..d01e1bfdb 100644 --- a/lib/http.c +++ b/lib/http.c @@ -3511,8 +3511,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, else { infof(data, "HTTP error before end of send, stop sending\n"); streamclose(conn, "Stop sending data before everything sent"); + result = Curl_done_sending(conn, k); + if(result) + return result; k->upload_done = TRUE; - k->keepon &= ~KEEP_SEND; /* don't send */ if(data->state.expect100header) k->exp100 = EXP100_FAILED; } diff --git a/lib/http2.c b/lib/http2.c index b016bac92..bbd42bf2f 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -1880,7 +1880,11 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, are going to send or sending request body in DATA frame */ stream->upload_mem = mem; stream->upload_len = len; - nghttp2_session_resume_data(h2, stream->stream_id); + rv = nghttp2_session_resume_data(h2, stream->stream_id); + if(nghttp2_is_fatal(rv)) { + *err = CURLE_SEND_ERROR; + return -1; + } rv = h2_session_send(conn->data, h2); if(nghttp2_is_fatal(rv)) { *err = CURLE_SEND_ERROR; diff --git a/lib/transfer.c b/lib/transfer.c index 514330e8c..b25359196 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -937,8 +937,8 @@ static CURLcode readwrite_data(struct Curl_easy *data, return CURLE_OK; } -static CURLcode done_sending(struct connectdata *conn, - struct SingleRequest *k) +CURLcode Curl_done_sending(struct connectdata *conn, + struct SingleRequest *k) { k->keepon &= ~KEEP_SEND; /* we're done writing */ @@ -1046,7 +1046,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data, break; } if(nread <= 0) { - result = done_sending(conn, k); + result = Curl_done_sending(conn, k); if(result) return result; break; @@ -1164,7 +1164,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data, k->upload_present = 0; /* no more bytes left */ if(k->upload_done) { - result = done_sending(conn, k); + result = Curl_done_sending(conn, k); if(result) return result; } diff --git a/lib/transfer.h b/lib/transfer.h index a9bff6348..ab7110a80 100644 --- a/lib/transfer.h +++ b/lib/transfer.h @@ -57,6 +57,9 @@ CURLcode Curl_retry_request(struct connectdata *conn, char **url); bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc); CURLcode Curl_get_upload_buffer(struct Curl_easy *data); +CURLcode Curl_done_sending(struct connectdata *conn, + struct SingleRequest *k); + /* This sets up a forthcoming transfer */ void Curl_setup_transfer (struct Curl_easy *data, -- cgit v1.2.1