int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags, int32_t stream_id, int32_t window_size_increment) { int rv; nghttp2_stream *stream = 0; if (window_size_increment == 0) { return 0; } flags = 0; if (stream_id == 0) { rv = nghttp2_adjust_local_window_size( &session->local_window_size, &session->recv_window_size, &session->recv_reduction, &window_size_increment); if (rv != 0) { return rv; } } else { stream = nghttp2_session_get_stream(session, stream_id); if (!stream) { return 0; } rv = nghttp2_adjust_local_window_size( &stream->local_window_size, &stream->recv_window_size, &stream->recv_reduction, &window_size_increment); if (rv != 0) { return rv; } } if (window_size_increment > 0) { if (stream_id == 0) { session->consumed_size = nghttp2_max(0, session->consumed_size - window_size_increment); } else { stream->consumed_size = nghttp2_max(0, stream->consumed_size - window_size_increment); } return nghttp2_session_add_window_update(session, flags, stream_id, window_size_increment); } return 0; }
void test_nghttp2_adjust_local_window_size(void) { int32_t local_window_size = 100; int32_t recv_window_size = 50; int32_t recv_reduction = 0; int32_t delta; delta = 0; CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size, &recv_window_size, &recv_reduction, &delta)); CU_ASSERT(100 == local_window_size); CU_ASSERT(50 == recv_window_size); CU_ASSERT(0 == recv_reduction); CU_ASSERT(0 == delta); delta = 49; CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size, &recv_window_size, &recv_reduction, &delta)); CU_ASSERT(100 == local_window_size); CU_ASSERT(1 == recv_window_size); CU_ASSERT(0 == recv_reduction); CU_ASSERT(49 == delta); delta = 1; CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size, &recv_window_size, &recv_reduction, &delta)); CU_ASSERT(100 == local_window_size); CU_ASSERT(0 == recv_window_size); CU_ASSERT(0 == recv_reduction); CU_ASSERT(1 == delta); delta = 1; CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size, &recv_window_size, &recv_reduction, &delta)); CU_ASSERT(101 == local_window_size); CU_ASSERT(0 == recv_window_size); CU_ASSERT(0 == recv_reduction); CU_ASSERT(1 == delta); delta = -1; CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size, &recv_window_size, &recv_reduction, &delta)); CU_ASSERT(100 == local_window_size); CU_ASSERT(-1 == recv_window_size); CU_ASSERT(1 == recv_reduction); CU_ASSERT(0 == delta); delta = 1; CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size, &recv_window_size, &recv_reduction, &delta)); CU_ASSERT(101 == local_window_size); CU_ASSERT(0 == recv_window_size); CU_ASSERT(0 == recv_reduction); CU_ASSERT(0 == delta); delta = 100; CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size, &recv_window_size, &recv_reduction, &delta)); CU_ASSERT(201 == local_window_size); CU_ASSERT(0 == recv_window_size); CU_ASSERT(0 == recv_reduction); CU_ASSERT(100 == delta); delta = -3; CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size, &recv_window_size, &recv_reduction, &delta)); CU_ASSERT(198 == local_window_size); CU_ASSERT(-3 == recv_window_size); CU_ASSERT(3 == recv_reduction); CU_ASSERT(0 == delta); recv_window_size += 3; delta = 3; CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size, &recv_window_size, &recv_reduction, &delta)); CU_ASSERT(201 == local_window_size); CU_ASSERT(3 == recv_window_size); CU_ASSERT(0 == recv_reduction); CU_ASSERT(0 == delta); local_window_size = 100; recv_window_size = 50; recv_reduction = 0; delta = INT32_MAX; CU_ASSERT(NGHTTP2_ERR_FLOW_CONTROL == nghttp2_adjust_local_window_size(&local_window_size, &recv_window_size, &recv_reduction, &delta)); CU_ASSERT(100 == local_window_size); CU_ASSERT(50 == recv_window_size); CU_ASSERT(0 == recv_reduction); CU_ASSERT(INT32_MAX == delta); delta = INT32_MIN; CU_ASSERT(NGHTTP2_ERR_FLOW_CONTROL == nghttp2_adjust_local_window_size(&local_window_size, &recv_window_size, &recv_reduction, &delta)); CU_ASSERT(100 == local_window_size); CU_ASSERT(50 == recv_window_size); CU_ASSERT(0 == recv_reduction); CU_ASSERT(INT32_MIN == delta); }
int nghttp2_session_set_local_window_size(nghttp2_session *session, uint8_t flags, int32_t stream_id, int32_t window_size) { int32_t window_size_increment; nghttp2_stream *stream; int rv; if (window_size < 0) { return NGHTTP2_ERR_INVALID_ARGUMENT; } flags = 0; if (stream_id == 0) { window_size_increment = window_size - session->local_window_size; if (window_size_increment == 0) { return 0; } if (window_size_increment < 0) { return nghttp2_adjust_local_window_size( &session->local_window_size, &session->recv_window_size, &session->recv_reduction, &window_size_increment); } rv = nghttp2_increase_local_window_size( &session->local_window_size, &session->recv_window_size, &session->recv_reduction, &window_size_increment); if (rv != 0) { return rv; } } else { stream = nghttp2_session_get_stream(session, stream_id); if (stream == NULL) { return 0; } window_size_increment = window_size - stream->local_window_size; if (window_size_increment == 0) { return 0; } if (window_size_increment < 0) { return nghttp2_adjust_local_window_size( &stream->local_window_size, &stream->recv_window_size, &stream->recv_reduction, &window_size_increment); } rv = nghttp2_increase_local_window_size( &stream->local_window_size, &stream->recv_window_size, &stream->recv_reduction, &window_size_increment); if (rv != 0) { return rv; } } if (window_size_increment > 0) { return nghttp2_session_add_window_update(session, flags, stream_id, window_size_increment); } return 0; }