Remove flow control disabling feature

This commit is contained in:
Tatsuhiro Tsujikawa 2014-02-06 00:23:20 +09:00
parent 196406da0e
commit c79adf6997
17 changed files with 63 additions and 405 deletions

View File

@ -425,14 +425,10 @@ typedef enum {
* SETTINGS_INITIAL_WINDOW_SIZE * SETTINGS_INITIAL_WINDOW_SIZE
*/ */
NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 7, NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 7,
/**
* SETTINGS_FLOW_CONTROL_OPTIONS
*/
NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS = 10,
/** /**
* Maximum ID of :type:`nghttp2_settings_id`. * Maximum ID of :type:`nghttp2_settings_id`.
*/ */
NGHTTP2_SETTINGS_MAX = 10 NGHTTP2_SETTINGS_MAX = 7
} nghttp2_settings_id; } nghttp2_settings_id;
/** /**
@ -1623,9 +1619,6 @@ size_t nghttp2_session_get_outbound_queue_size(nghttp2_session *session);
* window_size_increment with `nghttp2_submit_window_update()`, this * window_size_increment with `nghttp2_submit_window_update()`, this
* function returns the number of bytes less than actually received. * function returns the number of bytes less than actually received.
* *
* If flow control is disabled for that stream, this function returns
* 0.
*
* This function returns -1 if it fails. * This function returns -1 if it fails.
*/ */
int32_t nghttp2_session_get_stream_effective_recv_data_length int32_t nghttp2_session_get_stream_effective_recv_data_length
@ -1656,9 +1649,6 @@ int32_t nghttp2_session_get_stream_effective_local_window_size
* with `nghttp2_submit_window_update()`, this function returns the * with `nghttp2_submit_window_update()`, this function returns the
* number of bytes less than actually received. * number of bytes less than actually received.
* *
* If flow control is disabled for a connection, this function returns
* 0.
*
* This function returns -1 if it fails. * This function returns -1 if it fails.
*/ */
int32_t nghttp2_session_get_effective_recv_data_length int32_t nghttp2_session_get_effective_recv_data_length
@ -2021,8 +2011,8 @@ int nghttp2_submit_rst_stream(nghttp2_session *session, uint8_t flags,
* negative error codes: * negative error codes:
* *
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
* The |iv| contains invalid value (e.g., attempting to re-enable * The |iv| contains invalid value (e.g., initial window size
* flow control). * strictly greater than (1 << 31) - 1.
* :enum:`NGHTTP2_ERR_NOMEM` * :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory. * Out of memory.
*/ */

View File

@ -617,8 +617,7 @@ ssize_t nghttp2_nv_array_copy(nghttp2_nv **nva_ptr,
return nvlen; return nvlen;
} }
int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv, int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv)
int32_t flow_control_opt)
{ {
size_t i; size_t i;
for(i = 0; i < niv; ++i) { for(i = 0; i < niv; ++i) {
@ -628,15 +627,6 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv,
return 0; return 0;
} }
break; break;
case NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS:
if(flow_control_opt) {
if((iv[i].value & 0x1) == 0) {
/* Attempt to re-enabling flow-control is error */
return 0;
}
} else {
flow_control_opt = iv[i].value & 0x1;
}
default: default:
break; break;
} }

View File

@ -472,12 +472,10 @@ void nghttp2_nv_array_del(nghttp2_nv *nva);
/* /*
* Checks that the |iv|, which includes |niv| entries, does not have * Checks that the |iv|, which includes |niv| entries, does not have
* invalid values. The |flow_control_opt| is current flow control * invalid values.
* option value.
* *
* This function returns nonzero if it succeeds, or 0. * This function returns nonzero if it succeeds, or 0.
*/ */
int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv, int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv);
int32_t flow_control_opt);
#endif /* NGHTTP2_FRAME_H */ #endif /* NGHTTP2_FRAME_H */

View File

