Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions docs/libcurl/curl_easy_pause.3
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ this because it needs to drain the socket for the other transfers and the
already announced window size for the paused transfer will allow the server to
continue sending data up to that window size amount. By default, libcurl
announces a 32 megabyte window size, which thus can make libcurl end up
buffering 32 megabyte of data for a paused stream.
buffering 32 megabyte of data for a paused stream. The window size can be
changed with \fICURLOPT_STREAM_WINDOW_SIZE(3)\fP (easy interface) or
\fICURLMOPT_STREAM_WINDOW_SIZE(3)\fP (multi interface).

When such a paused stream is unpaused again, any buffered data will be
delivered first.
Expand Down Expand Up @@ -109,4 +111,5 @@ CURLE_OK (zero) means that the option was set properly, and a non-zero return
code means something wrong occurred after the new state was set. See the
\fIlibcurl-errors(3)\fP man page for the full list with descriptions.
.SH "SEE ALSO"
.BR curl_easy_cleanup "(3), " curl_easy_reset "(3)"
.BR curl_easy_cleanup "(3), " curl_easy_reset "(3), "
.BR CURLOPT_STREAM_WINDOW_SIZE "(3), " CURLMOPT_STREAM_WINDOW_SIZE "(3)"
2 changes: 2 additions & 0 deletions docs/libcurl/curl_easy_setopt.3
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ This HTTP/2 stream depends on another exclusively. See
\fICURLOPT_STREAM_DEPENDS_E(3)\fP
.IP CURLOPT_STREAM_WEIGHT
Set this HTTP/2 stream's weight. See \fICURLOPT_STREAM_WEIGHT(3)\fP
.IP CURLOPT_STREAM_WINDOW_SIZE
Set the HTTP/2 stream window size. See \fICURLMOPT_STREAM_WINDOW_SIZE(3)\fP
.SH SMTP OPTIONS
.IP CURLOPT_MAIL_FROM
Address of the sender. See \fICURLOPT_MAIL_FROM(3)\fP
Expand Down
2 changes: 2 additions & 0 deletions docs/libcurl/curl_multi_setopt.3
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ See \fICURLMOPT_PUSHDATA(3)\fP
See \fICURLMOPT_SOCKETFUNCTION(3)\fP
.IP CURLMOPT_SOCKETDATA
See \fICURLMOPT_SOCKETDATA(3)\fP
.IP CURLMOPT_STREAM_WINDOW_SIZE
See \fICURLMOPT_STREAM_WINDOW_SIZE(3)\fP
.IP CURLMOPT_TIMERFUNCTION
See \fICURLMOPT_TIMERFUNCTION(3)\fP
.IP CURLMOPT_TIMERDATA
Expand Down
60 changes: 60 additions & 0 deletions docs/libcurl/opts/CURLMOPT_STREAM_WINDOW_SIZE.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
.\" **************************************************************************
.\" * _ _ ____ _
.\" * Project ___| | | | _ \| |
.\" * / __| | | | |_) | |
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2021, Daniel Stenberg, <[email protected]>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
.\" * furnished to do so, under the terms of the COPYING file.
.\" *
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
.\" * KIND, either express or implied.
.\" *
.\" **************************************************************************
.\"
.TH CURLMOPT_STREAM_WINDOW_SIZE 3 "17 Nov 2021" "libcurl 7.81.0" "curl_multi_setopt options"
.SH NAME
CURLMOPT_STREAM_WINDOW_SIZE \- set stream window size for http2
.SH SYNOPSIS
.nf
#include <curl/curl.h>

CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_STREAM_WINDOW_SIZE,
long size);
.fi
.SH DESCRIPTION
Pass a long indicating the sender's HTTP/2 initial stream window \fBsize\fP in
bytes. This setting affects the initial window size of all streams. When using
\fIcurl_easy_pause(3)\fP , this value is also the maximum number of bytes libcurl
has to buffer for a paused stream.

This option is for the multi handle's use only. When using the easy interface,
you should instead use the \fICURLOPT_STREAM_WINDOW_SIZE(3)\fP option.

