http2: handle closed streams when uploading
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Sun, 28 Aug 2016 14:44:03 +0000 (16:44 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 28 Aug 2016 15:59:34 +0000 (17:59 +0200)
Fixes #986

lib/http.h
lib/http2.c

index 652900550e11c5918f6d6c3aadacb1ef206dc49d..9fb669c9d589eac74abac8852796eb745a6e1f75 100644 (file)
@@ -168,6 +168,7 @@ struct HTTP {
   const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
   size_t pauselen; /* the number of bytes left in data */
   bool closed; /* TRUE on HTTP2 stream close */
+  bool close_handled; /* TRUE if stream closure is handled by libcurl */
   uint32_t error_code; /* HTTP/2 error code */
 
   char *mem;     /* points to a buffer in memory to store received data */
index e51e72ab47c440f69d405bccafe7dfa1c5441899..6fc7cfa28372fdd73cef614edd0684a65cc973a2 100644 (file)
@@ -151,6 +151,7 @@ void Curl_http2_setup_req(struct Curl_easy *data)
   http->pauselen = 0;
   http->error_code = NGHTTP2_NO_ERROR;
   http->closed = FALSE;
+  http->close_handled = FALSE;
   http->mem = data->state.buffer;
   http->len = BUFSIZE;
   http->memlen = 0;
@@ -1256,6 +1257,8 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
     }
   }
 
+  stream->close_handled = TRUE;
+
   DEBUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
   return 0;
 }
@@ -1562,6 +1565,14 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
   DEBUGF(infof(conn->data, "http2_send len=%zu\n", len));
 
   if(stream->stream_id != -1) {
+    if(stream->close_handled) {
+      infof(conn->data, "stream %d closed\n", stream->stream_id);
+      *err = CURLE_HTTP2;
+      return -1;
+    }
+    else if(stream->closed) {
+      return http2_handle_stream_close(conn, conn->data, stream, err);
+    }
     /* If stream_id != -1, we have dispatched request HEADERS, and now
        are going to send or sending request body in DATA frame */
     stream->upload_mem = mem;