@ -186,7 +186,6 @@ static void init_settings(uint32_t *settings)
NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS; NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS;
settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] = settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] =
NGHTTP2_INITIAL_WINDOW_SIZE; NGHTTP2_INITIAL_WINDOW_SIZE;
settings[NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS] = 0;
} }
typedef struct { typedef struct {
@ -225,8 +224,6 @@ static int nghttp2_session_new(nghttp2_session **session_ptr,
NGHTTP2_OPTMASK_NO_AUTO_CONNECTION_WINDOW_UPDATE; NGHTTP2_OPTMASK_NO_AUTO_CONNECTION_WINDOW_UPDATE;
} }
(*session_ptr)->remote_flow_control = 1;
(*session_ptr)->local_flow_control = 1;
(*session_ptr)->remote_window_size = NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE; (*session_ptr)->remote_window_size = NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
(*session_ptr)->recv_window_size = 0; (*session_ptr)->recv_window_size = 0;
(*session_ptr)->recv_reduction = 0; (*session_ptr)->recv_reduction = 0;
@ -585,10 +582,6 @@ nghttp2_stream* nghttp2_session_open_stream(nghttp2_session *session,
return NULL; return NULL;
} }
nghttp2_stream_init(stream, stream_id, flags, pri, initial_state, nghttp2_stream_init(stream, stream_id, flags, pri, initial_state,
!session->remote_settings
[NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS],
!session->local_settings
[NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS],
session->remote_settings session->remote_settings
[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE], [NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE],
session->local_settings session->local_settings
@ -1016,12 +1009,8 @@ static size_t nghttp2_session_next_data_read(nghttp2_session *session,
{ {
int32_t window_size = NGHTTP2_DATA_PAYLOAD_LENGTH; int32_t window_size = NGHTTP2_DATA_PAYLOAD_LENGTH;
/* Take into account both connection-level flow control here */ /* Take into account both connection-level flow control here */
if(session->remote_flow_control) { window_size = nghttp2_min(window_size, session->remote_window_size);
window_size = nghttp2_min(window_size, session->remote_window_size); window_size = nghttp2_min(window_size, stream->remote_window_size);
}
if(stream->remote_flow_control) {
window_size = nghttp2_min(window_size, stream->remote_window_size);
}
if(window_size > 0) { if(window_size > 0) {
return window_size; return window_size;
} }
@ -1786,12 +1775,10 @@ int nghttp2_session_send(nghttp2_session *session)
} }
frame = nghttp2_outbound_item_get_data_frame(session->aob.item); frame = nghttp2_outbound_item_get_data_frame(session->aob.item);
stream = nghttp2_session_get_stream(session, frame->hd.stream_id); stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
if(stream && stream->remote_flow_control) { if(stream) {
stream->remote_window_size -= len; stream->remote_window_size -= len;
} }
if(session->remote_flow_control) { session->remote_window_size -= len;
session->remote_window_size -= len;
}
} }
session->aob.framebufoff += sentlen; session->aob.framebufoff += sentlen;
if(session->aob.framebufoff == session->aob.framebufmark) { if(session->aob.framebufoff == session->aob.framebufmark) {
@ -2506,8 +2493,7 @@ static int nghttp2_update_remote_initial_window_size_func
if(stream->deferred_data && if(stream->deferred_data &&
(stream->deferred_flags & NGHTTP2_DEFERRED_FLOW_CONTROL) && (stream->deferred_flags & NGHTTP2_DEFERRED_FLOW_CONTROL) &&
stream->remote_window_size > 0 && stream->remote_window_size > 0 &&
(arg->session->remote_flow_control == 0 || arg->session->remote_window_size > 0) {
arg->session->remote_window_size > 0)) {
rv = nghttp2_pq_push(&arg->session->ob_pq, stream->deferred_data); rv = nghttp2_pq_push(&arg->session->ob_pq, stream->deferred_data);
if(rv != 0) { if(rv != 0) {
/* FATAL */ /* FATAL */
@ -2552,9 +2538,6 @@ static int nghttp2_update_local_initial_window_size_func
nghttp2_stream *stream; nghttp2_stream *stream;
arg = (nghttp2_update_window_size_arg*)ptr; arg = (nghttp2_update_window_size_arg*)ptr;
stream = (nghttp2_stream*)entry; stream = (nghttp2_stream*)entry;
if(!stream->local_flow_control) {
return 0;
}
rv = nghttp2_stream_update_local_initial_window_size(stream, rv = nghttp2_stream_update_local_initial_window_size(stream,
arg->new_window_size, arg->new_window_size,
arg->old_window_size); arg->old_window_size);
@ -2603,70 +2586,6 @@ static int nghttp2_session_update_local_initial_window_size
&arg); &arg);
} }
static int nghttp2_disable_remote_flow_control_func(nghttp2_map_entry *entry,
void *ptr)
{
nghttp2_session *session;
nghttp2_stream *stream;
session = (nghttp2_session*)ptr;
stream = (nghttp2_stream*)entry;
stream->remote_flow_control = 0;
/* If DATA frame is deferred due to flow control, push it back to
outbound queue. */
if(stream->deferred_data &&
(stream->deferred_flags & NGHTTP2_DEFERRED_FLOW_CONTROL)) {
int rv;
rv = nghttp2_pq_push(&session->ob_pq, stream->deferred_data);
if(rv == 0) {
nghttp2_stream_detach_deferred_data(stream);
} else {
/* FATAL */
assert(rv < NGHTTP2_ERR_FATAL);
return rv;
}
}
return 0;
}
/*
* Disable remote side connection-level flow control and stream-level
* flow control of existing streams.
*
* This function returns 0 if it succeeds, or one of negative error codes.
*
* The error code is always FATAL.
*/
static int nghttp2_session_disable_remote_flow_control
(nghttp2_session *session)
{
session->remote_flow_control = 0;
return nghttp2_map_each(&session->streams,
nghttp2_disable_remote_flow_control_func, session);
}
static int nghttp2_disable_local_flow_control_func(nghttp2_map_entry *entry,
void *ptr)
{
nghttp2_stream *stream;
stream = (nghttp2_stream*)entry;
stream->local_flow_control = 0;
return 0;
}
/*
* Disable stream-level flow control in local side of existing
* streams.
*/
static void nghttp2_session_disable_local_flow_control
(nghttp2_session *session)
{
int rv;
session->local_flow_control = 0;
rv = nghttp2_map_each(&session->streams,
nghttp2_disable_local_flow_control_func, NULL);
assert(rv == 0);
}
/* /*
* Apply SETTINGS values |iv| having |niv| elements to the local * Apply SETTINGS values |iv| having |niv| elements to the local
* settings. SETTINGS_MAX_CONCURRENT_STREAMS is not applied here * settings. SETTINGS_MAX_CONCURRENT_STREAMS is not applied here
@ -2687,9 +2606,6 @@ int nghttp2_session_update_local_settings(nghttp2_session *session,
{ {
int rv; int rv;
size_t i; size_t i;
uint8_t old_flow_control =
session->local_settings[NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS];
uint8_t new_flow_control = old_flow_control;
int32_t new_initial_window_size = -1; int32_t new_initial_window_size = -1;
int32_t header_table_size = -1; int32_t header_table_size = -1;
uint8_t header_table_size_seen = 0; uint8_t header_table_size_seen = 0;
@ -2703,9 +2619,6 @@ int nghttp2_session_update_local_settings(nghttp2_session *session,
case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
new_initial_window_size = iv[i].value; new_initial_window_size = iv[i].value;
break; break;
case NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS:
new_flow_control = iv[i].value;
break;
} }
} }
if(header_table_size_seen) { if(header_table_size_seen) {
@ -2719,7 +2632,7 @@ int nghttp2_session_update_local_settings(nghttp2_session *session,
return rv; return rv;
} }
} }
if(!old_flow_control && !new_flow_control && new_initial_window_size != -1) { if(new_initial_window_size != -1) {
rv = nghttp2_session_update_local_initial_window_size rv = nghttp2_session_update_local_initial_window_size
(session, (session,
new_initial_window_size, new_initial_window_size,
@ -2736,10 +2649,6 @@ int nghttp2_session_update_local_settings(nghttp2_session *session,
session->local_settings[iv[i].settings_id] = iv[i].value; session->local_settings[iv[i].settings_id] = iv[i].value;
} }
} }
if(old_flow_control == 0 &&
session->local_settings[NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS]) {
nghttp2_session_disable_local_flow_control(session);
}
return 0; return 0;
} }
@ -2830,23 +2739,6 @@ int nghttp2_session_on_settings_received(nghttp2_session *session,
(session, frame, NGHTTP2_PROTOCOL_ERROR); (session, frame, NGHTTP2_PROTOCOL_ERROR);
} }
break; break;
case NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS:
if(entry->value & 0x1) {
if(session->remote_settings[entry->settings_id] == 0) {
rv = nghttp2_session_disable_remote_flow_control(session);
if(rv != 0) {
/* FATAL */
assert(rv < NGHTTP2_ERR_FATAL);
return rv;
}
}
} else if(session->remote_settings[entry->settings_id] == 1) {
/* Re-enabling flow control is subject to connection-level
error(?) */
return nghttp2_session_handle_invalid_connection
(session, frame, NGHTTP2_FLOW_CONTROL_ERROR);
}
break;
} }
session->remote_settings[entry->settings_id] = entry->value; session->remote_settings[entry->settings_id] = entry->value;
} }
@ -3035,7 +2927,7 @@ static int nghttp2_push_back_deferred_data_func(nghttp2_map_entry *entry,
outbound queue. */ outbound queue. */
if(stream->deferred_data && if(stream->deferred_data &&
(stream->deferred_flags & NGHTTP2_DEFERRED_FLOW_CONTROL) && (stream->deferred_flags & NGHTTP2_DEFERRED_FLOW_CONTROL) &&
(stream->remote_flow_control == 0 || stream->remote_window_size > 0)) { stream->remote_window_size > 0) {
int rv; int rv;
rv = nghttp2_pq_push(&session->ob_pq, stream->deferred_data); rv = nghttp2_pq_push(&session->ob_pq, stream->deferred_data);
if(rv == 0) { if(rv == 0) {
@ -3064,13 +2956,6 @@ static int session_on_connection_window_update_received
{ {
int rv; int rv;
/* Handle connection-level flow control */ /* Handle connection-level flow control */
if(session->remote_flow_control == 0) {
/* Disabling flow control by sending SETTINGS and receiving
WINDOW_UPDATE are asynchronous, so it is hard to determine
that the peer is misbehaving or not without measuring
RTT. For now, we just ignore such frames. */
return nghttp2_session_call_on_frame_received(session, frame);
}
if(NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment < if(NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment <
session->remote_window_size) { session->remote_window_size) {
return nghttp2_session_handle_invalid_connection return nghttp2_session_handle_invalid_connection
@ -3107,10 +2992,6 @@ static int session_on_stream_window_update_received
return nghttp2_session_handle_invalid_connection return nghttp2_session_handle_invalid_connection
(session, frame, NGHTTP2_PROTOCOL_ERROR); (session, frame, NGHTTP2_PROTOCOL_ERROR);
} }
if(stream->remote_flow_control == 0) {
/* Same reason with connection-level flow control */
return nghttp2_session_call_on_frame_received(session, frame);
}
if(NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment < if(NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment <
stream->remote_window_size) { stream->remote_window_size) {
return nghttp2_session_handle_invalid_stream(session, frame, return nghttp2_session_handle_invalid_stream(session, frame,
@ -3118,8 +2999,7 @@ static int session_on_stream_window_update_received
} }
stream->remote_window_size += frame->window_update.window_size_increment; stream->remote_window_size += frame->window_update.window_size_increment;
if(stream->remote_window_size > 0 && if(stream->remote_window_size > 0 &&
(session->remote_flow_control == 0 || session->remote_window_size > 0 &&
session->remote_window_size > 0) &&
stream->deferred_data != NULL && stream->deferred_data != NULL &&
(stream->deferred_flags & NGHTTP2_DEFERRED_FLOW_CONTROL)) { (stream->deferred_flags & NGHTTP2_DEFERRED_FLOW_CONTROL)) {
rv = nghttp2_pq_push(&session->ob_pq, stream->deferred_data); rv = nghttp2_pq_push(&session->ob_pq, stream->deferred_data);
@ -3411,7 +3291,6 @@ static int inbound_frame_set_settings_entry(nghttp2_inbound_frame *iframe)
case NGHTTP2_SETTINGS_ENABLE_PUSH: case NGHTTP2_SETTINGS_ENABLE_PUSH:
case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS:
case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
case NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS:
break; break;
default: default:
return -1; return -1;
@ -3822,23 +3701,21 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
DEBUGF(fprintf(stderr, "readlen=%zu, payloadleft=%zu\n", DEBUGF(fprintf(stderr, "readlen=%zu, payloadleft=%zu\n",
readlen, iframe->payloadleft)); readlen, iframe->payloadleft));
if(readlen > 0) { if(readlen > 0) {
if(session->local_flow_control) { rv = nghttp2_session_update_recv_connection_window_size
rv = nghttp2_session_update_recv_connection_window_size (session, readlen);
(session, readlen); if(nghttp2_is_fatal(rv)) {
if(nghttp2_is_fatal(rv)) { return rv;
return rv; }
} if(iframe->payloadleft ||
if(iframe->payloadleft || (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
(iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) { nghttp2_stream *stream;
nghttp2_stream *stream; stream = nghttp2_session_get_stream(session,
stream = nghttp2_session_get_stream(session, iframe->frame.hd.stream_id);
iframe->frame.hd.stream_id); if(stream) {
if(stream && stream->local_flow_control) { rv = nghttp2_session_update_recv_stream_window_size
rv = nghttp2_session_update_recv_stream_window_size (session, stream, readlen);
(session, stream, readlen); if(nghttp2_is_fatal(rv)) {
if(nghttp2_is_fatal(rv)) { return rv;
return rv;
}
} }
} }
} }
@ -3875,7 +3752,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
readlen = inbound_frame_payload_readlen(iframe, in, last); readlen = inbound_frame_payload_readlen(iframe, in, last);
iframe->payloadleft -= readlen; iframe->payloadleft -= readlen;
in += readlen; in += readlen;
if(readlen > 0 && session->local_flow_control) { if(readlen > 0) {
/* Update connection-level flow control window for ignored /* Update connection-level flow control window for ignored
DATA frame too */ DATA frame too */
rv = nghttp2_session_update_recv_connection_window_size rv = nghttp2_session_update_recv_connection_window_size
@ -4033,9 +3910,7 @@ int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags,
nghttp2_frame *frame; nghttp2_frame *frame;
nghttp2_settings_entry *iv_copy; nghttp2_settings_entry *iv_copy;
int r; int r;
if(!nghttp2_iv_check(iv, niv, if(!nghttp2_iv_check(iv, niv)) {
session->local_settings
[NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS])) {
return NGHTTP2_ERR_INVALID_ARGUMENT; return NGHTTP2_ERR_INVALID_ARGUMENT;
} }
frame = malloc(sizeof(nghttp2_frame)); frame = malloc(sizeof(nghttp2_frame));
@ -4149,9 +4024,6 @@ int32_t nghttp2_session_get_stream_effective_recv_data_length
if(stream == NULL) { if(stream == NULL) {
return -1; return -1;
} }
if(stream->local_flow_control == 0) {
return 0;
}
return stream->recv_window_size < 0 ? 0 : stream->recv_window_size; return stream->recv_window_size < 0 ? 0 : stream->recv_window_size;
} }
@ -4169,9 +4041,6 @@ int32_t nghttp2_session_get_stream_effective_local_window_size
int32_t nghttp2_session_get_effective_recv_data_length int32_t nghttp2_session_get_effective_recv_data_length
(nghttp2_session *session) (nghttp2_session *session)
{ {
if(session->local_flow_control == 0) {
return 0;
}
return session->recv_window_size < 0 ? 0 : session->recv_window_size; return session->recv_window_size < 0 ? 0 : session->recv_window_size;
} }

View File

@ -189,14 +189,6 @@ struct nghttp2_session {
/* Flags indicating GOAWAY is sent and/or recieved. The flags are /* Flags indicating GOAWAY is sent and/or recieved. The flags are
composed by bitwise OR-ing nghttp2_goaway_flag. */ composed by bitwise OR-ing nghttp2_goaway_flag. */
uint8_t goaway_flags; uint8_t goaway_flags;
/* Non-zero indicates connection-level flow control on remote side
is in effect. This will be disabled when WINDOW_UPDATE with
END_FLOW_CONTROL bit set is received. */
uint8_t remote_flow_control;
/* Non-zero indicates connection-level flow control on local side is
in effect. This will be disabled when WINDOW_UPDATE with
END_FLOW_CONTROL bit set is sent. */
uint8_t local_flow_control;
}; };
/* Struct used when updating initial window size of each active /* Struct used when updating initial window size of each active

View File

@ -29,8 +29,6 @@
void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id, void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
uint8_t flags, int32_t pri, uint8_t flags, int32_t pri,
nghttp2_stream_state initial_state, nghttp2_stream_state initial_state,
uint8_t remote_flow_control,
uint8_t local_flow_control,
int32_t remote_initial_window_size, int32_t remote_initial_window_size,
int32_t local_initial_window_size, int32_t local_initial_window_size,
void *stream_user_data) void *stream_user_data)
@ -44,8 +42,6 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
stream->stream_user_data = stream_user_data; stream->stream_user_data = stream_user_data;
stream->deferred_data = NULL; stream->deferred_data = NULL;
stream->deferred_flags = NGHTTP2_DEFERRED_NONE; stream->deferred_flags = NGHTTP2_DEFERRED_NONE;
stream->remote_flow_control = remote_flow_control;
stream->local_flow_control = local_flow_control;
stream->remote_window_size = remote_initial_window_size; stream->remote_window_size = remote_initial_window_size;
stream->local_window_size = local_initial_window_size; stream->local_window_size = local_initial_window_size;
stream->recv_window_size = 0; stream->recv_window_size = 0;

View File

@ -117,25 +117,11 @@ typedef struct {
/* The flags for defered DATA. Bitwise OR of zero or more /* The flags for defered DATA. Bitwise OR of zero or more
nghttp2_deferred_flag values */ nghttp2_deferred_flag values */
uint8_t deferred_flags; uint8_t deferred_flags;
/* Flag to indicate whether the remote side has flow control
enabled. If it is enabled, we have to enforces flow control to
send data to the other side. This could be disabled when
receiving SETTINGS with flow control options off or receiving
WINDOW_UPDATE with END_FLOW_CONTROL bit set. */
uint8_t remote_flow_control;
/* Flag to indicate whether the local side has flow control
enabled. If it is enabled, the received data are subject to the
flow control. This could be disabled by sending SETTINGS with
flow control options off or sending WINDOW_UPDATE with
END_FLOW_CONTROL bit set. */
uint8_t local_flow_control;
} nghttp2_stream; } nghttp2_stream;
void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id, void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
uint8_t flags, int32_t pri, uint8_t flags, int32_t pri,
nghttp2_stream_state initial_state, nghttp2_stream_state initial_state,
uint8_t remote_flow_control,
uint8_t local_flow_control,
int32_t remote_initial_window_size, int32_t remote_initial_window_size,
int32_t local_initial_window_size, int32_t local_initial_window_size,
void *stream_user_data); void *stream_user_data);

View File

@ -219,9 +219,6 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
} }
flags = 0; flags = 0;
if(stream_id == 0) { if(stream_id == 0) {
if(!session->local_flow_control) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
rv = nghttp2_adjust_local_window_size(&session->local_window_size, rv = nghttp2_adjust_local_window_size(&session->local_window_size,
&session->recv_window_size, &session->recv_window_size,
&session->recv_reduction, &session->recv_reduction,
@ -232,9 +229,6 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
} else { } else {
stream = nghttp2_session_get_stream(session, stream_id); stream = nghttp2_session_get_stream(session, stream_id);
if(stream) { if(stream) {
if(!stream->local_flow_control) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
rv = nghttp2_adjust_local_window_size(&stream->local_window_size, rv = nghttp2_adjust_local_window_size(&stream->local_window_size,
&stream->recv_window_size, &stream->recv_window_size,
&stream->recv_reduction, &stream->recv_reduction,
@ -325,9 +319,7 @@ ssize_t nghttp2_pack_settings_payload(uint8_t *buf,
const nghttp2_settings_entry *iv, const nghttp2_settings_entry *iv,
size_t niv) size_t niv)
{ {
/* Assume that current flow_control_option is 0 (which means that if(!nghttp2_iv_check(iv, niv)) {
flow control is enabled) */
if(!nghttp2_iv_check(iv, niv, 0)) {
return NGHTTP2_ERR_INVALID_ARGUMENT; return NGHTTP2_ERR_INVALID_ARGUMENT;
} }

View File

@ -71,8 +71,7 @@ Config::Config()
verbose(false), verbose(false),
daemon(false), daemon(false),
verify_client(false), verify_client(false),
no_tls(false), no_tls(false)
no_flow_control(false)
{} {}
Request::Request(int32_t stream_id) Request::Request(int32_t stream_id)
@ -373,11 +372,6 @@ int Http2Handler::on_connect()
entry[0].value = 100; entry[0].value = 100;
entry[1].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH; entry[1].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
entry[1].value = 0; entry[1].value = 0;
if(sessions_->get_config()->no_flow_control) {
entry[niv].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS;
entry[niv].value = 1;
++niv;
}
if(sessions_->get_config()->header_table_size >= 0) { if(sessions_->get_config()->header_table_size >= 0) {
entry[niv].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE; entry[niv].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
entry[niv].value = sessions_->get_config()->header_table_size; entry[niv].value = sessions_->get_config()->header_table_size;

View File

@ -62,7 +62,6 @@ struct Config {
bool daemon; bool daemon;
bool verify_client; bool verify_client;
bool no_tls; bool no_tls;
bool no_flow_control;
Config(); Config();
}; };

View File

@ -95,8 +95,6 @@ const char* strsettingsid(int32_t id)
return "SETTINGS_MAX_CONCURRENT_STREAMS"; return "SETTINGS_MAX_CONCURRENT_STREAMS";
case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
return "SETTINGS_INITIAL_WINDOW_SIZE"; return "SETTINGS_INITIAL_WINDOW_SIZE";
case NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS:
return "SETTINGS_FLOW_CONTROL_OPTIONS";
default: default:
return "UNKNOWN"; return "UNKNOWN";
} }

View File

@ -95,7 +95,6 @@ struct Config {
bool verbose; bool verbose;
bool get_assets; bool get_assets;
bool stat; bool stat;
bool no_flow_control;
bool upgrade; bool upgrade;
Config() Config()
: output_upper_thres(1024*1024), : output_upper_thres(1024*1024),
@ -111,7 +110,6 @@ struct Config {
verbose(false), verbose(false),
get_assets(false), get_assets(false),
stat(false), stat(false),
no_flow_control(false),
upgrade(false) upgrade(false)
{} {}
}; };
@ -366,11 +364,6 @@ size_t populate_settings(nghttp2_settings_entry *iv)
} else { } else {
iv[1].value = NGHTTP2_INITIAL_WINDOW_SIZE; iv[1].value = NGHTTP2_INITIAL_WINDOW_SIZE;
} }
if(config.no_flow_control) {
iv[niv].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS;
iv[niv].value = 1;
++niv;
}
if(config.header_table_size >= 0) { if(config.header_table_size >= 0) {
iv[niv].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE; iv[niv].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
iv[niv].value = config.header_table_size; iv[niv].value = config.header_table_size;
@ -1642,7 +1635,7 @@ int run(char **uris, int n)
namespace { namespace {
void print_usage(std::ostream& out) void print_usage(std::ostream& out)
{ {
out << "Usage: nghttp [-Oafnsuv] [-t <SECONDS>] [-w <WINDOW_BITS>] [-W <WINDOW_BITS>]\n" out << "Usage: nghttp [-Oansuv] [-t <SECONDS>] [-w <WINDOW_BITS>] [-W <WINDOW_BITS>]\n"
<< " [--cert=<CERT>] [--key=<KEY>] [-d <FILE>] [-m <N>]\n" << " [--cert=<CERT>] [--key=<KEY>] [-d <FILE>] [-m <N>]\n"
<< " [-p <PRIORITY>] [-M <N>]\n" << " [-p <PRIORITY>] [-M <N>]\n"
<< " <URI>..." << " <URI>..."
@ -1686,9 +1679,6 @@ void print_help(std::ostream& out)
<< " -m, --multiply=<N> Request each URI <N> times. By default, same\n" << " -m, --multiply=<N> Request each URI <N> times. By default, same\n"
<< " URI is not requested twice. This option\n" << " URI is not requested twice. This option\n"
<< " disables it too.\n" << " disables it too.\n"
<< " -f, --no-flow-control\n"
<< " Disables connection and stream level flow\n"
<< " controls.\n"
<< " -u, --upgrade Perform HTTP Upgrade for HTTP/2.0. This\n" << " -u, --upgrade Perform HTTP Upgrade for HTTP/2.0. This\n"
<< " option is ignored if the request URI has\n" << " option is ignored if the request URI has\n"
<< " https scheme.\n" << " https scheme.\n"
@ -1727,7 +1717,6 @@ int main(int argc, char **argv)
{"header", required_argument, nullptr, 'H'}, {"header", required_argument, nullptr, 'H'},
{"data", required_argument, nullptr, 'd'}, {"data", required_argument, nullptr, 'd'},
{"multiply", required_argument, nullptr, 'm'}, {"multiply", required_argument, nullptr, 'm'},
{"no-flow-control", no_argument, nullptr, 'f'},
{"upgrade", no_argument, nullptr, 'u'}, {"upgrade", no_argument, nullptr, 'u'},
{"pri", required_argument, nullptr, 'p'}, {"pri", required_argument, nullptr, 'p'},
{"peer-max-concurrent-streams", required_argument, nullptr, 'M'}, {"peer-max-concurrent-streams", required_argument, nullptr, 'M'},
@ -1738,7 +1727,7 @@ int main(int argc, char **argv)
{nullptr, 0, nullptr, 0 } {nullptr, 0, nullptr, 0 }
}; };
int option_index = 0; int option_index = 0;
int c = getopt_long(argc, argv, "M:Oac:d:fm:np:hH:vst:uw:W:", long_options, int c = getopt_long(argc, argv, "M:Oac:d:m:np:hH:vst:uw:W:", long_options,
&option_index); &option_index);
char *end; char *end;
if(c == -1) { if(c == -1) {
@ -1752,9 +1741,6 @@ int main(int argc, char **argv)
case 'O': case 'O':
config.remote_name = true; config.remote_name = true;
break; break;
case 'f':
config.no_flow_control = true;
break;
case 'h': case 'h':
print_help(std::cout); print_help(std::cout);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);

View File

@ -75,7 +75,7 @@ int parse_push_config(Config& config, const char *optarg)
namespace { namespace {
void print_usage(std::ostream& out) void print_usage(std::ostream& out)
{ {
out << "Usage: nghttpd [-DVfhv] [-d <PATH>] [--no-tls] <PORT> [<PRIVATE_KEY> <CERT>]" out << "Usage: nghttpd [-DVhv] [-d <PATH>] [--no-tls] <PORT> [<PRIVATE_KEY> <CERT>]"
<< std::endl; << std::endl;
} }
} // namespace } // namespace
@ -103,9 +103,6 @@ void print_help(std::ostream& out)
<< " -v, --verbose Print debug information such as reception/\n" << " -v, --verbose Print debug information such as reception/\n"
<< " transmission of frames and name/value pairs.\n" << " transmission of frames and name/value pairs.\n"
<< " --no-tls Disable SSL/TLS.\n" << " --no-tls Disable SSL/TLS.\n"
<< " -f, --no-flow-control\n"
<< " Disables connection and stream level flow\n"
<< " controls.\n"
<< " -c, --header-table-size=<N>\n" << " -c, --header-table-size=<N>\n"
<< " Specify decoder header table size.\n" << " Specify decoder header table size.\n"
<< " --color Force colored log output.\n" << " --color Force colored log output.\n"
@ -134,7 +131,6 @@ int main(int argc, char **argv)
{"help", no_argument, nullptr, 'h'}, {"help", no_argument, nullptr, 'h'},
{"verbose", no_argument, nullptr, 'v'}, {"verbose", no_argument, nullptr, 'v'},
{"verify-client", no_argument, nullptr, 'V'}, {"verify-client", no_argument, nullptr, 'V'},
{"no-flow-control", no_argument, nullptr, 'f'},
{"header-table-size", required_argument, nullptr, 'c'}, {"header-table-size", required_argument, nullptr, 'c'},
{"push", required_argument, nullptr, 'p'}, {"push", required_argument, nullptr, 'p'},
{"no-tls", no_argument, &flag, 1}, {"no-tls", no_argument, &flag, 1},
@ -142,7 +138,7 @@ int main(int argc, char **argv)
{nullptr, 0, nullptr, 0} {nullptr, 0, nullptr, 0}
}; };
int option_index = 0; int option_index = 0;
int c = getopt_long(argc, argv, "DVc:d:fhp:v", long_options, &option_index); int c = getopt_long(argc, argv, "DVc:d:hp:v", long_options, &option_index);
char *end; char *end;
if(c == -1) { if(c == -1) {
break; break;
@ -157,9 +153,6 @@ int main(int argc, char **argv)
case 'd': case 'd':
config.htdocs = optarg; config.htdocs = optarg;
break; break;
case 'f':
config.no_flow_control = true;
break;
case 'h': case 'h':
print_help(std::cout); print_help(std::cout);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);

View File

@ -177,10 +177,6 @@ int main(int argc, char* argv[])
test_nghttp2_session_defer_data) || test_nghttp2_session_defer_data) ||
!CU_add_test(pSuite, "session_flow_control", !CU_add_test(pSuite, "session_flow_control",
test_nghttp2_session_flow_control) || test_nghttp2_session_flow_control) ||
!CU_add_test(pSuite, "session_flow_control_disable_remote",
test_nghttp2_session_flow_control_disable_remote) ||
!CU_add_test(pSuite, "session_flow_control_disable_local",
test_nghttp2_session_flow_control_disable_local) ||
!CU_add_test(pSuite, "session_flow_control_data_recv", !CU_add_test(pSuite, "session_flow_control_data_recv",
test_nghttp2_session_flow_control_data_recv) || test_nghttp2_session_flow_control_data_recv) ||
!CU_add_test(pSuite, "session_data_read_temporal_failure", !CU_add_test(pSuite, "session_data_read_temporal_failure",

View File

@ -220,8 +220,8 @@ void test_nghttp2_frame_pack_settings()
iv[0].value = 256; iv[0].value = 256;
iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
iv[1].value = 16384; iv[1].value = 16384;
iv[2].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS; iv[2].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
iv[2].value = 1; iv[2].value = 4096;
nghttp2_frame_settings_init(&frame, NGHTTP2_FLAG_NONE, nghttp2_frame_settings_init(&frame, NGHTTP2_FLAG_NONE,
nghttp2_frame_iv_copy(iv, 3), 3); nghttp2_frame_iv_copy(iv, 3), 3);
@ -397,22 +397,16 @@ void test_nghttp2_iv_check(void)
iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS; iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
iv[0].value = 100; iv[0].value = 100;
iv[1].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS; iv[1].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
iv[1].value = 0; iv[1].value = 1024;
iv[2].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS;
iv[2].value = 1;
CU_ASSERT(nghttp2_iv_check(iv, 2, 0)); CU_ASSERT(nghttp2_iv_check(iv, 2));
CU_ASSERT(nghttp2_iv_check(iv, 3, 0));
/* Re-enabling flow-control*/
CU_ASSERT(0 == nghttp2_iv_check(iv, 2, 1));
CU_ASSERT(0 == nghttp2_iv_check(iv, 3, 1));
iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
iv[1].value = NGHTTP2_MAX_WINDOW_SIZE; iv[1].value = NGHTTP2_MAX_WINDOW_SIZE;
CU_ASSERT(nghttp2_iv_check(iv, 2, 0)); CU_ASSERT(nghttp2_iv_check(iv, 2));
/* Too large window size */ /* Too large window size */
iv[1].value = (uint32_t)NGHTTP2_MAX_WINDOW_SIZE + 1; iv[1].value = (uint32_t)NGHTTP2_MAX_WINDOW_SIZE + 1;
CU_ASSERT(0 == nghttp2_iv_check(iv, 2, 0)); CU_ASSERT(0 == nghttp2_iv_check(iv, 2));
} }

View File

@ -1311,8 +1311,8 @@ void test_nghttp2_session_on_settings_received(void)
iv[2].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; iv[2].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
iv[2].value = 64*1024; iv[2].value = 64*1024;
iv[3].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS; iv[3].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
iv[3].value = 1; iv[3].value = 1024;
/* Unknown settings ID */ /* Unknown settings ID */
iv[4].settings_id = 999; iv[4].settings_id = 999;
@ -1341,8 +1341,8 @@ void test_nghttp2_session_on_settings_received(void)
session->remote_settings[NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS]); session->remote_settings[NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS]);
CU_ASSERT(64*1024 == CU_ASSERT(64*1024 ==
session->remote_settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]); session->remote_settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
CU_ASSERT(1 == CU_ASSERT(1024 ==
session->remote_settings[NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS]); session->remote_settings[NGHTTP2_SETTINGS_HEADER_TABLE_SIZE]);
CU_ASSERT(64*1024 == stream1->remote_window_size); CU_ASSERT(64*1024 == stream1->remote_window_size);
CU_ASSERT(0 == stream2->remote_window_size); CU_ASSERT(0 == stream2->remote_window_size);
@ -1354,10 +1354,6 @@ void test_nghttp2_session_on_settings_received(void)
CU_ASSERT(16*1024 == stream1->remote_window_size); CU_ASSERT(16*1024 == stream1->remote_window_size);
CU_ASSERT(-48*1024 == stream2->remote_window_size); CU_ASSERT(-48*1024 == stream2->remote_window_size);
CU_ASSERT(0 == stream1->remote_flow_control);
CU_ASSERT(0 == stream2->remote_flow_control);
CU_ASSERT(0 == session->remote_flow_control);
nghttp2_frame_settings_free(&frame.settings); nghttp2_frame_settings_free(&frame.settings);
nghttp2_session_del(session); nghttp2_session_del(session);
@ -2591,18 +2587,14 @@ void test_nghttp2_submit_settings(void)
iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
iv[1].value = 16*1024; iv[1].value = 16*1024;
iv[2].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS; iv[2].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
iv[2].value = 1; iv[2].value = 50;
iv[3].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS; iv[3].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
iv[3].value = 50; iv[3].value = 0;
iv[4].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE; iv[4].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
iv[4].value = 0; iv[4].value = (uint32_t)NGHTTP2_MAX_WINDOW_SIZE + 1;
/* Attempt to re-enable flow-control */
iv[5].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS;
iv[5].value = 0;
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks)); memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
callbacks.send_callback = null_send_callback; callbacks.send_callback = null_send_callback;
@ -2610,25 +2602,23 @@ void test_nghttp2_submit_settings(void)
nghttp2_session_server_new(&session, &callbacks, &ud); nghttp2_session_server_new(&session, &callbacks, &ud);
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT == CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT ==
nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, iv, 6)); nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, iv, 5));
/* Make sure that local settings are not changed */ /* Make sure that local settings are not changed */
CU_ASSERT(NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS == CU_ASSERT(NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS ==
session->local_settings[NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS]); session->local_settings[NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS]);
CU_ASSERT(NGHTTP2_INITIAL_WINDOW_SIZE == CU_ASSERT(NGHTTP2_INITIAL_WINDOW_SIZE ==
session->local_settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]); session->local_settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
CU_ASSERT(0 ==
session->local_settings[NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS]);
/* Now sends without 6th one */ /* Now sends without 5th one */
CU_ASSERT(0 == nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, iv, 5)); CU_ASSERT(0 == nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, iv, 4));
item = nghttp2_session_get_next_ob_item(session); item = nghttp2_session_get_next_ob_item(session);
CU_ASSERT(NGHTTP2_SETTINGS == OB_CTRL_TYPE(item)); CU_ASSERT(NGHTTP2_SETTINGS == OB_CTRL_TYPE(item));
frame = item->frame; frame = item->frame;
CU_ASSERT(5 == frame->settings.niv); CU_ASSERT(4 == frame->settings.niv);
CU_ASSERT(5 == frame->settings.iv[0].value); CU_ASSERT(5 == frame->settings.iv[0].value);
CU_ASSERT(NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS == CU_ASSERT(NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS ==
frame->settings.iv[0].settings_id); frame->settings.iv[0].settings_id);
@ -2651,9 +2641,6 @@ void test_nghttp2_submit_settings(void)
CU_ASSERT(16*1024 == CU_ASSERT(16*1024 ==
session->local_settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]); session->local_settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
CU_ASSERT(1 ==
session->local_settings[NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS]);
CU_ASSERT(0 == session->local_flow_control);
CU_ASSERT(0 == session->hd_inflater.ctx.hd_table_bufsize_max); CU_ASSERT(0 == session->hd_inflater.ctx.hd_table_bufsize_max);
nghttp2_session_del(session); nghttp2_session_del(session);
@ -2673,9 +2660,6 @@ void test_nghttp2_submit_settings_update_local_window_size(void)
iv[0].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; iv[0].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
iv[0].value = 16*1024; iv[0].value = 16*1024;
iv[1].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS;
iv[1].value = 1;
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks)); memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
callbacks.send_callback = null_send_callback; callbacks.send_callback = null_send_callback;
@ -2690,7 +2674,6 @@ void test_nghttp2_submit_settings_update_local_window_size(void)
stream = nghttp2_session_open_stream(session, 3, NGHTTP2_STREAM_FLAG_NONE, stream = nghttp2_session_open_stream(session, 3, NGHTTP2_STREAM_FLAG_NONE,
NGHTTP2_PRI_DEFAULT, NGHTTP2_PRI_DEFAULT,
NGHTTP2_STREAM_OPENED, NULL); NGHTTP2_STREAM_OPENED, NULL);
stream->local_flow_control = 0;
CU_ASSERT(0 == nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, iv, 1)); CU_ASSERT(0 == nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, iv, 1));
CU_ASSERT(0 == nghttp2_session_send(session)); CU_ASSERT(0 == nghttp2_session_send(session));
@ -2701,7 +2684,7 @@ void test_nghttp2_submit_settings_update_local_window_size(void)
CU_ASSERT(16*1024 + 100 == stream->local_window_size); CU_ASSERT(16*1024 + 100 == stream->local_window_size);
stream = nghttp2_session_get_stream(session, 3); stream = nghttp2_session_get_stream(session, 3);
CU_ASSERT(NGHTTP2_INITIAL_WINDOW_SIZE == stream->local_window_size); CU_ASSERT(16*1024 == stream->local_window_size);
item = nghttp2_session_get_next_ob_item(session); item = nghttp2_session_get_next_ob_item(session);
CU_ASSERT(NGHTTP2_WINDOW_UPDATE == OB_CTRL_TYPE(item)); CU_ASSERT(NGHTTP2_WINDOW_UPDATE == OB_CTRL_TYPE(item));
@ -2709,20 +2692,6 @@ void test_nghttp2_submit_settings_update_local_window_size(void)
nghttp2_session_del(session); nghttp2_session_del(session);
/* Check flow control disabled case */
nghttp2_session_server_new(&session, &callbacks, NULL);
stream = nghttp2_session_open_stream(session, 1, NGHTTP2_STREAM_FLAG_NONE,
NGHTTP2_PRI_DEFAULT,
NGHTTP2_STREAM_OPENED, NULL);
CU_ASSERT(0 == nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, iv, 2));
CU_ASSERT(0 == nghttp2_session_send(session));
CU_ASSERT(0 == nghttp2_session_on_settings_received(session, &ack_frame, 0));
CU_ASSERT(NGHTTP2_INITIAL_WINDOW_SIZE == stream->local_window_size);
nghttp2_session_del(session);
/* Check overflow case */ /* Check overflow case */
iv[0].value = 128*1024; iv[0].value = 128*1024;
nghttp2_session_server_new(&session, &callbacks, NULL); nghttp2_session_server_new(&session, &callbacks, NULL);
@ -2817,10 +2786,6 @@ void test_nghttp2_submit_window_update(void)
CU_ASSERT(0 == CU_ASSERT(0 ==
nghttp2_submit_window_update(session, NGHTTP2_FLAG_NONE, 2, 0)); nghttp2_submit_window_update(session, NGHTTP2_FLAG_NONE, 2, 0));
/* Disable local flow control */
stream->local_flow_control = 0;
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT ==
nghttp2_submit_window_update(session, NGHTTP2_FLAG_NONE, 2, -1));
/* It is ok if stream is closed or does not exist at the call /* It is ok if stream is closed or does not exist at the call
time */ time */
CU_ASSERT(0 == CU_ASSERT(0 ==
@ -3431,84 +3396,6 @@ void test_nghttp2_session_flow_control(void)
nghttp2_session_del(session); nghttp2_session_del(session);
} }
void test_nghttp2_session_flow_control_disable_remote(void)
{
nghttp2_session *session;
nghttp2_session_callbacks callbacks;
my_user_data ud;
nghttp2_data_provider data_prd;
nghttp2_frame frame;
size_t data_size = 128*1024;
nghttp2_settings_entry iv = { NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS, 0x1 };
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
callbacks.send_callback = null_send_callback;
callbacks.on_frame_send_callback = on_frame_send_callback;
data_prd.read_callback = fixed_length_data_source_read_callback;
ud.frame_send_cb_called = 0;
ud.data_source_length = data_size;
/* Initial window size is 64KiB */
nghttp2_session_client_new(&session, &callbacks, &ud);
nghttp2_submit_request(session, NGHTTP2_PRI_DEFAULT, NULL, 0,
&data_prd, NULL);
/* Sends 64KiB data */
CU_ASSERT(0 == nghttp2_session_send(session));
CU_ASSERT(data_size - NGHTTP2_INITIAL_WINDOW_SIZE == ud.data_source_length);
/* Disable flow control entirely */
nghttp2_frame_settings_init(&frame.settings, NGHTTP2_FLAG_NONE,
dup_iv(&iv, 1), 1);
nghttp2_session_on_settings_received(session, &frame, 1);
/* Check both connection and stream-level remote_flow_control is
disabled */
CU_ASSERT(0 == nghttp2_session_get_stream(session, 1)->remote_flow_control);
CU_ASSERT(0 == session->remote_flow_control);
/* Sends remaining data */
CU_ASSERT(0 == nghttp2_session_send(session));
CU_ASSERT(0 == ud.data_source_length);
nghttp2_frame_settings_free(&frame.settings);
nghttp2_session_del(session);
}
void test_nghttp2_session_flow_control_disable_local(void)
{
nghttp2_session *session;
nghttp2_session_callbacks callbacks;
nghttp2_stream *stream;
nghttp2_settings_entry iv[1];
nghttp2_frame ack_frame;
nghttp2_frame_settings_init(&ack_frame.settings, NGHTTP2_FLAG_ACK, NULL, 0);
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
callbacks.send_callback = null_send_callback;
nghttp2_session_client_new(&session, &callbacks, NULL);
stream = nghttp2_session_open_stream(session, 1, NGHTTP2_STREAM_FLAG_NONE,
NGHTTP2_PRI_DEFAULT,
NGHTTP2_STREAM_OPENING, NULL);
iv[0].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS;
iv[0].value = 1;
CU_ASSERT(0 == nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, iv,
ARRLEN(iv)));
CU_ASSERT(0 == nghttp2_session_send(session));
CU_ASSERT(0 == nghttp2_session_on_settings_received(session, &ack_frame, 0));
CU_ASSERT(0 == stream->local_flow_control);
CU_ASSERT(0 == session->local_flow_control);
nghttp2_session_del(session);
nghttp2_frame_settings_free(&ack_frame.settings);
}
void test_nghttp2_session_flow_control_data_recv(void) void test_nghttp2_session_flow_control_data_recv(void)
{ {
nghttp2_session *session; nghttp2_session *session;
@ -3934,8 +3821,8 @@ void test_nghttp2_pack_settings_payload(void)
nghttp2_settings_entry *resiv; nghttp2_settings_entry *resiv;
size_t resniv; size_t resniv;
iv[0].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS; iv[0].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
iv[0].value = 1; iv[0].value = 1023;
iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
iv[1].value = 4095; iv[1].value = 4095;
@ -3944,8 +3831,8 @@ void test_nghttp2_pack_settings_payload(void)
CU_ASSERT(0 == nghttp2_frame_unpack_settings_payload2(&resiv, &resniv, CU_ASSERT(0 == nghttp2_frame_unpack_settings_payload2(&resiv, &resniv,
buf, len)); buf, len));
CU_ASSERT(2 == resniv); CU_ASSERT(2 == resniv);
CU_ASSERT(NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS == resiv[0].settings_id); CU_ASSERT(NGHTTP2_SETTINGS_HEADER_TABLE_SIZE == resiv[0].settings_id);
CU_ASSERT(1 == resiv[0].value); CU_ASSERT(1023 == resiv[0].value);
CU_ASSERT(NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE == resiv[1].settings_id); CU_ASSERT(NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE == resiv[1].settings_id);
CU_ASSERT(4095 == resiv[1].value); CU_ASSERT(4095 == resiv[1].value);

View File

@ -79,8 +79,6 @@ void test_nghttp2_session_stream_close_on_headers_push(void);
void test_nghttp2_session_stop_data_with_rst_stream(void); void test_nghttp2_session_stop_data_with_rst_stream(void);
void test_nghttp2_session_defer_data(void); void test_nghttp2_session_defer_data(void);
void test_nghttp2_session_flow_control(void); void test_nghttp2_session_flow_control(void);
void test_nghttp2_session_flow_control_disable_remote(void);
void test_nghttp2_session_flow_control_disable_local(void);
void test_nghttp2_session_flow_control_data_recv(void); void test_nghttp2_session_flow_control_data_recv(void);
void test_nghttp2_session_data_read_temporal_failure(void); void test_nghttp2_session_data_read_temporal_failure(void);
void test_nghttp2_session_on_stream_close(void); void test_nghttp2_session_on_stream_close(void);