Valid values range from 1 to 2147483647 (0x7FFFFFFF).
.SH DEFAULT
33554432 (32 megabytes)
.SH PROTOCOLS
HTTP/2
.SH EXAMPLE
.nf
CURLM *m = curl_multi_init();
/* set stream window size to HTTP/2 default 2^16-1 */
curl_multi_setopt(m, CURLMOPT_STREAM_WINDOW_SIZE, 65535L);
.fi
.SH AVAILABILITY
Added in 7.81.0
.SH RETURN VALUE
Returns CURLM_OK of the option is supported and window size is within range,
CURLM_BAD_FUNCTION_ARGUMENT if not within range. Returns CURLM_UNKNOWN_OPTION
if the option is not supported.
.SH "SEE ALSO"
.BR curl_easy_pause "(3), " CURLOPT_STREAM_WINDOW_SIZE "(3)"
62 changes: 62 additions & 0 deletions docs/libcurl/opts/CURLOPT_STREAM_WINDOW_SIZE.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
.\" **************************************************************************
.\" * _ _ ____ _
.\" * Project ___| | | | _ \| |
.\" * / __| | | | |_) | |
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2021, Daniel Stenberg, <[email protected]>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
.\" * furnished to do so, under the terms of the COPYING file.
.\" *
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
.\" * KIND, either express or implied.
.\" *
.\" **************************************************************************
.\"
.TH CURLOPT_STREAM_WINDOW_SIZE 3 "17 Nov 2021" "libcurl 7.81.0" "curl_easy_setopt options"
.SH NAME
CURLOPT_STREAM_WINDOW_SIZE \- set stream window size for http2
.SH SYNOPSIS
.nf
#include <curl/curl.h>

CURLMcode curl_easy_setopt(CURL *handle, CURLOPT_STREAM_WINDOW_SIZE,
long size);
.fi
.SH DESCRIPTION
Pass a long indicating the sender's HTTP/2 initial stream window \fBsize\fP in
bytes. This setting affects the initial window size of all streams. When using
\fIcurl_easy_pause(3)\fP , this value is also the maximum number of bytes libcurl
has to buffer for a paused stream.

If you add this easy handle to a multi handle, this setting is not
acknowledged, and you must instead use \fIcurl_multi_setopt(3)\fP and the
\fICURLMOPT_STREAM_WINDOW_SIZE(3)\fP option.

Valid values range from 1 to 2147483647 (0x7FFFFFFF).
.SH DEFAULT
33554432 (32 megabytes)
.SH PROTOCOLS
HTTP/2
.SH EXAMPLE
.nf
CURL *curl = curl_easy_init();
/* set stream window size to HTTP/2 default 2^16-1 */
curl_easy_setopt(curl, CURLOPT_STREAM_WINDOW_SIZE, 65535L);
.fi
.SH AVAILABILITY
Added in 7.81.0
.SH RETURN VALUE

