|
|
@@ -146,12 +146,12 @@ static CURLcode http2_disconnect(struct Curl_easy *data,
|
|
|
(void)data;
|
|
|
#endif
|
|
|
|
|
|
- H2BUGF(infof(data, "HTTP/2 DISCONNECT starts now\n"));
|
|
|
+ H2BUGF(infof(data, "HTTP/2 DISCONNECT starts now"));
|
|
|
|
|
|
nghttp2_session_del(c->h2);
|
|
|
Curl_safefree(c->inbuf);
|
|
|
|
|
|
- H2BUGF(infof(data, "HTTP/2 DISCONNECT done\n"));
|
|
|
+ H2BUGF(infof(data, "HTTP/2 DISCONNECT done"));
|
|
|
|
|
|
return CURLE_OK;
|
|
|
}
|
|
|
@@ -196,11 +196,13 @@ static bool http2_connisdead(struct Curl_easy *data, struct connectdata *conn)
|
|
|
data, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
|
|
|
if(nread != -1) {
|
|
|
infof(data,
|
|
|
- "%d bytes stray data read before trying h2 connection\n",
|
|
|
+ "%d bytes stray data read before trying h2 connection",
|
|
|
(int)nread);
|
|
|
httpc->nread_inbuf = 0;
|
|
|
httpc->inbuflen = nread;
|
|
|
- (void)h2_process_pending_input(data, httpc, &result);
|
|
|
+ if(h2_process_pending_input(data, httpc, &result) < 0)
|
|
|
+ /* immediate error, considered dead */
|
|
|
+ dead = TRUE;
|
|
|
}
|
|
|
else
|
|
|
/* the read failed so let's say this is dead anyway */
|
|
|
@@ -350,13 +352,12 @@ static const struct Curl_handler Curl_handler_http2_ssl = {
|
|
|
};
|
|
|
|
|
|
/*
|
|
|
- * Store nghttp2 version info in this buffer, Prefix with a space. Return
|
|
|
- * total length written.
|
|
|
+ * Store nghttp2 version info in this buffer.
|
|
|
*/
|
|
|
-int Curl_http2_ver(char *p, size_t len)
|
|
|
+void Curl_http2_ver(char *p, size_t len)
|
|
|
{
|
|
|
nghttp2_info *h2 = nghttp2_version(0);
|
|
|
- return msnprintf(p, len, "nghttp2/%s", h2->version_str);
|
|
|
+ (void)msnprintf(p, len, "nghttp2/%s", h2->version_str);
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -551,7 +552,7 @@ static int push_promise(struct Curl_easy *data,
|
|
|
const nghttp2_push_promise *frame)
|
|
|
{
|
|
|
int rv; /* one of the CURL_PUSH_* defines */
|
|
|
- H2BUGF(infof(data, "PUSH_PROMISE received, stream %u!\n",
|
|
|
+ H2BUGF(infof(data, "PUSH_PROMISE received, stream %u!",
|
|
|
frame->promised_stream_id));
|
|
|
if(data->multi->push_cb) {
|
|
|
struct HTTP *stream;
|
|
|
@@ -563,7 +564,7 @@ static int push_promise(struct Curl_easy *data,
|
|
|
/* clone the parent */
|
|
|
struct Curl_easy *newhandle = duphandle(data);
|
|
|
if(!newhandle) {
|
|
|
- infof(data, "failed to duplicate handle\n");
|
|
|
+ infof(data, "failed to duplicate handle");
|
|
|
rv = CURL_PUSH_DENY; /* FAIL HARD */
|
|
|
goto fail;
|
|
|
}
|
|
|
@@ -571,7 +572,7 @@ static int push_promise(struct Curl_easy *data,
|
|
|
heads.data = data;
|
|
|
heads.frame = frame;
|
|
|
/* ask the application */
|
|
|
- H2BUGF(infof(data, "Got PUSH_PROMISE, ask application!\n"));
|
|
|
+ H2BUGF(infof(data, "Got PUSH_PROMISE, ask application!"));
|
|
|
|
|
|
stream = data->req.p.http;
|
|
|
if(!stream) {
|
|
|
@@ -619,7 +620,7 @@ static int push_promise(struct Curl_easy *data,
|
|
|
state with the given connection !*/
|
|
|
rc = Curl_multi_add_perform(data->multi, newhandle, conn);
|
|
|
if(rc) {
|
|
|
- infof(data, "failed to add handle to multi\n");
|
|
|
+ infof(data, "failed to add handle to multi");
|
|
|
http2_stream_free(newhandle->req.p.http);
|
|
|
newhandle->req.p.http = NULL;
|
|
|
Curl_close(&newhandle);
|
|
|
@@ -632,15 +633,17 @@ static int push_promise(struct Curl_easy *data,
|
|
|
frame->promised_stream_id,
|
|
|
newhandle);
|
|
|
if(rv) {
|
|
|
- infof(data, "failed to set user_data for stream %d\n",
|
|
|
+ infof(data, "failed to set user_data for stream %d",
|
|
|
frame->promised_stream_id);
|
|
|
DEBUGASSERT(0);
|
|
|
rv = CURL_PUSH_DENY;
|
|
|
goto fail;
|
|
|
}
|
|
|
+ Curl_dyn_init(&newstream->header_recvbuf, DYN_H2_HEADERS);
|
|
|
+ Curl_dyn_init(&newstream->trailer_recvbuf, DYN_H2_TRAILERS);
|
|
|
}
|
|
|
else {
|
|
|
- H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
|
|
|
+ H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!"));
|
|
|
rv = CURL_PUSH_DENY;
|
|
|
}
|
|
|
fail:
|
|
|
@@ -676,21 +679,21 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
|
|
/* stream ID zero is for connection-oriented stuff */
|
|
|
if(frame->hd.type == NGHTTP2_SETTINGS) {
|
|
|
uint32_t max_conn = httpc->settings.max_concurrent_streams;
|
|
|
- H2BUGF(infof(data, "Got SETTINGS\n"));
|
|
|
+ H2BUGF(infof(data, "Got SETTINGS"));
|
|
|
httpc->settings.max_concurrent_streams =
|
|
|
nghttp2_session_get_remote_settings(
|
|
|
session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
|
|
|
httpc->settings.enable_push =
|
|
|
nghttp2_session_get_remote_settings(
|
|
|
session, NGHTTP2_SETTINGS_ENABLE_PUSH);
|
|
|
- H2BUGF(infof(data, "MAX_CONCURRENT_STREAMS == %d\n",
|
|
|
+ H2BUGF(infof(data, "MAX_CONCURRENT_STREAMS == %d",
|
|
|
httpc->settings.max_concurrent_streams));
|
|
|
- H2BUGF(infof(data, "ENABLE_PUSH == %s\n",
|
|
|
+ H2BUGF(infof(data, "ENABLE_PUSH == %s",
|
|
|
httpc->settings.enable_push?"TRUE":"false"));
|
|
|
if(max_conn != httpc->settings.max_concurrent_streams) {
|
|
|
/* only signal change if the value actually changed */
|
|
|
infof(data,
|
|
|
- "Connection state changed (MAX_CONCURRENT_STREAMS == %u)!\n",
|
|
|
+ "Connection state changed (MAX_CONCURRENT_STREAMS == %u)!",
|
|
|
httpc->settings.max_concurrent_streams);
|
|
|
multi_connchanged(data->multi);
|
|
|
}
|
|
|
@@ -700,19 +703,19 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
|
|
data_s = nghttp2_session_get_stream_user_data(session, stream_id);
|
|
|
if(!data_s) {
|
|
|
H2BUGF(infof(data,
|
|
|
- "No Curl_easy associated with stream: %x\n",
|
|
|
+ "No Curl_easy associated with stream: %x",
|
|
|
stream_id));
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
stream = data_s->req.p.http;
|
|
|
if(!stream) {
|
|
|
- H2BUGF(infof(data_s, "No proto pointer for stream: %x\n",
|
|
|
+ H2BUGF(infof(data_s, "No proto pointer for stream: %x",
|
|
|
stream_id));
|
|
|
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
|
|
}
|
|
|
|
|
|
- H2BUGF(infof(data_s, "on_frame_recv() header %x stream %x\n",
|
|
|
+ H2BUGF(infof(data_s, "on_frame_recv() header %x stream %x",
|
|
|
frame->hd.type, stream_id));
|
|
|
|
|
|
switch(frame->hd.type) {
|
|
|
@@ -760,7 +763,8 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
|
|
ncopy);
|
|
|
stream->nread_header_recvbuf += ncopy;
|
|
|
|
|
|
- H2BUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p\n",
|
|
|
+ DEBUGASSERT(stream->mem);
|
|
|
+ H2BUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p",
|
|
|
ncopy, stream_id, stream->mem));
|
|
|
|
|
|
stream->len -= ncopy;
|
|
|
@@ -782,13 +786,13 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
|
|
if(nghttp2_is_fatal(h2))
|
|
|
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
|
|
else if(rv == CURL_PUSH_ERROROUT) {
|
|
|
- DEBUGF(infof(data_s, "Fail the parent stream (too)\n"));
|
|
|
+ DEBUGF(infof(data_s, "Fail the parent stream (too)"));
|
|
|
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
- H2BUGF(infof(data_s, "Got frame type %x for stream %u!\n",
|
|
|
+ H2BUGF(infof(data_s, "Got frame type %x for stream %u!",
|
|
|
frame->hd.type, stream_id));
|
|
|
break;
|
|
|
}
|
|
|
@@ -833,7 +837,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
|
|
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
|
|
|
|
|
|
H2BUGF(infof(data_s, "%zu data received for stream %u "
|
|
|
- "(%zu left in buffer %p, total %zu)\n",
|
|
|
+ "(%zu left in buffer %p, total %zu)",
|
|
|
nread, stream_id,
|
|
|
stream->len, stream->mem,
|
|
|
stream->memlen));
|
|
|
@@ -842,7 +846,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
|
|
stream->pausedata = mem + nread;
|
|
|
stream->pauselen = len - nread;
|
|
|
H2BUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer"
|
|
|
- ", stream %u\n",
|
|
|
+ ", stream %u",
|
|
|
len - nread, stream_id));
|
|
|
data_s->conn->proto.httpc.pause_stream_id = stream_id;
|
|
|
|
|
|
@@ -880,7 +884,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
|
|
decided to reject stream (e.g., PUSH_PROMISE). */
|
|
|
return 0;
|
|
|
}
|
|
|
- H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n",
|
|
|
+ H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u",
|
|
|
nghttp2_http2_strerror(error_code), error_code, stream_id));
|
|
|
stream = data_s->req.p.http;
|
|
|
if(!stream)
|
|
|
@@ -895,15 +899,15 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
|
|
/* remove the entry from the hash as the stream is now gone */
|
|
|
rv = nghttp2_session_set_stream_user_data(session, stream_id, 0);
|
|
|
if(rv) {
|
|
|
- infof(data_s, "http/2: failed to clear user_data for stream %d!\n",
|
|
|
+ infof(data_s, "http/2: failed to clear user_data for stream %d!",
|
|
|
stream_id);
|
|
|
DEBUGASSERT(0);
|
|
|
}
|
|
|
if(stream_id == httpc->pause_stream_id) {
|
|
|
- H2BUGF(infof(data_s, "Stopped the pause stream!\n"));
|
|
|
+ H2BUGF(infof(data_s, "Stopped the pause stream!"));
|
|
|
httpc->pause_stream_id = 0;
|
|
|
}
|
|
|
- H2BUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
|
|
|
+ H2BUGF(infof(data_s, "Removed stream %u hash!", stream_id));
|
|
|
stream->stream_id = 0; /* cleared */
|
|
|
}
|
|
|
return 0;
|
|
|
@@ -921,7 +925,7 @@ static int on_begin_headers(nghttp2_session *session,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- H2BUGF(infof(data_s, "on_begin_headers() was called\n"));
|
|
|
+ H2BUGF(infof(data_s, "on_begin_headers() was called"));
|
|
|
|
|
|
if(frame->hd.type != NGHTTP2_HEADERS) {
|
|
|
return 0;
|
|
|
@@ -1049,7 +1053,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
|
|
|
|
|
if(stream->bodystarted) {
|
|
|
/* This is a trailer */
|
|
|
- H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen,
|
|
|
+ H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s", namelen, name, valuelen,
|
|
|
value));
|
|
|
result = Curl_dyn_addf(&stream->trailer_recvbuf,
|
|
|
"%.*s: %.*s\r\n", namelen, name,
|
|
|
@@ -1082,7 +1086,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
|
|
if(get_transfer(httpc) != data_s)
|
|
|
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
|
|
|
|
|
|
- H2BUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n",
|
|
|
+ H2BUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)",
|
|
|
stream->status_code, data_s));
|
|
|
return 0;
|
|
|
}
|
|
|
@@ -1106,7 +1110,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
|
|
if(get_transfer(httpc) != data_s)
|
|
|
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
|
|
|
|
|
|
- H2BUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
|
|
|
+ H2BUGF(infof(data_s, "h2 header: %.*s: %.*s", namelen, name, valuelen,
|
|
|
value));
|
|
|
|
|
|
return 0; /* 0 is successful */
|
|
|
@@ -1156,7 +1160,7 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
|
|
|
return NGHTTP2_ERR_DEFERRED;
|
|
|
|
|
|
H2BUGF(infof(data_s, "data_source_read_callback: "
|
|
|
- "returns %zu bytes stream %u\n",
|
|
|
+ "returns %zu bytes stream %u",
|
|
|
nread, stream_id));
|
|
|
|
|
|
return nread;
|
|
|
@@ -1223,7 +1227,7 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
|
|
|
(void)nghttp2_session_send(httpc->h2);
|
|
|
|
|
|
if(http->stream_id == httpc->pause_stream_id) {
|
|
|
- infof(data, "stopped the pause stream!\n");
|
|
|
+ infof(data, "stopped the pause stream!");
|
|
|
httpc->pause_stream_id = 0;
|
|
|
}
|
|
|
}
|
|
|
@@ -1236,7 +1240,7 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
|
|
|
int rv = nghttp2_session_set_stream_user_data(httpc->h2,
|
|
|
http->stream_id, 0);
|
|
|
if(rv) {
|
|
|
- infof(data, "http/2: failed to clear user_data for stream %d!\n",
|
|
|
+ infof(data, "http/2: failed to clear user_data for stream %d!",
|
|
|
http->stream_id);
|
|
|
DEBUGASSERT(0);
|
|
|
}
|
|
|
@@ -1383,7 +1387,7 @@ static int h2_process_pending_input(struct Curl_easy *data,
|
|
|
if(nread == rv) {
|
|
|
H2BUGF(infof(data,
|
|
|
"h2_process_pending_input: All data in connection buffer "
|
|
|
- "processed\n"));
|
|
|
+ "processed"));
|
|
|
httpc->inbuflen = 0;
|
|
|
httpc->nread_inbuf = 0;
|
|
|
}
|
|
|
@@ -1391,7 +1395,7 @@ static int h2_process_pending_input(struct Curl_easy *data,
|
|
|
httpc->nread_inbuf += rv;
|
|
|
H2BUGF(infof(data,
|
|
|
"h2_process_pending_input: %zu bytes left in connection "
|
|
|
- "buffer\n",
|
|
|
+ "buffer",
|
|
|
httpc->inbuflen - httpc->nread_inbuf));
|
|
|
}
|
|
|
|
|
|
@@ -1412,7 +1416,7 @@ static int h2_process_pending_input(struct Curl_easy *data,
|
|
|
if(should_close_session(httpc)) {
|
|
|
struct HTTP *stream = data->req.p.http;
|
|
|
H2BUGF(infof(data,
|
|
|
- "h2_process_pending_input: nothing to do in this session\n"));
|
|
|
+ "h2_process_pending_input: nothing to do in this session"));
|
|
|
if(stream->error)
|
|
|
*err = CURLE_HTTP2;
|
|
|
else {
|
|
|
@@ -1456,7 +1460,7 @@ CURLcode Curl_http2_done_sending(struct Curl_easy *data,
|
|
|
struct SingleRequest *k = &data->req;
|
|
|
int rv;
|
|
|
|
|
|
- H2BUGF(infof(data, "HTTP/2 still wants to send data (easy %p)\n", data));
|
|
|
+ H2BUGF(infof(data, "HTTP/2 still wants to send data (easy %p)", data));
|
|
|
|
|
|
/* and attempt to send the pending frames */
|
|
|
rv = h2_session_send(data, h2);
|
|
|
@@ -1495,7 +1499,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
|
|
/* Reset to FALSE to prevent infinite loop in readwrite_data function. */
|
|
|
stream->closed = FALSE;
|
|
|
if(stream->error == NGHTTP2_REFUSED_STREAM) {
|
|
|
- H2BUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection!\n",
|
|
|
+ H2BUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection!",
|
|
|
stream->stream_id));
|
|
|
connclose(conn, "REFUSED_STREAM"); /* don't use this anymore */
|
|
|
data->state.refused_stream = TRUE;
|
|
|
@@ -1544,7 +1548,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
|
|
|
|
|
stream->close_handled = TRUE;
|
|
|
|
|
|
- H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
|
|
|
+ H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close"));
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
@@ -1587,7 +1591,7 @@ static int h2_session_send(struct Curl_easy *data,
|
|
|
|
|
|
h2_pri_spec(data, &pri_spec);
|
|
|
|
|
|
- H2BUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)\n",
|
|
|
+ H2BUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)",
|
|
|
stream->stream_id, data));
|
|
|
DEBUGASSERT(stream->stream_id != -1);
|
|
|
rv = nghttp2_submit_priority(h2, NGHTTP2_FLAG_NONE, stream->stream_id,
|
|
|
@@ -1611,7 +1615,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
|
|
|
|
|
if(should_close_session(httpc)) {
|
|
|
H2BUGF(infof(data,
|
|
|
- "http2_recv: nothing to do in this session\n"));
|
|
|
+ "http2_recv: nothing to do in this session"));
|
|
|
if(conn->bits.close) {
|
|
|
/* already marked for closure, return OK and we're done */
|
|
|
*err = CURLE_OK;
|
|
|
@@ -1621,10 +1625,6 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- if(stream->closed)
|
|
|
- /* closed overrides paused */
|
|
|
- return http2_handle_stream_close(conn, data, stream, err);
|
|
|
-
|
|
|
/* Nullify here because we call nghttp2_session_send() and they
|
|
|
might refer to the old buffer. */
|
|
|
stream->upload_mem = NULL;
|
|
|
@@ -1645,12 +1645,12 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
|
|
stream->nread_header_recvbuf, ncopy);
|
|
|
stream->nread_header_recvbuf += ncopy;
|
|
|
|
|
|
- H2BUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n",
|
|
|
+ H2BUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf",
|
|
|
(int)ncopy));
|
|
|
return ncopy;
|
|
|
}
|
|
|
|
|
|
- H2BUGF(infof(data, "http2_recv: easy %p (stream %u) win %u/%u\n",
|
|
|
+ H2BUGF(infof(data, "http2_recv: easy %p (stream %u) win %u/%u",
|
|
|
data, stream->stream_id,
|
|
|
nghttp2_session_get_local_window_size(httpc->h2),
|
|
|
nghttp2_session_get_stream_local_window_size(httpc->h2,
|
|
|
@@ -1658,7 +1658,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
|
|
));
|
|
|
|
|
|
if((data->state.drain) && stream->memlen) {
|
|
|
- H2BUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n",
|
|
|
+ H2BUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)",
|
|
|
stream->memlen, stream->stream_id,
|
|
|
stream->mem, mem));
|
|
|
if(mem != stream->mem) {
|
|
|
@@ -1686,7 +1686,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
|
|
stream->pauselen -= nread;
|
|
|
|
|
|
if(stream->pauselen == 0) {
|
|
|
- H2BUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
|
|
|
+ H2BUGF(infof(data, "Unpaused by stream %u", stream->stream_id));
|
|
|
DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
|
|
|
httpc->pause_stream_id = 0;
|
|
|
|
|
|
@@ -1704,7 +1704,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
- H2BUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n",
|
|
|
+ H2BUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u",
|
|
|
nread, stream->stream_id));
|
|
|
return nread;
|
|
|
}
|
|
|
@@ -1720,7 +1720,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
|
|
if(stream->closed)
|
|
|
/* closed overrides paused */
|
|
|
return 0;
|
|
|
- H2BUGF(infof(data, "stream %x is paused, pause id: %x\n",
|
|
|
+ H2BUGF(infof(data, "stream %x is paused, pause id: %x",
|
|
|
stream->stream_id, httpc->pause_stream_id));
|
|
|
*err = CURLE_AGAIN;
|
|
|
return -1;
|
|
|
@@ -1758,12 +1758,12 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- H2BUGF(infof(data, "end of stream\n"));
|
|
|
+ H2BUGF(infof(data, "end of stream"));
|
|
|
*err = CURLE_OK;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- H2BUGF(infof(data, "nread=%zd\n", nread));
|
|
|
+ H2BUGF(infof(data, "nread=%zd", nread));
|
|
|
|
|
|
httpc->inbuflen = nread;
|
|
|
|
|
|
@@ -1772,7 +1772,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
|
|
else {
|
|
|
nread = httpc->inbuflen - httpc->nread_inbuf;
|
|
|
(void)nread; /* silence warning, used in debug */
|
|
|
- H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd\n",
|
|
|
+ H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd",
|
|
|
nread));
|
|
|
}
|
|
|
|
|
|
@@ -1781,14 +1781,14 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
|
|
}
|
|
|
if(stream->memlen) {
|
|
|
ssize_t retlen = stream->memlen;
|
|
|
- H2BUGF(infof(data, "http2_recv: returns %zd for stream %u\n",
|
|
|
+ H2BUGF(infof(data, "http2_recv: returns %zd for stream %u",
|
|
|
retlen, stream->stream_id));
|
|
|
stream->memlen = 0;
|
|
|
|
|
|
if(httpc->pause_stream_id == stream->stream_id) {
|
|
|
/* data for this stream is returned now, but this stream caused a pause
|
|
|
already so we need it called again asap */
|
|
|
- H2BUGF(infof(data, "Data returned for PAUSED stream %u\n",
|
|
|
+ H2BUGF(infof(data, "Data returned for PAUSED stream %u",
|
|
|
stream->stream_id));
|
|
|
}
|
|
|
else if(!stream->closed) {
|
|
|
@@ -1803,7 +1803,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
|
|
if(stream->closed)
|
|
|
return http2_handle_stream_close(conn, data, stream, err);
|
|
|
*err = CURLE_AGAIN;
|
|
|
- H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u\n",
|
|
|
+ H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u",
|
|
|
stream->stream_id));
|
|
|
return -1;
|
|
|
}
|
|
|
@@ -1907,11 +1907,11 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
|
|
|
|
|
(void)sockindex;
|
|
|
|
|
|
- H2BUGF(infof(data, "http2_send len=%zu\n", len));
|
|
|
+ H2BUGF(infof(data, "http2_send len=%zu", len));
|
|
|
|
|
|
if(stream->stream_id != -1) {
|
|
|
if(stream->close_handled) {
|
|
|
- infof(data, "stream %d closed\n", stream->stream_id);
|
|
|
+ infof(data, "stream %d closed", stream->stream_id);
|
|
|
*err = CURLE_HTTP2_STREAM;
|
|
|
return -1;
|
|
|
}
|
|
|
@@ -1940,7 +1940,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
|
|
stream->upload_len = 0;
|
|
|
|
|
|
if(should_close_session(httpc)) {
|
|
|
- H2BUGF(infof(data, "http2_send: nothing to do in this session\n"));
|
|
|
+ H2BUGF(infof(data, "http2_send: nothing to do in this session"));
|
|
|
*err = CURLE_HTTP2;
|
|
|
return -1;
|
|
|
}
|
|
|
@@ -1953,7 +1953,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
|
|
nghttp2_session_resume_data(h2, stream->stream_id);
|
|
|
}
|
|
|
|
|
|
- H2BUGF(infof(data, "http2_send returns %zu for stream %u\n", len,
|
|
|
+ H2BUGF(infof(data, "http2_send returns %zu for stream %u", len,
|
|
|
stream->stream_id));
|
|
|
return len;
|
|
|
}
|
|
|
@@ -2116,7 +2116,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
|
|
for(i = 0; i < nheader; ++i) {
|
|
|
acc += nva[i].namelen + nva[i].valuelen;
|
|
|
|
|
|
- H2BUGF(infof(data, "h2 header: %.*s:%.*s\n",
|
|
|
+ H2BUGF(infof(data, "h2 header: %.*s:%.*s",
|
|
|
nva[i].namelen, nva[i].name,
|
|
|
nva[i].valuelen, nva[i].value));
|
|
|
}
|
|
|
@@ -2124,13 +2124,13 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
|
|
if(acc > MAX_ACC) {
|
|
|
infof(data, "http2_send: Warning: The cumulative length of all "
|
|
|
"headers exceeds %d bytes and that could cause the "
|
|
|
- "stream to be rejected.\n", MAX_ACC);
|
|
|
+ "stream to be rejected.", MAX_ACC);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
h2_pri_spec(data, &pri_spec);
|
|
|
|
|
|
- H2BUGF(infof(data, "http2_send request allowed %d (easy handle %p)\n",
|
|
|
+ H2BUGF(infof(data, "http2_send request allowed %d (easy handle %p)",
|
|
|
nghttp2_session_check_request_allowed(h2), (void *)data));
|
|
|
|
|
|
switch(data->state.httpreq) {
|
|
|
@@ -2158,20 +2158,20 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
|
|
|
|
|
if(stream_id < 0) {
|
|
|
H2BUGF(infof(data,
|
|
|
- "http2_send() nghttp2_submit_request error (%s)%d\n",
|
|
|
+ "http2_send() nghttp2_submit_request error (%s)%d",
|
|
|
nghttp2_strerror(stream_id), stream_id));
|
|
|
*err = CURLE_SEND_ERROR;
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- infof(data, "Using Stream ID: %x (easy handle %p)\n",
|
|
|
+ infof(data, "Using Stream ID: %x (easy handle %p)",
|
|
|
stream_id, (void *)data);
|
|
|
stream->stream_id = stream_id;
|
|
|
|
|
|
rv = h2_session_send(data, h2);
|
|
|
if(rv) {
|
|
|
H2BUGF(infof(data,
|
|
|
- "http2_send() nghttp2_session_send error (%s)%d\n",
|
|
|
+ "http2_send() nghttp2_session_send error (%s)%d",
|
|
|
nghttp2_strerror(rv), rv));
|
|
|
|
|
|
*err = CURLE_SEND_ERROR;
|
|
|
@@ -2179,7 +2179,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
|
|
}
|
|
|
|
|
|
if(should_close_session(httpc)) {
|
|
|
- H2BUGF(infof(data, "http2_send: nothing to do in this session\n"));
|
|
|
+ H2BUGF(infof(data, "http2_send: nothing to do in this session"));
|
|
|
*err = CURLE_HTTP2;
|
|
|
return -1;
|
|
|
}
|
|
|
@@ -2215,6 +2215,22 @@ CURLcode Curl_http2_setup(struct Curl_easy *data,
|
|
|
Curl_dyn_init(&stream->header_recvbuf, DYN_H2_HEADERS);
|
|
|
Curl_dyn_init(&stream->trailer_recvbuf, DYN_H2_TRAILERS);
|
|
|
|
|
|
+ stream->upload_left = 0;
|
|
|
+ stream->upload_mem = NULL;
|
|
|
+ stream->upload_len = 0;
|
|
|
+ stream->mem = data->state.buffer;
|
|
|
+ stream->len = data->set.buffer_size;
|
|
|
+
|
|
|
+ httpc->inbuflen = 0;
|
|
|
+ httpc->nread_inbuf = 0;
|
|
|
+
|
|
|
+ httpc->pause_stream_id = 0;
|
|
|
+ httpc->drain_total = 0;
|
|
|
+
|
|
|
+ multi_connchanged(data->multi);
|
|
|
+ /* below this point only connection related inits are done, which only needs
|
|
|
+ to be done once per connection */
|
|
|
+
|
|
|
if((conn->handler == &Curl_handler_http2_ssl) ||
|
|
|
(conn->handler == &Curl_handler_http2))
|
|
|
return CURLE_OK; /* already done */
|
|
|
@@ -2230,25 +2246,13 @@ CURLcode Curl_http2_setup(struct Curl_easy *data,
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- infof(data, "Using HTTP2, server supports multi-use\n");
|
|
|
- stream->upload_left = 0;
|
|
|
- stream->upload_mem = NULL;
|
|
|
- stream->upload_len = 0;
|
|
|
- stream->mem = data->state.buffer;
|
|
|
- stream->len = data->set.buffer_size;
|
|
|
-
|
|
|
- httpc->inbuflen = 0;
|
|
|
- httpc->nread_inbuf = 0;
|
|
|
-
|
|
|
- httpc->pause_stream_id = 0;
|
|
|
- httpc->drain_total = 0;
|
|
|
+ infof(data, "Using HTTP2, server supports multiplexing");
|
|
|
|
|
|
conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
|
|
|
conn->httpversion = 20;
|
|
|
conn->bundle->multiuse = BUNDLE_MULTIPLEX;
|
|
|
|
|
|
- infof(data, "Connection state changed (HTTP/2 confirmed)\n");
|
|
|
- multi_connchanged(data->multi);
|
|
|
+ infof(data, "Connection state changed (HTTP/2 confirmed)");
|
|
|
|
|
|
return CURLE_OK;
|
|
|
}
|
|
|
@@ -2287,7 +2291,7 @@ CURLcode Curl_http2_switched(struct Curl_easy *data,
|
|
|
stream->stream_id,
|
|
|
data);
|
|
|
if(rv) {
|
|
|
- infof(data, "http/2: failed to set user_data for stream %d!\n",
|
|
|
+ infof(data, "http/2: failed to set user_data for stream %d!",
|
|
|
stream->stream_id);
|
|
|
DEBUGASSERT(0);
|
|
|
}
|
|
|
@@ -2327,7 +2331,7 @@ CURLcode Curl_http2_switched(struct Curl_easy *data,
|
|
|
}
|
|
|
|
|
|
infof(data, "Copying HTTP/2 data in stream buffer to connection buffer"
|
|
|
- " after upgrade: len=%zu\n",
|
|
|
+ " after upgrade: len=%zu",
|
|
|
nread);
|
|
|
|
|
|
if(nread)
|
|
|
@@ -2337,15 +2341,8 @@ CURLcode Curl_http2_switched(struct Curl_easy *data,
|
|
|
|
|
|
DEBUGASSERT(httpc->nread_inbuf == 0);
|
|
|
|
|
|
- /* Good enough to call it an end once the remaining payload is copied to the
|
|
|
- * connection buffer.
|
|
|
- * Some servers (e.g. nghttpx v1.43.0) may fulfill stream 1 immediately
|
|
|
- * following the protocol switch other than waiting for the client-side
|
|
|
- * connection preface. If h2_process_pending_input is invoked here to parse
|
|
|
- * the remaining payload, stream 1 would be marked as closed too early and
|
|
|
- * thus ignored in http2_recv (following 252790c53).
|
|
|
- * The logic in lib/http.c and lib/transfer.c guarantees a following
|
|
|
- * http2_recv would be invoked very soon. */
|
|
|
+ if(-1 == h2_process_pending_input(data, httpc, &result))
|
|
|
+ return CURLE_HTTP2;
|
|
|
|
|
|
return CURLE_OK;
|
|
|
}
|
|
|
@@ -2378,7 +2375,7 @@ CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause)
|
|
|
if(rv)
|
|
|
return CURLE_SEND_ERROR;
|
|
|
|
|
|
- DEBUGF(infof(data, "Set HTTP/2 window size to %u for stream %u\n",
|
|
|
+ DEBUGF(infof(data, "Set HTTP/2 window size to %u for stream %u",
|
|
|
window, stream->stream_id));
|
|
|
|
|
|
#ifdef DEBUGBUILD
|
|
|
@@ -2387,7 +2384,7 @@ CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause)
|
|
|
uint32_t window2 =
|
|
|
nghttp2_session_get_stream_local_window_size(httpc->h2,
|
|
|
stream->stream_id);
|
|
|
- DEBUGF(infof(data, "HTTP/2 window size is now %u for stream %u\n",
|
|
|
+ DEBUGF(infof(data, "HTTP/2 window size is now %u for stream %u",
|
|
|
window2, stream->stream_id));
|
|
|
}
|
|
|
#endif
|