Made spdylay_submit_window_update() not be bounded by recv_window_size

Current SPDY/3 spec does not clearly prohibit to send
delta_window_size which makes resulting window size more than initial
window size. For this reason, spdylay_submit_window_update() can send
delta_window_size in [1, (1 << 31)-1], inclusive, without bounded by
stream's recv_window_size. Of course, the application is now
responsible to keep the resulting window size <= (1 << 31)-1.

spdylay_submit_window_update() now returns
SPDYLAY_ERR_INVALID_ARGUMENT if delta_window_size is 0 or negative.
This commit is contained in:
Tatsuhiro Tsujikawa 2012-05-20 16:03:01 +09:00
parent 80ab232060
commit b95e9a8c4c
3 changed files with 27 additions and 15 deletions

View File

@ -1894,15 +1894,16 @@ int spdylay_submit_settings(spdylay_session *session, uint8_t flags,
/**
* @function
*
* Submits WINDOW_UPDATE frame. The library keeps track of the
* received bytes from the remote endpoint. If the |delta_window_size|
* is larger than the received bytes, then it is reduced to the
* received bytes. If the received bytes is 0, the library will not
* send this frame.
* Submits WINDOW_UPDATE frame. The effective range of the
* |delta_window_size| is [1, (1 << 31)-1], inclusive. But the
* application must be responsible to keep the resulting window size
* <= (1 << 31)-1.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :enum:`SPDYLAY_ERR_INVALID_ARGUMENT`
* The |delta_window_size| is 0 or negative.
* :enum:`SPDYLAY_ERR_STREAM_CLOSED`
* The stream is already closed or does not exist.
* :enum:`SPDYLAY_ERR_NOMEM`

View File

@ -233,16 +233,15 @@ int spdylay_submit_window_update(spdylay_session *session, int32_t stream_id,
int32_t delta_window_size)
{
spdylay_stream *stream;
if(delta_window_size <= 0) {
return SPDYLAY_ERR_INVALID_ARGUMENT;
}
stream = spdylay_session_get_stream(session, stream_id);
if(stream) {
delta_window_size = spdylay_min(delta_window_size,
stream->recv_window_size);
if(delta_window_size > 0) {
stream->recv_window_size -= delta_window_size;
return spdylay_session_add_window_update(session, stream_id,
delta_window_size);
}
return 0;
stream->recv_window_size -= spdylay_min(delta_window_size,
stream->recv_window_size);
return spdylay_session_add_window_update(session, stream_id,
delta_window_size);
} else {
return SPDYLAY_ERR_STREAM_CLOSED;
}

View File

@ -2339,15 +2339,27 @@ void test_spdylay_submit_window_update(void)
CU_ASSERT(SPDYLAY_WINDOW_UPDATE == OB_CTRL_TYPE(item));
CU_ASSERT(1024 == OB_CTRL(item)->window_update.delta_window_size);
CU_ASSERT(0 == spdylay_session_send(session));
CU_ASSERT(3072 == stream->recv_window_size);
CU_ASSERT(0 == spdylay_submit_window_update(session, stream_id, 4096));
item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(SPDYLAY_WINDOW_UPDATE == OB_CTRL_TYPE(item));
CU_ASSERT(3072 == OB_CTRL(item)->window_update.delta_window_size);
CU_ASSERT(4096 == OB_CTRL(item)->window_update.delta_window_size);
CU_ASSERT(0 == spdylay_session_send(session));
CU_ASSERT(0 == stream->recv_window_size);
CU_ASSERT(0 == spdylay_submit_window_update(session, stream_id, 4096));
CU_ASSERT(NULL == spdylay_session_get_next_ob_item(session));
CU_ASSERT(SPDYLAY_WINDOW_UPDATE == OB_CTRL_TYPE(item));
CU_ASSERT(4096 == OB_CTRL(item)->window_update.delta_window_size);
CU_ASSERT(0 == spdylay_session_send(session));
CU_ASSERT(0 == stream->recv_window_size);
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
spdylay_submit_window_update(session, stream_id, 0));
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
spdylay_submit_window_update(session, stream_id, -1));
CU_ASSERT(SPDYLAY_ERR_STREAM_CLOSED ==
spdylay_submit_window_update(session, 4, 4096));
spdylay_session_del(session);
}