Returns CURLE_OK of the option is supported and window size is within range,
CURLE_BAD_FUNCTION_ARGUMENT if not within range. Returns CURLE_UNKNOWN_OPTION
if the option is not supported.
.SH "SEE ALSO"
.BR curl_easy_pause "(3), " CURLMOPT_STREAM_WINDOW_SIZE "(3)"
2 changes: 2 additions & 0 deletions docs/libcurl/opts/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ man_MANS = \
CURLMOPT_PUSHFUNCTION.3 \
CURLMOPT_SOCKETDATA.3 \
CURLMOPT_SOCKETFUNCTION.3 \
CURLMOPT_STREAM_WINDOW_SIZE.3 \
CURLMOPT_TIMERDATA.3 \
CURLMOPT_TIMERFUNCTION.3 \
CURLOPT_ABSTRACT_UNIX_SOCKET.3 \
Expand Down Expand Up @@ -361,6 +362,7 @@ man_MANS = \
CURLOPT_STREAM_DEPENDS.3 \
CURLOPT_STREAM_DEPENDS_E.3 \
CURLOPT_STREAM_WEIGHT.3 \
CURLOPT_STREAM_WINDOW_SIZE.3 \
CURLOPT_SUPPRESS_CONNECT_HEADERS.3 \
CURLOPT_TCP_FASTOPEN.3 \
CURLOPT_TCP_KEEPALIVE.3 \
Expand Down
2 changes: 2 additions & 0 deletions docs/libcurl/symbols-in-versions
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ CURLMOPT_PUSHDATA 7.44.0
CURLMOPT_PUSHFUNCTION 7.44.0
CURLMOPT_SOCKETDATA 7.15.4
CURLMOPT_SOCKETFUNCTION 7.15.4
CURLMOPT_STREAM_WINDOW_SIZE 7.81.0
CURLMOPT_TIMERDATA 7.16.0
CURLMOPT_TIMERFUNCTION 7.16.0
CURLMSG_DONE 7.9.6
Expand Down Expand Up @@ -651,6 +652,7 @@ CURLOPT_STDERR 7.1
CURLOPT_STREAM_DEPENDS 7.46.0
CURLOPT_STREAM_DEPENDS_E 7.46.0
CURLOPT_STREAM_WEIGHT 7.46.0
CURLOPT_STREAM_WINDOW_SIZE 7.81.0
CURLOPT_SUPPRESS_CONNECT_HEADERS 7.54.0
CURLOPT_TCP_FASTOPEN 7.49.0
CURLOPT_TCP_KEEPALIVE 7.25.0
Expand Down
3 changes: 3 additions & 0 deletions include/curl/curl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2135,6 +2135,9 @@ typedef enum {
/* Set MIME option flags. */
CURLOPT(CURLOPT_MIME_OPTIONS, CURLOPTTYPE_LONG, 315),

/* Stream window size */
CURLOPT(CURLOPT_STREAM_WINDOW_SIZE, CURLOPTTYPE_LONG, 316),

CURLOPT_LASTENTRY /* the last unused */
} CURLoption;

Expand Down
3 changes: 3 additions & 0 deletions include/curl/multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,9 @@ typedef enum {
/* maximum number of concurrent streams to support on a connection */
CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16),

/* stream window size (default 32M) */
CURLOPT(CURLMOPT_STREAM_WINDOW_SIZE, CURLOPTTYPE_LONG, 17),

CURLMOPT_LASTENTRY /* the last unused */
} CURLMoption;

Expand Down
4 changes: 4 additions & 0 deletions lib/easy.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,10 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events)
/* Copy the MAXCONNECTS option to the multi handle */
curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects);

/* Copy the STREAM_WINDOW_SIZE option to the multi handle */
curl_multi_setopt(multi, CURLMOPT_STREAM_WINDOW_SIZE,
data->set.stream_window_size);

