From 3d4c0c8b9bc1d53df2e38961343f755a84579f83 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 5 Sep 2016 11:07:40 +0200 Subject: [PATCH] http2: return EOF when done uploading without known size Fixes #982 --- lib/http2.c | 37 +++++++++++++++++++++++++++++++++++-- lib/http2.h | 2 ++ lib/transfer.c | 3 +++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/lib/http2.c b/lib/http2.c index 17915d45a..a66b8f74c 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -1149,7 +1149,8 @@ static int h2_session_send(struct Curl_easy *data, */ static int h2_process_pending_input(struct Curl_easy *data, struct http_conn *httpc, - CURLcode *err) { + CURLcode *err) +{ ssize_t nread; char *inbuf; ssize_t rv; @@ -1197,9 +1198,41 @@ static int h2_process_pending_input(struct Curl_easy *data, return 0; } +/* + * Called from transfer.c:done_sending when we stop uploading. + */ +CURLcode Curl_http2_done_sending(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + + if((conn->handler == &Curl_handler_http2_ssl) || + (conn->handler == &Curl_handler_http2)) { + /* make sure this is only attempted for HTTP/2 transfers */ + + struct HTTP *stream = conn->data->req.protop; + + if(stream->upload_left) { + /* If the stream still thinks there's data left to upload. */ + struct http_conn *httpc = &conn->proto.httpc; + nghttp2_session *h2 = httpc->h2; + + stream->upload_left = 0; /* DONE! */ + + /* resume sending here to trigger the callback to get called again so + that it can signal EOF to nghttp2 */ + (void)nghttp2_session_resume_data(h2, stream->stream_id); + + (void)h2_process_pending_input(conn->data, httpc, &result); + } + } + return result; +} + + static ssize_t http2_handle_stream_close(struct connectdata *conn, struct Curl_easy *data, - struct HTTP *stream, CURLcode *err) { + struct HTTP *stream, CURLcode *err) +{ char *trailer_pos, *trailer_end; CURLcode result; struct http_conn *httpc = &conn->proto.httpc; diff --git a/lib/http2.h b/lib/http2.h index cad578ca1..891753590 100644 --- a/lib/http2.h +++ b/lib/http2.h @@ -52,6 +52,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn, void Curl_http2_setup_conn(struct connectdata *conn); void Curl_http2_setup_req(struct Curl_easy *data); void Curl_http2_done(struct connectdata *conn, bool premature); +CURLcode Curl_http2_done_sending(struct connectdata *conn); #else /* USE_NGHTTP2 */ #define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL #define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL @@ -63,6 +64,7 @@ void Curl_http2_done(struct connectdata *conn, bool premature); #define Curl_http2_init_state(x) #define Curl_http2_init_userset(x) #define Curl_http2_done(x,y) +#define Curl_http2_done_sending(x) #endif #endif /* HEADER_CURL_HTTP2_H */ diff --git a/lib/transfer.c b/lib/transfer.c index 5d5ee6be0..2fad6f32f 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -75,6 +75,7 @@ #include "multiif.h" #include "connect.h" #include "non-ascii.h" +#include "http2.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -832,6 +833,8 @@ static CURLcode done_sending(struct connectdata *conn, { k->keepon &= ~KEEP_SEND; /* we're done writing */ + Curl_http2_done_sending(conn); + if(conn->bits.rewindaftersend) { CURLcode result = Curl_readrewind(conn); if(result)