]> granicus.if.org Git - curl/commitdiff
http2: return EOF when done uploading without known size
authorDaniel Stenberg <daniel@haxx.se>
Mon, 5 Sep 2016 09:07:40 +0000 (11:07 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 5 Sep 2016 12:32:32 +0000 (14:32 +0200)
Fixes #982

lib/http2.c
lib/http2.h
lib/transfer.c

index 17915d45a034b247985912d9cc8c4d330ffe24f1..a66b8f74cbbd880b2767e316c886de4345c333db 100644 (file)
@@ -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;
index cad578ca1d28b9aa2d175913eab592f83bd92e84..89175359021ae6f46d5fdd2620dbb3bfda262009 100644 (file)
@@ -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 */
index 5d5ee6be05eddfa0149630418c66c59f2f4bdf78..2fad6f32fc1a0944684ed9b35f8bdec50faee6f2 100644 (file)
@@ -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)