mcode = curl_multi_add_handle(multi, data);
if(mcode) {
curl_multi_cleanup(multi);
Expand Down
3 changes: 2 additions & 1 deletion lib/easyoptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ struct curl_easyoption Curl_easyopts[] = {
{"STREAM_DEPENDS", CURLOPT_STREAM_DEPENDS, CURLOT_OBJECT, 0},
{"STREAM_DEPENDS_E", CURLOPT_STREAM_DEPENDS_E, CURLOT_OBJECT, 0},
{"STREAM_WEIGHT", CURLOPT_STREAM_WEIGHT, CURLOT_LONG, 0},
{"STREAM_WINDOW_SIZE", CURLOPT_STREAM_WINDOW_SIZE, CURLOT_LONG, 0},
{"SUPPRESS_CONNECT_HEADERS", CURLOPT_SUPPRESS_CONNECT_HEADERS,
CURLOT_LONG, 0},
{"TCP_FASTOPEN", CURLOPT_TCP_FASTOPEN, CURLOT_LONG, 0},
Expand Down Expand Up @@ -360,6 +361,6 @@ struct curl_easyoption Curl_easyopts[] = {
*/
int Curl_easyopts_check(void)
{
return ((CURLOPT_LASTENTRY%10000) != (315 + 1));
return ((CURLOPT_LASTENTRY%10000) != (316 + 1));
}
#endif
6 changes: 2 additions & 4 deletions lib/http2.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@
#define NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE 1
#endif

#define HTTP2_HUGE_WINDOW_SIZE (32 * 1024 * 1024) /* 32 MB */

#ifdef DEBUG_HTTP2
#define H2BUGF(x) x
#else
Expand Down Expand Up @@ -1194,7 +1192,7 @@ static void populate_settings(struct Curl_easy *data,
iv[0].value = Curl_multi_max_concurrent_streams(data->multi);

iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
iv[1].value = HTTP2_HUGE_WINDOW_SIZE;
iv[1].value = data->multi->stream_window_size;

iv[2].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
iv[2].value = data->multi->push_cb != NULL;
Expand Down Expand Up @@ -2375,7 +2373,7 @@ CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause)
else {
struct HTTP *stream = data->req.p.http;
struct http_conn *httpc = &data->conn->proto.httpc;
uint32_t window = !pause * HTTP2_HUGE_WINDOW_SIZE;
uint32_t window = !pause * data->multi->stream_window_size;
int rv = nghttp2_session_set_local_window_size(httpc->h2,
NGHTTP2_FLAG_NONE,
stream->stream_id,
Expand Down
2 changes: 2 additions & 0 deletions lib/http2.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
from the peer */
#define DEFAULT_MAX_CONCURRENT_STREAMS 100

#define HTTP2_HUGE_WINDOW_SIZE (32 * 1024 * 1024) /* 32 MB */

/*
* Store nghttp2 version info in this buffer.
*/
Expand Down
13 changes: 13 additions & 0 deletions lib/multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,9 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
/* -1 means it not set by user, use the default value */
multi->maxconnects = -1;
multi->max_concurrent_streams = 100;
#ifdef USE_NGHTTP2
multi->stream_window_size = HTTP2_HUGE_WINDOW_SIZE;
#endif
multi->ipv6_works = Curl_ipv6works(NULL);

#ifdef USE_WINSOCK
Expand Down Expand Up @@ -3154,6 +3157,16 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi,
multi->max_concurrent_streams = curlx_sltoui(streams);
}
break;
case CURLMOPT_STREAM_WINDOW_SIZE:
{
long stream_window_size = va_arg(param, long);
if((stream_window_size > 0) &&
((unsigned long)stream_window_size <= 0x7FFFFFFF))
multi->stream_window_size = curlx_sltoui(stream_window_size);
else
return CURLM_BAD_FUNCTION_ARGUMENT;
}
break;
default:
res = CURLM_UNKNOWN_OPTION;
break;
Expand Down
1 change: 1 addition & 0 deletions lib/multihandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ struct Curl_multi {
struct curltime timer_lastcall; /* the fixed time for the timeout for the
previous callback */
unsigned int max_concurrent_streams;
unsigned int stream_window_size;

#ifdef USE_WINSOCK
WSAEVENT wsa_event; /* winsock event used for waits */
Expand Down
10 changes: 10 additions & 0 deletions lib/setopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3036,6 +3036,16 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
case CURLOPT_PREREQDATA:
data->set.prereq_userp = va_arg(param, void *);
break;
case CURLOPT_STREAM_WINDOW_SIZE:
{
long stream_window_size = va_arg(param, long);
if((stream_window_size > 0) &&
((unsigned long)stream_window_size <= 0x7FFFFFFF))
data->set.stream_window_size = curlx_sltoui(stream_window_size);
else
return CURLE_BAD_FUNCTION_ARGUMENT;
}
break;
default:
/* unknown tag and its companion, just ignore: */
result = CURLE_UNKNOWN_OPTION;
Expand Down
3 changes: 3 additions & 0 deletions lib/url.c
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,9 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
set->fnmatch = ZERO_NULL;
set->upkeep_interval_ms = CURL_UPKEEP_INTERVAL_DEFAULT;
set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
#ifdef USE_NGHTTP2
set->stream_window_size = HTTP2_HUGE_WINDOW_SIZE; /* for easy handles */
#endif
set->maxage_conn = 118;
set->maxlifetime_conn = 0;
set->http09_allowed = FALSE;
Expand Down
1 change: 1 addition & 0 deletions lib/urldata.h
Original file line number Diff line number Diff line change
Expand Up @@ -1775,6 +1775,7 @@ struct UserDefined {
struct Curl_easy *stream_depends_on;
int stream_weight;
struct Curl_http2_dep *stream_dependents;
unsigned int stream_window_size;

curl_resolver_start_callback resolver_start; /* optional callback called
before resolver start */
Expand Down