* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#define HTTP2_HUGE_WINDOW_SIZE (1 << 30)
+#ifdef DEBUG_HTTP2
+#define H2BUGF(x) x
+#else
+#define H2BUGF(x) do { } WHILE_FALSE
+#endif
+
/*
* Curl_http2_init_state() is called when the easy handle is created and
* allows for HTTP/2 specific init of state.
struct http_conn *c = &conn->proto.httpc;
(void)dead_connection;
- DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
+ H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
nghttp2_session_del(c->h2);
Curl_safefree(c->inbuf);
http2_stream_free(conn->data->req.protop);
- DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
+ H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
return CURLE_OK;
}
const nghttp2_push_promise *frame)
{
int rv;
- DEBUGF(infof(data, "PUSH_PROMISE received, stream %u!\n",
+ H2BUGF(infof(data, "PUSH_PROMISE received, stream %u!\n",
frame->promised_stream_id));
if(data->multi->push_cb) {
struct HTTP *stream;
heads.data = data;
heads.frame = frame;
/* ask the application */
- DEBUGF(infof(data, "Got PUSH_PROMISE, ask application!\n"));
+ H2BUGF(infof(data, "Got PUSH_PROMISE, ask application!\n"));
stream = data->req.protop;
if(!stream) {
frame->promised_stream_id, newhandle);
}
else {
- DEBUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
+ H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
rv = 1;
}
fail:
/* stream ID zero is for connection-oriented stuff */
if(frame->hd.type == NGHTTP2_SETTINGS) {
uint32_t max_conn = httpc->settings.max_concurrent_streams;
- DEBUGF(infof(conn->data, "Got SETTINGS\n"));
+ H2BUGF(infof(conn->data, "Got SETTINGS\n"));
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);
- DEBUGF(infof(conn->data, "MAX_CONCURRENT_STREAMS == %d\n",
+ H2BUGF(infof(conn->data, "MAX_CONCURRENT_STREAMS == %d\n",
httpc->settings.max_concurrent_streams));
- DEBUGF(infof(conn->data, "ENABLE_PUSH == %s\n",
+ H2BUGF(infof(conn->data, "ENABLE_PUSH == %s\n",
httpc->settings.enable_push?"TRUE":"false"));
if(max_conn != httpc->settings.max_concurrent_streams) {
/* only signal change if the value actually changed */
lastStream = stream_id;
}
if(!data_s) {
- DEBUGF(infof(conn->data,
+ H2BUGF(infof(conn->data,
"No Curl_easy associated with stream: %x\n",
stream_id));
return 0;
stream = data_s->req.protop;
if(!stream) {
- DEBUGF(infof(conn->data, "No proto pointer for stream: %x\n",
+ H2BUGF(infof(conn->data, "No proto pointer for stream: %x\n",
stream_id));
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
- DEBUGF(infof(data_s, "on_frame_recv() header %x stream %x\n",
+ H2BUGF(infof(data_s, "on_frame_recv() header %x stream %x\n",
frame->hd.type, stream_id));
switch(frame->hd.type) {
ncopy);
stream->nread_header_recvbuf += ncopy;
- DEBUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p\n",
+ H2BUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p\n",
ncopy, stream_id, stream->mem));
stream->len -= ncopy;
}
break;
default:
- DEBUGF(infof(conn->data, "Got frame type %x for stream %u!\n",
+ H2BUGF(infof(conn->data, "Got frame type %x for stream %u!\n",
frame->hd.type, stream_id));
break;
}
{
struct Curl_easy *data_s = NULL;
(void)userp;
-#if !defined(DEBUGBUILD) || defined(CURL_DISABLE_VERBOSE_STRINGS)
+#if !defined(DEBUG_HTTP2) || defined(CURL_DISABLE_VERBOSE_STRINGS)
(void)lib_error_code;
#endif
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
if(data_s) {
- DEBUGF(infof(data_s,
+ H2BUGF(infof(data_s,
"on_invalid_frame_recv() was called, error=%d:%s\n",
lib_error_code, nghttp2_strerror(lib_error_code)));
}
if(conn->data != data_s)
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
- DEBUGF(infof(data_s, "%zu data received for stream %u "
+ H2BUGF(infof(data_s, "%zu data received for stream %u "
"(%zu left in buffer %p, total %zu)\n",
nread, stream_id,
stream->len, stream->mem,
if(nread < len) {
stream->pausedata = data + nread;
stream->pauselen = len - nread;
- DEBUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer"
+ H2BUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer"
", stream %u\n",
len - nread, stream_id));
data_s->easy_conn->proto.httpc.pause_stream_id = stream_id;
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
if(data_s) {
- DEBUGF(infof(data_s, "before_frame_send() was called\n"));
+ H2BUGF(infof(data_s, "before_frame_send() was called\n"));
}
return 0;
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
if(data_s) {
- DEBUGF(infof(data_s, "on_frame_send() was called, length = %zd\n",
+ H2BUGF(infof(data_s, "on_frame_send() was called, length = %zd\n",
frame->hd.length));
}
return 0;
{
struct Curl_easy *data_s;
(void)userp;
-#if !defined(DEBUGBUILD) || defined(CURL_DISABLE_VERBOSE_STRINGS)
+#if !defined(DEBUG_HTTP2) || defined(CURL_DISABLE_VERBOSE_STRINGS)
(void)lib_error_code;
#endif
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
if(data_s) {
- DEBUGF(infof(data_s,
+ H2BUGF(infof(data_s,
"on_frame_not_send() was called, lib_error_code = %d\n",
lib_error_code));
}
decided to reject stream (e.g., PUSH_PROMISE). */
return 0;
}
- DEBUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n",
+ H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n",
Curl_http2_strerror(error_code), error_code, stream_id));
stream = data_s->req.protop;
if(!stream)
/* remove the entry from the hash as the stream is now gone */
nghttp2_session_set_stream_user_data(session, stream_id, 0);
- DEBUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
+ H2BUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
}
return 0;
}
return 0;
}
- DEBUGF(infof(data_s, "on_begin_headers() was called\n"));
+ H2BUGF(infof(data_s, "on_begin_headers() was called\n"));
if(frame->hd.type != NGHTTP2_HEADERS) {
return 0;
}
/* This is trailer HEADERS started. Allocate buffer for them. */
- DEBUGF(infof(data_s, "trailer field started\n"));
+ H2BUGF(infof(data_s, "trailer field started\n"));
DEBUGASSERT(stream->trailer_recvbuf == NULL);
/* 4 is for ": " and "\r\n". */
uint32_t n = (uint32_t)(namelen + valuelen + 4);
- DEBUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen,
+ H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen,
value));
Curl_add_buffer(stream->trailer_recvbuf, &n, sizeof(n));
if(conn->data != data_s)
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
- DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n",
+ H2BUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n",
stream->status_code, data_s));
return 0;
}
if(conn->data != data_s)
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
- DEBUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
+ H2BUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
value));
return 0; /* 0 is successful */
else if(nread == 0)
return NGHTTP2_ERR_DEFERRED;
- DEBUGF(infof(data_s, "data_source_read_callback: "
+ H2BUGF(infof(data_s, "data_source_read_callback: "
"returns %zu bytes stream %u\n",
nread, stream_id));
struct http_conn *httpc = &conn->proto.httpc;
if(http->header_recvbuf) {
- DEBUGF(infof(data, "free header_recvbuf!!\n"));
+ H2BUGF(infof(data, "free header_recvbuf!!\n"));
Curl_add_buffer_free(http->header_recvbuf);
http->header_recvbuf = NULL; /* clear the pointer */
Curl_add_buffer_free(http->trailer_recvbuf);
}
if(nread == rv) {
- DEBUGF(infof(data,
+ H2BUGF(infof(data,
"h2_process_pending_input: All data in connection buffer "
"processed\n"));
httpc->inbuflen = 0;
}
else {
httpc->nread_inbuf += rv;
- DEBUGF(infof(data,
+ H2BUGF(infof(data,
"h2_process_pending_input: %zu bytes left in connection "
"buffer\n",
httpc->inbuflen - httpc->nread_inbuf));
}
if(should_close_session(httpc)) {
- DEBUGF(infof(data,
+ H2BUGF(infof(data,
"h2_process_pending_input: nothing to do in this session\n"));
*err = CURLE_HTTP2;
return -1;
stream->close_handled = TRUE;
- DEBUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
+ H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
return 0;
}
h2_pri_spec(data, &pri_spec);
- DEBUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)\n",
+ H2BUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)\n",
stream->stream_id, data));
rv = nghttp2_submit_priority(h2, NGHTTP2_FLAG_NONE, stream->stream_id,
&pri_spec);
(void)sockindex; /* we always do HTTP2 on sockindex 0 */
if(should_close_session(httpc)) {
- DEBUGF(infof(data,
+ H2BUGF(infof(data,
"http2_recv: nothing to do in this session\n"));
*err = CURLE_HTTP2;
return -1;
ncopy);
stream->nread_header_recvbuf += ncopy;
- DEBUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n",
+ H2BUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n",
(int)ncopy));
return ncopy;
}
- DEBUGF(infof(data, "http2_recv: easy %p (stream %u)\n",
+ H2BUGF(infof(data, "http2_recv: easy %p (stream %u)\n",
data, stream->stream_id));
if((data->state.drain) && stream->memlen) {
- DEBUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n",
+ H2BUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n",
stream->memlen, stream->stream_id,
stream->mem, mem));
if(mem != stream->mem) {
infof(data, "%zu data bytes written\n", nread);
if(stream->pauselen == 0) {
- DEBUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
+ H2BUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
httpc->pause_stream_id = 0;
return -1;
}
}
- DEBUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n",
+ H2BUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n",
nread, stream->stream_id));
return nread;
}
socket is not read. But it seems that usually streams are
notified with its drain property, and socket is read again
quickly. */
- DEBUGF(infof(data, "stream %x is paused, pause id: %x\n",
+ H2BUGF(infof(data, "stream %x is paused, pause id: %x\n",
stream->stream_id, httpc->pause_stream_id));
*err = CURLE_AGAIN;
return -1;
return -1;
}
- DEBUGF(infof(data, "nread=%zd\n", nread));
+ H2BUGF(infof(data, "nread=%zd\n", nread));
httpc->inbuflen = nread;
inbuf = httpc->inbuf;
nread = httpc->inbuflen - httpc->nread_inbuf;
inbuf = httpc->inbuf + httpc->nread_inbuf;
- DEBUGF(infof(data, "Use data left in connection buffer, nread=%zd\n",
+ H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd\n",
nread));
}
rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
*err = CURLE_RECV_ERROR;
return -1;
}
- DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv));
+ H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv));
if(nread == rv) {
- DEBUGF(infof(data, "All data in connection buffer processed\n"));
+ H2BUGF(infof(data, "All data in connection buffer processed\n"));
httpc->inbuflen = 0;
httpc->nread_inbuf = 0;
}
else {
httpc->nread_inbuf += rv;
- DEBUGF(infof(data, "%zu bytes left in connection buffer\n",
+ H2BUGF(infof(data, "%zu bytes left in connection buffer\n",
httpc->inbuflen - httpc->nread_inbuf));
}
/* Always send pending frames in nghttp2 session, because
}
if(should_close_session(httpc)) {
- DEBUGF(infof(data, "http2_recv: nothing to do in this session\n"));
+ H2BUGF(infof(data, "http2_recv: nothing to do in this session\n"));
*err = CURLE_HTTP2;
return -1;
}
}
if(stream->memlen) {
ssize_t retlen = stream->memlen;
- DEBUGF(infof(data, "http2_recv: returns %zd for stream %u\n",
+ H2BUGF(infof(data, "http2_recv: returns %zd for stream %u\n",
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 */
- DEBUGF(infof(data, "Data returned for PAUSED stream %u\n",
+ H2BUGF(infof(data, "Data returned for PAUSED stream %u\n",
stream->stream_id));
}
else if(!stream->closed) {
return http2_handle_stream_close(conn, data, stream, err);
}
*err = CURLE_AGAIN;
- DEBUGF(infof(data, "http2_recv returns AGAIN for stream %u\n",
+ H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u\n",
stream->stream_id));
return -1;
}
(void)sockindex;
- DEBUGF(infof(conn->data, "http2_send len=%zu\n", len));
+ H2BUGF(infof(conn->data, "http2_send len=%zu\n", len));
if(stream->stream_id != -1) {
if(stream->close_handled) {
stream->upload_len = 0;
if(should_close_session(httpc)) {
- DEBUGF(infof(conn->data, "http2_send: nothing to do in this session\n"));
+ H2BUGF(infof(conn->data, "http2_send: nothing to do in this session\n"));
*err = CURLE_HTTP2;
return -1;
}
nghttp2_session_resume_data(h2, stream->stream_id);
}
- DEBUGF(infof(conn->data, "http2_send returns %zu for stream %u\n", len,
+ H2BUGF(infof(conn->data, "http2_send returns %zu for stream %u\n", len,
stream->stream_id));
return len;
}
for(i = 0; i < nheader; ++i) {
acc += nva[i].namelen + nva[i].valuelen;
- DEBUGF(infof(conn->data, "h2 header: %.*s:%.*s\n",
+ H2BUGF(infof(conn->data, "h2 header: %.*s:%.*s\n",
nva[i].namelen, nva[i].name,
nva[i].valuelen, nva[i].value));
}
Curl_safefree(nva);
if(stream_id < 0) {
- DEBUGF(infof(conn->data, "http2_send() send error\n"));
+ H2BUGF(infof(conn->data, "http2_send() send error\n"));
*err = CURLE_SEND_ERROR;
return -1;
}
}
if(should_close_session(httpc)) {
- DEBUGF(infof(conn->data, "http2_send: nothing to do in this session\n"));
+ H2BUGF(infof(conn->data, "http2_send: nothing to do in this session\n"));
*err = CURLE_HTTP2;
return -1;
}
return CURLE_HTTP2;
}
- DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc));
+ H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc));
if((ssize_t)nread == nproc) {
httpc->inbuflen = 0;
}
if(should_close_session(httpc)) {
- DEBUGF(infof(data,
+ H2BUGF(infof(data,
"nghttp2_session_send(): nothing to do in this session\n"));
return CURLE_HTTP2;
}