]> granicus.if.org Git - curl/commitdiff
http2: Faster http2 upload
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Wed, 20 May 2015 14:11:43 +0000 (23:11 +0900)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 20 May 2015 20:43:37 +0000 (22:43 +0200)
Previously, when we send all given buffer in data_source_callback, we
return NGHTTP2_ERR_DEFERRED, and nghttp2 library removes this stream
temporarily for writing.  This itself is good.  If this is the sole
stream in the session, nghttp2_session_want_write() returns zero,
which means that libcurl does not check writeability of the underlying
socket.  This leads to very slow upload, because it seems curl only
upload 16k something per 1 second.  To fix this, if we still have data
to send, call nghttp2_session_resume_data after nghttp2_session_send.
This makes nghttp2_session_want_write() returns nonzero (if connection
window still opens), and as a result, socket writeability is checked,
and upload speed becomes normal.

lib/http2.c

index c653bbe177de36a1e777ff20f50f1986cf69f289..df3fa9d1bb2a9fc5575e0309f9dd38768ef0892b 100644 (file)
@@ -1024,6 +1024,19 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
     }
     len -= stream->upload_len;
 
+    /* Nullify here because we call nghttp2_session_send() and they
+       might refer to the old buffer. */
+    stream->upload_mem = NULL;
+    stream->upload_len = 0;
+
+    if(stream->upload_left) {
+      /* we are sure that we have more data to send here.  Calling the
+         following API will make nghttp2_session_want_write() return
+         nonzero if remote window allows it, which then libcurl checks
+         socket is writable or not.  See http2_perform_getsock(). */
+      nghttp2_session_resume_data(h2, stream->stream_id);
+    }
+
     DEBUGF(infof(conn->data, "http2_send returns %zu for stream %x\n", len,
                  stream->stream_id));
     return len;