From bb6a90dc4d88b82d802994fb519f286ca4ff6834 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 2 Feb 2012 21:51:52 +0900 Subject: [PATCH] Added spdylay_stream_add_pushed_stream With this function and 3 new member in spdylay_stream, we can track server- pushed streams which associate them to this stream. --- lib/spdylay_stream.c | 24 +++++++++++++++++++- lib/spdylay_stream.h | 18 ++++++++++++--- tests/Makefile.am | 4 ++-- tests/main.c | 5 ++++- tests/spdylay_stream_test.c | 45 +++++++++++++++++++++++++++++++++++++ tests/spdylay_stream_test.h | 30 +++++++++++++++++++++++++ 6 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 tests/spdylay_stream_test.c create mode 100644 tests/spdylay_stream_test.h diff --git a/lib/spdylay_stream.c b/lib/spdylay_stream.c index 113d5ebe..2d2a47ba 100644 --- a/lib/spdylay_stream.c +++ b/lib/spdylay_stream.c @@ -33,12 +33,34 @@ void spdylay_stream_init(spdylay_stream *stream, int32_t stream_id, stream->pri = pri; stream->state = initial_state; stream->shut_flags = SPDYLAY_SHUT_NONE; + stream->pushed_streams = NULL; + stream->pushed_streams_length = 0; + stream->pushed_streams_capacity = 0; } void spdylay_stream_free(spdylay_stream *stream) -{} +{ + free(stream->pushed_streams); +} void spdylay_stream_shutdown(spdylay_stream *stream, spdylay_shut_flag flag) { stream->shut_flags |= flag; } + +int spdylay_stream_add_pushed_stream(spdylay_stream *stream, int32_t stream_id) +{ + if(stream->pushed_streams_capacity == stream->pushed_streams_length) { + int32_t *streams; + size_t capacity = stream->pushed_streams_capacity == 0 ? + 5 : stream->pushed_streams_capacity*2; + streams = realloc(stream->pushed_streams, capacity*sizeof(uint32_t)); + if(streams == NULL) { + return SPDYLAY_ERR_NOMEM; + } + stream->pushed_streams = streams; + stream->pushed_streams_capacity = capacity; + } + stream->pushed_streams[stream->pushed_streams_length++] = stream_id; + return 0; +} diff --git a/lib/spdylay_stream.h b/lib/spdylay_stream.h index f85426c5..19eec737 100644 --- a/lib/spdylay_stream.h +++ b/lib/spdylay_stream.h @@ -77,9 +77,14 @@ typedef struct { uint8_t pri; /* Bitwise OR of zero or more spdylay_shut_flag values */ uint8_t shut_flags; - /* TODO spdylay_stream should remember pushed stream ID, so that if - RST_STREAM with CANCEL (mandatory?) is sent, we can close all of - them. */ + /* The array of server-pushed stream IDs which associate them to + this stream. */ + int32_t *pushed_streams; + /* The number of stored pushed stream ID in |pushed_streams| */ + size_t pushed_streams_length; + /* The maximum number of stream ID the |pushed_streams| can + store. */ + size_t pushed_streams_capacity; } spdylay_stream; void spdylay_stream_init(spdylay_stream *stream, int32_t stream_id, @@ -94,4 +99,11 @@ void spdylay_stream_free(spdylay_stream *stream); */ void spdylay_stream_shutdown(spdylay_stream *stream, spdylay_shut_flag flag); +/* + * Add server-pushed |stream_id| to this stream. This happens when + * server-pushed stream is associated to this stream. This function + * returns 0 if it succeeds, or negative error code. + */ +int spdylay_stream_add_pushed_stream(spdylay_stream *stream, int32_t stream_id); + #endif /* SPDYLAY_STREAM */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 5f2884df..dc9f084a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -27,11 +27,11 @@ check_PROGRAMS = main OBJECTS = main.c spdylay_pq_test.c spdylay_map_test.c spdylay_queue_test.c \ spdylay_buffer_test.c spdylay_zlib_test.c spdylay_session_test.c \ - spdylay_frame_test.c + spdylay_frame_test.c spdylay_stream_test.c HFILES = spdylay_pq_test.h spdylay_map_test.h spdylay_queue_test.h \ spdylay_buffer_test.h spdylay_zlib_test.h spdylay_session_test.h \ - spdylay_frame_test.h + spdylay_frame_test.h spdylay_stream_test.h main_SOURCES = $(HFILES) $(OBJECTS) diff --git a/tests/main.c b/tests/main.c index dff44e59..4671bb04 100644 --- a/tests/main.c +++ b/tests/main.c @@ -33,6 +33,7 @@ #include "spdylay_zlib_test.h" #include "spdylay_session_test.h" #include "spdylay_frame_test.h" +#include "spdylay_stream_test.h" int init_suite1(void) { @@ -104,7 +105,9 @@ int main() test_spdylay_frame_pack_headers) || !CU_add_test(pSuite, "frame_pack_settings", test_spdylay_frame_pack_settings) || - !CU_add_test(pSuite, "frame_nv_sort", test_spdylay_frame_nv_sort)) { + !CU_add_test(pSuite, "frame_nv_sort", test_spdylay_frame_nv_sort) || + !CU_add_test(pSuite, "stream_add_pushed_stream", + test_spdylay_stream_add_pushed_stream)) { CU_cleanup_registry(); return CU_get_error(); } diff --git a/tests/spdylay_stream_test.c b/tests/spdylay_stream_test.c new file mode 100644 index 00000000..3e3c32d7 --- /dev/null +++ b/tests/spdylay_stream_test.c @@ -0,0 +1,45 @@ +/* + * Spdylay - SPDY Library + * + * Copyright (c) 2012 Tatsuhiro Tsujikawa + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "spdylay_stream_test.h" + +#include + +#include "spdylay_stream.h" + +void test_spdylay_stream_add_pushed_stream() +{ + spdylay_stream stream; + int i, n; + spdylay_stream_init(&stream, 1, SPDYLAY_FLAG_NONE, 3, SPDYLAY_STREAM_OPENING); + n = 26; + for(i = 2; i < n; i += 2) { + CU_ASSERT(0 == spdylay_stream_add_pushed_stream(&stream, i)); + CU_ASSERT(i/2 == stream.pushed_streams_length); + } + for(i = 2; i < n; i += 2) { + CU_ASSERT(i == stream.pushed_streams[i/2-1]); + } + spdylay_stream_free(&stream); +} diff --git a/tests/spdylay_stream_test.h b/tests/spdylay_stream_test.h new file mode 100644 index 00000000..1326063e --- /dev/null +++ b/tests/spdylay_stream_test.h @@ -0,0 +1,30 @@ +/* + * Spdylay - SPDY Library + * + * Copyright (c) 2012 Tatsuhiro Tsujikawa + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef SPDYLAY_STREAM_TEST_H +#define SPDYLAY_STREAM_TEST_H + +void test_spdylay_stream_add_pushed_stream(); + +#endif /* SPDYLAY_STREAM_TEST_H */