http2: call done_sending on end of upload
authorDaniel Stenberg <daniel@haxx.se>
Mon, 24 Jun 2019 09:21:26 +0000 (11:21 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 24 Jun 2019 21:11:37 +0000 (23:11 +0200)
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
lib/http2.c
lib/transfer.c
lib/transfer.h

index a80e8015756b8ae6d057e443e89817551459d7b9..d01e1bfdbb8e3ebb0d56d7407230dc3007a14148 100644 (file)
@@ -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;
               }
index b016bac92298ee06e1bae8d5baeac63185e2efde..bbd42bf2f315a7dc122cda3464d6205b0770937d 100644 (file)
@@ -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;
index 514330e8c1dc31a14892dfe9306a3cca41e34379..b25359196b7dcd5dacb6c2d6b5c8c14ced62675f 100644 (file)
@@ -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;
       }
index a9bff634867b19cdc557e5600c35eb0b55a6e435..ab7110a805149dc654257c33d548f63af311f215 100644 (file)
@@ -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,