From c175d184a2c254765d1a0d66978de4886b0a2ece Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Wed, 20 May 2015 23:11:43 +0900 Subject: [PATCH] http2: Faster http2 upload 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 | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/http2.c b/lib/http2.c index c653bbe177de36..df3fa9d1bb2a9f 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -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;