From b7429e7c2d010be58fe5a8333e3ccdcfd4a66c0d Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 8 May 2012 23:41:59 +0900 Subject: [PATCH] Added spdylay_submit_window_update() public API. --- lib/includes/spdylay/spdylay.h | 20 ++++++++++++++++++ lib/spdylay_submit.c | 20 ++++++++++++++++++ tests/main.c | 2 ++ tests/spdylay_session_test.c | 37 ++++++++++++++++++++++++++++++++++ tests/spdylay_session_test.h | 1 + 5 files changed, 80 insertions(+) diff --git a/lib/includes/spdylay/spdylay.h b/lib/includes/spdylay/spdylay.h index a4a15d94..3c7d260e 100644 --- a/lib/includes/spdylay/spdylay.h +++ b/lib/includes/spdylay/spdylay.h @@ -1800,6 +1800,26 @@ int spdylay_submit_goaway(spdylay_session *session, uint32_t status_code); int spdylay_submit_settings(spdylay_session *session, uint8_t flags, const spdylay_settings_entry *iv, size_t niv); +/** + * @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. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * :enum:`SPDYLAY_ERR_STREAM_CLOSED` + * The stream is already closed or does not exist. + * :enum:`SPDYLAY_ERR_NOMEM` + * Out of memory. + */ +int spdylay_submit_window_update(spdylay_session *session, int32_t stream_id, + int32_t delta_window_size); + /** * @function * diff --git a/lib/spdylay_submit.c b/lib/spdylay_submit.c index 0a5fcc37..730d48ca 100644 --- a/lib/spdylay_submit.c +++ b/lib/spdylay_submit.c @@ -28,6 +28,7 @@ #include "spdylay_session.h" #include "spdylay_frame.h" +#include "spdylay_helper.h" static int spdylay_submit_syn_stream_shared (spdylay_session *session, @@ -228,6 +229,25 @@ int spdylay_submit_settings(spdylay_session *session, uint8_t flags, return r; } +int spdylay_submit_window_update(spdylay_session *session, int32_t stream_id, + int32_t delta_window_size) +{ + spdylay_stream *stream; + 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; + } else { + return SPDYLAY_ERR_STREAM_CLOSED; + } +} + int spdylay_submit_request(spdylay_session *session, uint8_t pri, const char **nv, const spdylay_data_provider *data_prd, diff --git a/tests/main.c b/tests/main.c index a6893e96..429cd998 100644 --- a/tests/main.c +++ b/tests/main.c @@ -154,6 +154,8 @@ int main(int argc, char* argv[]) test_spdylay_session_set_initial_client_cert_origin) || !CU_add_test(pSuite, "session_set_option", test_spdylay_session_set_option) || + !CU_add_test(pSuite, "submit_window_update", + test_spdylay_submit_window_update) || !CU_add_test(pSuite, "frame_unpack_nv_spdy2", test_spdylay_frame_unpack_nv_spdy2) || !CU_add_test(pSuite, "frame_unpack_nv_spdy3", diff --git a/tests/spdylay_session_test.c b/tests/spdylay_session_test.c index 0fb77ae1..a8c62d2f 100644 --- a/tests/spdylay_session_test.c +++ b/tests/spdylay_session_test.c @@ -2280,3 +2280,40 @@ void test_spdylay_session_set_option(void) spdylay_session_del(session); } + +void test_spdylay_submit_window_update(void) +{ + spdylay_session *session; + spdylay_session_callbacks callbacks; + int32_t stream_id = 2; + my_user_data ud; + spdylay_outbound_item *item; + spdylay_stream *stream; + + memset(&callbacks, 0, sizeof(spdylay_session_callbacks)); + callbacks.send_callback = null_send_callback; + + spdylay_session_client_new(&session, SPDYLAY_PROTO_SPDY3, + &callbacks, &ud); + stream = spdylay_session_open_stream(session, stream_id, + SPDYLAY_CTRL_FLAG_NONE, 3, + SPDYLAY_STREAM_OPENED, NULL); + stream->recv_window_size = 4096; + + CU_ASSERT(0 == spdylay_submit_window_update(session, stream_id, 1024)); + item = spdylay_session_get_next_ob_item(session); + 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(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(0 == spdylay_session_send(session)); + + CU_ASSERT(0 == spdylay_submit_window_update(session, stream_id, 4096)); + CU_ASSERT(NULL == spdylay_session_get_next_ob_item(session)); + + spdylay_session_del(session); +} diff --git a/tests/spdylay_session_test.h b/tests/spdylay_session_test.h index e7359706..1ef36902 100644 --- a/tests/spdylay_session_test.h +++ b/tests/spdylay_session_test.h @@ -68,5 +68,6 @@ void test_spdylay_session_prep_credential(void); void test_spdylay_submit_syn_stream_with_credential(void); void test_spdylay_session_set_initial_client_cert_origin(void); void test_spdylay_session_set_option(void); +void test_spdylay_submit_window_update(void); #endif /* SPDYLAY_SESSION_TEST_H */