From 847830f13225a6467b06decf3b3e95eb16a8e001 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 25 Feb 2012 01:17:03 +0900 Subject: [PATCH] Added ability to pack/unpack SPDY/3 frames. Added SPDY/3 zlib dictionary from draft-mbelshe-httpbis-spdy-00. --- lib/includes/spdylay/spdylay.h | 9 ++ lib/spdylay_frame.c | 129 +++++++++++++++---- lib/spdylay_frame.h | 16 +++ lib/spdylay_session.c | 12 +- lib/spdylay_zlib.c | 227 ++++++++++++++++++++++++++++++++- lib/spdylay_zlib.h | 14 +- tests/main.c | 7 +- tests/spdylay_frame_test.c | 124 +++++++++++++++++- tests/spdylay_frame_test.h | 2 + tests/spdylay_zlib_test.c | 16 ++- tests/spdylay_zlib_test.h | 3 +- 11 files changed, 509 insertions(+), 50 deletions(-) diff --git a/lib/includes/spdylay/spdylay.h b/lib/includes/spdylay/spdylay.h index c0940b0e..87815623 100644 --- a/lib/includes/spdylay/spdylay.h +++ b/lib/includes/spdylay/spdylay.h @@ -46,6 +46,7 @@ typedef struct spdylay_session spdylay_session; typedef enum { SPDYLAY_ERR_INVALID_ARGUMENT = -501, SPDYLAY_ERR_ZLIB = -502, + SPDYLAY_ERR_UNSUPPORTED_VERSION = -503, SPDYLAY_ERR_WOULDBLOCK = -504, SPDYLAY_ERR_PROTO = -505, SPDYLAY_ERR_INVALID_FRAME = -506, @@ -370,6 +371,10 @@ typedef struct { * * SPDYLAY_ERR_NOMEM * Out of memory. + * SPDYLAY_ERR_ZLIB + * The z_stream initialization failed. + * SPDYLAY_ERR_UNSUPPORTED_VERSION + * The version is not supported. */ int spdylay_session_client_new(spdylay_session **session_ptr, const spdylay_session_callbacks *callbacks, @@ -386,6 +391,10 @@ int spdylay_session_client_new(spdylay_session **session_ptr, * * SPDYLAY_ERR_NOMEM * Out of memory. + * SPDYLAY_ERR_ZLIB + * The z_stream initialization failed. + * SPDYLAY_ERR_UNSUPPORTED_VERSION + * The version is not supported. */ int spdylay_session_server_new(spdylay_session **session_ptr, const spdylay_session_callbacks *callbacks, diff --git a/lib/spdylay_frame.c b/lib/spdylay_frame.c index 9255c705..e651d9ba 100644 --- a/lib/spdylay_frame.c +++ b/lib/spdylay_frame.c @@ -38,6 +38,21 @@ (LEN_SIZE == 2 ? \ spdylay_put_uint16be(OUT, VAL) : spdylay_put_uint32be(OUT, VAL)) +/* Returns the number of bytes in length of name/value pair for the + given protocol version |version|. If |version| is not supported, + returns 0. */ +static size_t spdylay_frame_get_len_size(uint16_t version) +{ + if(SPDYLAY_PROTO_SPDY2 == version) { + return 2; + } else if(SPDYLAY_PROTO_SPDY3 == version) { + return 4; + } else { + /* Unsupported version */ + return 0; + } +} + static uint8_t spdylay_unpack_pri(const uint8_t *data) { return (data[0] >> 6) & 0x3; @@ -441,6 +456,7 @@ void spdylay_frame_goaway_init(spdylay_goaway *frame, frame->hd.type = SPDYLAY_GOAWAY; frame->hd.length = 4; frame->last_good_stream_id = last_good_stream_id; + frame->status_code = 0; /* TODO Add status_code arg for spdy/3 */ } void spdylay_frame_goaway_free(spdylay_goaway *frame) @@ -520,11 +536,15 @@ ssize_t spdylay_frame_pack_syn_stream(uint8_t **buf_ptr, spdylay_zlib *deflater) { ssize_t framelen; + size_t len_size = spdylay_frame_get_len_size(frame->hd.version); + if(len_size == 0) { + return SPDYLAY_ERR_UNSUPPORTED_VERSION; + } framelen = spdylay_frame_alloc_pack_nv(buf_ptr, buflen_ptr, nvbuf_ptr, nvbuflen_ptr, frame->nv, SPDYLAY_SYN_STREAM_NV_OFFSET, - 2, + len_size, deflater); if(framelen < 0) { return framelen; @@ -536,6 +556,9 @@ ssize_t spdylay_frame_pack_syn_stream(uint8_t **buf_ptr, spdylay_put_uint32be(&(*buf_ptr)[8], frame->stream_id); spdylay_put_uint32be(&(*buf_ptr)[12], frame->assoc_stream_id); (*buf_ptr)[16] = (frame->pri << 6); + if(frame->hd.version == SPDYLAY_PROTO_SPDY3) { + (*buf_ptr)[17] = frame->slot; + } return framelen; } @@ -548,23 +571,34 @@ int spdylay_frame_unpack_syn_stream(spdylay_syn_stream *frame, spdylay_zlib *inflater) { int r; + size_t len_size; if(payloadlen < 12) { return SPDYLAY_ERR_INVALID_FRAME; } spdylay_frame_unpack_ctrl_hd(&frame->hd, head); + len_size = spdylay_frame_get_len_size(frame->hd.version); + if(len_size == 0) { + return SPDYLAY_ERR_UNSUPPORTED_VERSION; + } frame->stream_id = spdylay_get_uint32(payload) & SPDYLAY_STREAM_ID_MASK; frame->assoc_stream_id = spdylay_get_uint32(payload+4) & SPDYLAY_STREAM_ID_MASK; frame->pri = spdylay_unpack_pri(payload+8); + if(frame->hd.version == SPDYLAY_PROTO_SPDY3) { + frame->slot = payload[9]; + } else { + frame->slot = 0; + } r = spdylay_frame_alloc_unpack_nv(&frame->nv, inflatebuf, nvbuf_ptr, nvbuflen_ptr, payload+10, payloadlen-10, - 2, + len_size, inflater); return r; } -#define SPDYLAY_SYN_REPLY_NV_OFFSET 14 +#define SPDYLAY_SPDY2_SYN_REPLY_NV_OFFSET 14 +#define SPDYLAY_SPDY3_SYN_REPLY_NV_OFFSET 12 ssize_t spdylay_frame_pack_syn_reply(uint8_t **buf_ptr, size_t *buflen_ptr, @@ -574,17 +608,24 @@ ssize_t spdylay_frame_pack_syn_reply(uint8_t **buf_ptr, spdylay_zlib *deflater) { ssize_t framelen; + size_t len_size; + size_t nv_offset; + len_size = spdylay_frame_get_len_size(frame->hd.version); + if(len_size == 0) { + return SPDYLAY_ERR_UNSUPPORTED_VERSION; + } + nv_offset = frame->hd.version == SPDYLAY_PROTO_SPDY2 ? + SPDYLAY_SPDY2_SYN_REPLY_NV_OFFSET : SPDYLAY_SPDY3_SYN_REPLY_NV_OFFSET; + framelen = spdylay_frame_alloc_pack_nv(buf_ptr, buflen_ptr, nvbuf_ptr, nvbuflen_ptr, - frame->nv, - SPDYLAY_SYN_REPLY_NV_OFFSET, - 2, - deflater); + frame->nv, nv_offset, + len_size, deflater); if(framelen < 0) { return framelen; } frame->hd.length = framelen-SPDYLAY_FRAME_HEAD_LENGTH; - memset(*buf_ptr, 0, SPDYLAY_SYN_REPLY_NV_OFFSET); + memset(*buf_ptr, 0, nv_offset); spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd); spdylay_put_uint32be(&(*buf_ptr)[8], frame->stream_id); return framelen; @@ -599,16 +640,22 @@ int spdylay_frame_unpack_syn_reply(spdylay_syn_reply *frame, spdylay_zlib *inflater) { int r; + size_t len_size; + size_t nv_offset; if(payloadlen < 8) { return SPDYLAY_ERR_INVALID_FRAME; } spdylay_frame_unpack_ctrl_hd(&frame->hd, head); + len_size = spdylay_frame_get_len_size(frame->hd.version); + if(len_size == 0) { + return SPDYLAY_ERR_UNSUPPORTED_VERSION; + } + nv_offset = frame->hd.version == SPDYLAY_PROTO_SPDY2 ? 6 : 4; frame->stream_id = spdylay_get_uint32(payload) & SPDYLAY_STREAM_ID_MASK; r = spdylay_frame_alloc_unpack_nv(&frame->nv, inflatebuf, nvbuf_ptr, nvbuflen_ptr, - payload+6, payloadlen-6, - 2, - inflater); + payload+nv_offset, payloadlen-nv_offset, + len_size, inflater); return r; } @@ -642,8 +689,15 @@ int spdylay_frame_unpack_ping(spdylay_ping *frame, ssize_t spdylay_frame_pack_goaway(uint8_t **buf_ptr, size_t *buflen_ptr, spdylay_goaway *frame) { - ssize_t framelen = 12; + ssize_t framelen; int r; + if(frame->hd.version == SPDYLAY_PROTO_SPDY2) { + framelen = 12; + } else if(frame->hd.version == SPDYLAY_PROTO_SPDY3) { + framelen = 16; + } else { + return SPDYLAY_ERR_UNSUPPORTED_VERSION; + } r = spdylay_reserve_buffer(buf_ptr, buflen_ptr, framelen); if(r != 0) { return r; @@ -651,6 +705,9 @@ ssize_t spdylay_frame_pack_goaway(uint8_t **buf_ptr, size_t *buflen_ptr, memset(*buf_ptr, 0, framelen); spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd); spdylay_put_uint32be(&(*buf_ptr)[8], frame->last_good_stream_id); + if(frame->hd.version == SPDYLAY_PROTO_SPDY3) { + spdylay_put_uint32be(&(*buf_ptr)[12], frame->status_code); + } return framelen; } @@ -658,16 +715,28 @@ int spdylay_frame_unpack_goaway(spdylay_goaway *frame, const uint8_t *head, size_t headlen, const uint8_t *payload, size_t payloadlen) { - if(payloadlen != 4) { - return SPDYLAY_ERR_INVALID_FRAME; - } spdylay_frame_unpack_ctrl_hd(&frame->hd, head); + if(frame->hd.version == SPDYLAY_PROTO_SPDY2) { + if(payloadlen != 4) { + return SPDYLAY_ERR_INVALID_FRAME; + } + } else if(frame->hd.version == SPDYLAY_PROTO_SPDY3) { + if(payloadlen != 8) { + return SPDYLAY_ERR_INVALID_FRAME; + } + } else { + return SPDYLAY_ERR_UNSUPPORTED_VERSION; + } frame->last_good_stream_id = spdylay_get_uint32(payload) & SPDYLAY_STREAM_ID_MASK; + if(frame->hd.version == SPDYLAY_PROTO_SPDY3) { + frame->status_code = spdylay_get_uint32(payload+4); + } return 0; } -#define SPDYLAY_HEADERS_NV_OFFSET 14 +#define SPDYLAY_SPDY2_HEADERS_NV_OFFSET 14 +#define SPDYLAY_SPDY3_HEADERS_NV_OFFSET 12 ssize_t spdylay_frame_pack_headers(uint8_t **buf_ptr, size_t *buflen_ptr, uint8_t **nvbuf_ptr, size_t *nvbuflen_ptr, @@ -675,17 +744,23 @@ ssize_t spdylay_frame_pack_headers(uint8_t **buf_ptr, size_t *buflen_ptr, spdylay_zlib *deflater) { ssize_t framelen; + size_t len_size; + size_t nv_offset; + len_size = spdylay_frame_get_len_size(frame->hd.version); + if(len_size == 0) { + return SPDYLAY_ERR_UNSUPPORTED_VERSION; + } + nv_offset = frame->hd.version == SPDYLAY_PROTO_SPDY2 ? + SPDYLAY_SPDY2_HEADERS_NV_OFFSET : SPDYLAY_SPDY3_HEADERS_NV_OFFSET; framelen = spdylay_frame_alloc_pack_nv(buf_ptr, buflen_ptr, nvbuf_ptr, nvbuflen_ptr, - frame->nv, - SPDYLAY_HEADERS_NV_OFFSET, - 2, - deflater); + frame->nv, nv_offset, + len_size, deflater); if(framelen < 0) { return framelen; } frame->hd.length = framelen-SPDYLAY_FRAME_HEAD_LENGTH; - memset(*buf_ptr, 0, SPDYLAY_HEADERS_NV_OFFSET); + memset(*buf_ptr, 0, nv_offset); spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd); spdylay_put_uint32be(&(*buf_ptr)[8], frame->stream_id); return framelen; @@ -700,16 +775,22 @@ int spdylay_frame_unpack_headers(spdylay_headers *frame, spdylay_zlib *inflater) { int r; + size_t len_size; + size_t nv_offset; if(payloadlen < 8) { return SPDYLAY_ERR_INVALID_FRAME; } spdylay_frame_unpack_ctrl_hd(&frame->hd, head); + len_size = spdylay_frame_get_len_size(frame->hd.version); + if(len_size == 0) { + return SPDYLAY_ERR_UNSUPPORTED_VERSION; + } + nv_offset = frame->hd.version == SPDYLAY_PROTO_SPDY2 ? 6 : 4; frame->stream_id = spdylay_get_uint32(payload) & SPDYLAY_STREAM_ID_MASK; r = spdylay_frame_alloc_unpack_nv(&frame->nv, inflatebuf, nvbuf_ptr, nvbuflen_ptr, - payload+6, payloadlen-6, - 2, - inflater); + payload+nv_offset, payloadlen-nv_offset, + len_size, inflater); return r; } diff --git a/lib/spdylay_frame.h b/lib/spdylay_frame.h index 99cdee66..07418953 100644 --- a/lib/spdylay_frame.h +++ b/lib/spdylay_frame.h @@ -60,6 +60,8 @@ * This function returns the size of packed frame if it succeeds, or * returns one of the following negative error codes: * + * SPDYLAY_ERR_UNSUPPORTED_VERSION + * The version is not supported. * SPDYLAY_ERR_ZLIB * The deflate operation failed. * SPDYLAY_ERR_NOMEM @@ -88,6 +90,8 @@ ssize_t spdylay_frame_pack_syn_stream(uint8_t **buf_ptr, * * SPDYLAY_ERR_INVALID_FRAME * The input data are invalid. + * SPDYLAY_ERR_UNSUPPORTED_VERSION + * The version is not supported. * SPDYLAY_ERR_ZLIB * The inflate operation failed. * SPDYLAY_ERR_NOMEM @@ -118,6 +122,8 @@ int spdylay_frame_unpack_syn_stream(spdylay_syn_stream *frame, * This function returns the size of packed frame if it succeeds, or * returns one of the following negative error codes: * + * SPDYLAY_ERR_UNSUPPORTED_VERSION + * The version is not supported. * SPDYLAY_ERR_ZLIB * The deflate operation failed. * SPDYLAY_ERR_NOMEM @@ -142,6 +148,8 @@ ssize_t spdylay_frame_pack_syn_reply(uint8_t **buf_ptr, * This function returns 0 if it succeeds or one of the following * negative error codes: * + * SPDYLAY_ERR_UNSUPPORTED_VERSION + * The version is not supported. * SPDYLAY_ERR_INVALID_FRAME * The input data are invalid. * SPDYLAY_ERR_ZLIB @@ -194,6 +202,8 @@ int spdylay_frame_unpack_ping(spdylay_ping *frame, * This function returns 0 if it succeeds or one of the following * negative error codes: * + * SPDYLAY_ERR_UNSUPPORTED_VERSION + * The version is not supported. * SPDYLAY_ERR_NOMEM * Out of memory. */ @@ -206,6 +216,8 @@ ssize_t spdylay_frame_pack_goaway(uint8_t **buf_ptr, size_t *buflen_ptr, * This function returns 0 if it succeeds or one of the following * negative error codes: * + * SPDYLAY_ERR_UNSUPPORTED_VERSION + * The version is not supported. * SPDYLAY_ERR_INVALID_FRAME * The input data are invalid. */ @@ -230,6 +242,8 @@ int spdylay_frame_unpack_goaway(spdylay_goaway *frame, * This function returns the size of packed frame if it succeeds, or * returns one of the following negative error codes: * + * SPDYLAY_ERR_UNSUPPORTED_VERSION + * The version is not supported. * SPDYLAY_ERR_ZLIB * The deflate operation failed. * SPDYLAY_ERR_NOMEM @@ -252,6 +266,8 @@ ssize_t spdylay_frame_pack_headers(uint8_t **buf_ptr, size_t *buflen_ptr, * This function returns 0 if it succeeds or one of the following * negative error codes: * + * SPDYLAY_ERR_UNSUPPORTED_VERSION + * The version is not supported. * SPDYLAY_ERR_INVALID_FRAME * The input data are invalid. * SPDYLAY_ERR_ZLIB diff --git a/lib/spdylay_session.c b/lib/spdylay_session.c index a3c98f21..3d16ac3e 100644 --- a/lib/spdylay_session.c +++ b/lib/spdylay_session.c @@ -95,11 +95,13 @@ static int spdylay_session_new(spdylay_session **session_ptr, (*session_ptr)->goaway_flags = SPDYLAY_GOAWAY_NONE; (*session_ptr)->last_good_stream_id = 0; - r = spdylay_zlib_deflate_hd_init(&(*session_ptr)->hd_deflater); + r = spdylay_zlib_deflate_hd_init(&(*session_ptr)->hd_deflater, + (*session_ptr)->version); if(r != 0) { goto fail_hd_deflater; } - r = spdylay_zlib_inflate_hd_init(&(*session_ptr)->hd_inflater); + r = spdylay_zlib_inflate_hd_init(&(*session_ptr)->hd_inflater, + (*session_ptr)->version); if(r != 0) { goto fail_hd_inflater; } @@ -163,7 +165,7 @@ static int spdylay_session_new(spdylay_session **session_ptr, fail_hd_deflater: free(*session_ptr); fail_session: - return SPDYLAY_ERR_NOMEM; + return r; } int spdylay_session_client_new(spdylay_session **session_ptr, @@ -474,8 +476,8 @@ static int spdylay_session_is_data_allowed(spdylay_session *session, } } -ssize_t spdylay_session_prep_frame(spdylay_session *session, - spdylay_outbound_item *item) +static ssize_t spdylay_session_prep_frame(spdylay_session *session, + spdylay_outbound_item *item) { /* TODO Get or validate stream ID here */ /* TODO Validate assoc_stream_id here */ diff --git a/lib/spdylay_zlib.c b/lib/spdylay_zlib.c index 623968e3..70ce1a1a 100644 --- a/lib/spdylay_zlib.c +++ b/lib/spdylay_zlib.c @@ -24,11 +24,13 @@ */ #include "spdylay_zlib.h" +#include + #define COMPRESSION_LEVEL 9 #define WINDOW_BITS 11 #define MEM_LEVEL 1 -static const char hd_dict[] = +static const char spdy2_hd_dict[] = "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-" "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi" "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser" @@ -43,30 +45,241 @@ static const char hd_dict[] = "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1" ".1statusversionurl"; -int spdylay_zlib_deflate_hd_init(spdylay_zlib *deflater) +static const uint8_t spdy3_hd_dict[] = { + 0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69, /* - - - - o p t i */ + 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, /* o n s - - - - h */ + 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70, /* e a d - - - - p */ + 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70, /* o s t - - - - p */ + 0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65, /* u t - - - - d e */ + 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05, /* l e t e - - - - */ + 0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00, /* t r a c e - - - */ + 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00, /* - a c c e p t - */ + 0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, /* - - - a c c e p */ + 0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, /* t - c h a r s e */ + 0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63, /* t - - - - a c c */ + 0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, /* e p t - e n c o */ + 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f, /* d i n g - - - - */ + 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c, /* a c c e p t - l */ + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, /* a n g u a g e - */ + 0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, /* - - - a c c e p */ + 0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, /* t - r a n g e s */ + 0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00, /* - - - - a g e - */ + 0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, /* - - - a l l o w */ + 0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68, /* - - - - a u t h */ + 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, /* o r i z a t i o */ + 0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63, /* n - - - - c a c */ + 0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, /* h e - c o n t r */ + 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, /* o l - - - - c o */ + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, /* n n e c t i o n */ + 0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, /* - - - - c o n t */ + 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65, /* e n t - b a s e */ + 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74, /* - - - - c o n t */ + 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, /* e n t - e n c o */ + 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, /* d i n g - - - - */ + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, /* c o n t e n t - */ + 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, /* l a n g u a g e */ + 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74, /* - - - - c o n t */ + 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, /* e n t - l e n g */ + 0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, /* t h - - - - c o */ + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f, /* n t e n t - l o */ + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, /* c a t i o n - - */ + 0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, /* - - c o n t e n */ + 0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00, /* t - m d 5 - - - */ + 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, /* - c o n t e n t */ + 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, /* - r a n g e - - */ + 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, /* - - c o n t e n */ + 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, /* t - t y p e - - */ + 0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00, /* - - d a t e - - */ + 0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00, /* - - e t a g - - */ + 0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, /* - - e x p e c t */ + 0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69, /* - - - - e x p i */ + 0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66, /* r e s - - - - f */ + 0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68, /* r o m - - - - h */ + 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69, /* o s t - - - - i */ + 0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, /* f - m a t c h - */ + 0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f, /* - - - i f - m o */ + 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73, /* d i f i e d - s */ + 0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d, /* i n c e - - - - */ + 0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d, /* i f - n o n e - */ + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00, /* m a t c h - - - */ + 0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67, /* - i f - r a n g */ + 0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d, /* e - - - - i f - */ + 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, /* u n m o d i f i */ + 0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65, /* e d - s i n c e */ + 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74, /* - - - - l a s t */ + 0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, /* - m o d i f i e */ + 0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63, /* d - - - - l o c */ + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, /* a t i o n - - - */ + 0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72, /* - m a x - f o r */ + 0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00, /* w a r d s - - - */ + 0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00, /* - p r a g m a - */ + 0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79, /* - - - p r o x y */ + 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, /* - a u t h e n t */ + 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, /* i c a t e - - - */ + 0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, /* - p r o x y - a */ + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, /* u t h o r i z a */ + 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05, /* t i o n - - - - */ + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, /* r a n g e - - - */ + 0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, /* - r e f e r e r */ + 0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72, /* - - - - r e t r */ + 0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00, /* y - a f t e r - */ + 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, /* - - - s e r v e */ + 0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00, /* r - - - - t e - */ + 0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c, /* - - - t r a i l */ + 0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72, /* e r - - - - t r */ + 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65, /* a n s f e r - e */ + 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, /* n c o d i n g - */ + 0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, /* - - - u p g r a */ + 0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73, /* d e - - - - u s */ + 0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, /* e r - a g e n t */ + 0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79, /* - - - - v a r y */ + 0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00, /* - - - - v i a - */ + 0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, /* - - - w a r n i */ + 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77, /* n g - - - - w w */ + 0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, /* w - a u t h e n */ + 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, /* t i c a t e - - */ + 0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, /* - - m e t h o d */ + 0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, /* - - - - g e t - */ + 0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, /* - - - s t a t u */ + 0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30, /* s - - - - 2 0 0 */ + 0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76, /* - O K - - - - v */ + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, /* e r s i o n - - */ + 0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, /* - - H T T P - 1 */ + 0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72, /* - 1 - - - - u r */ + 0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62, /* l - - - - p u b */ + 0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73, /* l i c - - - - s */ + 0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69, /* e t - c o o k i */ + 0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65, /* e - - - - k e e */ + 0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00, /* p - a l i v e - */ + 0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, /* - - - o r i g i */ + 0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32, /* n 1 0 0 1 0 1 2 */ + 0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35, /* 0 1 2 0 2 2 0 5 */ + 0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30, /* 2 0 6 3 0 0 3 0 */ + 0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33, /* 2 3 0 3 3 0 4 3 */ + 0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37, /* 0 5 3 0 6 3 0 7 */ + 0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30, /* 4 0 2 4 0 5 4 0 */ + 0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34, /* 6 4 0 7 4 0 8 4 */ + 0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31, /* 0 9 4 1 0 4 1 1 */ + 0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31, /* 4 1 2 4 1 3 4 1 */ + 0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34, /* 4 4 1 5 4 1 6 4 */ + 0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34, /* 1 7 5 0 2 5 0 4 */ + 0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e, /* 5 0 5 2 0 3 - N */ + 0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f, /* o n - A u t h o */ + 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, /* r i t a t i v e */ + 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, /* - I n f o r m a */ + 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20, /* t i o n 2 0 4 - */ + 0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, /* N o - C o n t e */ + 0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f, /* n t 3 0 1 - M o */ + 0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d, /* v e d - P e r m */ + 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34, /* a n e n t l y 4 */ + 0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52, /* 0 0 - B a d - R */ + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30, /* e q u e s t 4 0 */ + 0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, /* 1 - U n a u t h */ + 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30, /* o r i z e d 4 0 */ + 0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, /* 3 - F o r b i d */ + 0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e, /* d e n 4 0 4 - N */ + 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, /* o t - F o u n d */ + 0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65, /* 5 0 0 - I n t e */ + 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, /* r n a l - S e r */ + 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, /* v e r - E r r o */ + 0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74, /* r 5 0 1 - N o t */ + 0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, /* - I m p l e m e */ + 0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20, /* n t e d 5 0 3 - */ + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, /* S e r v i c e - */ + 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, /* U n a v a i l a */ + 0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46, /* b l e J a n - F */ + 0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41, /* e b - M a r - A */ + 0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a, /* p r - M a y - J */ + 0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41, /* u n - J u l - A */ + 0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20, /* u g - S e p t - */ + 0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20, /* O c t - N o v - */ + 0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30, /* D e c - 0 0 - 0 */ + 0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e, /* 0 - 0 0 - M o n */ + 0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57, /* - - T u e - - W */ + 0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c, /* e d - - T h u - */ + 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61, /* - F r i - - S a */ + 0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20, /* t - - S u n - - */ + 0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b, /* G M T c h u n k */ + 0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, /* e d - t e x t - */ + 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61, /* h t m l - i m a */ + 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69, /* g e - p n g - i */ + 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67, /* m a g e - j p g */ + 0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, /* - i m a g e - g */ + 0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, /* i f - a p p l i */ + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, /* c a t i o n - x */ + 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, /* m l - a p p l i */ + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, /* c a t i o n - x */ + 0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c, /* h t m l - x m l */ + 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, /* - t e x t - p l */ + 0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74, /* a i n - t e x t */ + 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, /* - j a v a s c r */ + 0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c, /* i p t - p u b l */ + 0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, /* i c p r i v a t */ + 0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, /* e m a x - a g e */ + 0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65, /* - g z i p - d e */ + 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, /* f l a t e - s d */ + 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, /* c h c h a r s e */ + 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63, /* t - u t f - 8 c */ + 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69, /* h a r s e t - i */ + 0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, /* s o - 8 8 5 9 - */ + 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a, /* 1 - u t f - - - */ + 0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e /* - e n q - 0 - */ +}; + +static const uint8_t* spdylay_select_hd_dict(size_t *len_ptr, uint16_t version) { + const uint8_t *hd_dict; + hd_dict = NULL; + if(version == SPDYLAY_PROTO_SPDY2) { + hd_dict = (const uint8_t*)spdy2_hd_dict; + *len_ptr = sizeof(spdy2_hd_dict); + } else if(version == SPDYLAY_PROTO_SPDY3) { + hd_dict = spdy3_hd_dict; + *len_ptr = sizeof(spdy3_hd_dict); + } + return hd_dict; +} + +int spdylay_zlib_deflate_hd_init(spdylay_zlib *deflater, uint16_t version) +{ + const unsigned char *hd_dict; + size_t hd_dict_length; deflater->zst.next_in = Z_NULL; deflater->zst.zalloc = Z_NULL; deflater->zst.zfree = Z_NULL; deflater->zst.opaque = Z_NULL; + deflater->version = version; + hd_dict = spdylay_select_hd_dict(&hd_dict_length, version); + if(hd_dict == NULL) { + return SPDYLAY_ERR_UNSUPPORTED_VERSION; + } if(Z_OK != deflateInit2(&deflater->zst, COMPRESSION_LEVEL, Z_DEFLATED, WINDOW_BITS, MEM_LEVEL, Z_DEFAULT_STRATEGY)) { return SPDYLAY_ERR_ZLIB; } if(Z_OK != deflateSetDictionary(&deflater->zst, (uint8_t*)hd_dict, - sizeof(hd_dict))) { + hd_dict_length)) { + spdylay_zlib_deflate_free(deflater); return SPDYLAY_ERR_ZLIB; } return 0; } -int spdylay_zlib_inflate_hd_init(spdylay_zlib *inflater) +int spdylay_zlib_inflate_hd_init(spdylay_zlib *inflater, uint16_t version) { + const unsigned char *hd_dict; + size_t hd_dict_length; inflater->zst.next_in = Z_NULL; inflater->zst.avail_in = 0; inflater->zst.zalloc = Z_NULL; inflater->zst.zfree = Z_NULL; + inflater->version = version; + hd_dict = spdylay_select_hd_dict(&hd_dict_length, version); + if(hd_dict == NULL) { + return SPDYLAY_ERR_UNSUPPORTED_VERSION; + } if(Z_OK != inflateInit(&inflater->zst)) { + spdylay_zlib_inflate_free(inflater); return SPDYLAY_ERR_ZLIB; } return 0; @@ -123,8 +336,12 @@ ssize_t spdylay_zlib_inflate_hd(spdylay_zlib *inflater, if(r == Z_STREAM_ERROR || r == Z_STREAM_END || r == Z_DATA_ERROR) { return SPDYLAY_ERR_ZLIB; } else if(r == Z_NEED_DICT) { + const uint8_t *hd_dict; + size_t hd_dict_length; + hd_dict = spdylay_select_hd_dict(&hd_dict_length, inflater->version); + assert(hd_dict); if(Z_OK != inflateSetDictionary(&inflater->zst, (uint8_t*)hd_dict, - sizeof(hd_dict))) { + hd_dict_length)) { return SPDYLAY_ERR_ZLIB; } } else { diff --git a/lib/spdylay_zlib.h b/lib/spdylay_zlib.h index 3ca3dca1..c26f2a97 100644 --- a/lib/spdylay_zlib.h +++ b/lib/spdylay_zlib.h @@ -35,31 +35,37 @@ /* This structure is used for both deflater and inflater. */ typedef struct { z_stream zst; + /* The protocol version to select the dictionary later. */ + uint16_t version; } spdylay_zlib; /* * Initializes |deflater| for deflating name/values pairs in the - * frame. + * frame of the protocol version |version|. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * * SPDYLAY_ERR_ZLIB * The z_stream initialization failed. + * SPDYLAY_ERR_UNSUPPORTED_VERSION + * The version is not supported. */ -int spdylay_zlib_deflate_hd_init(spdylay_zlib *deflater); +int spdylay_zlib_deflate_hd_init(spdylay_zlib *deflater, uint16_t version); /* * Initializes |inflater| for inflating name/values pairs in the - * frame. + * frame of the protocol version |version|. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * * SPDYLAY_ERR_ZLIB * The z_stream initialization failed. + * SPDYLAY_ERR_UNSUPPORTED_VERSION + * The version is not supported. */ -int spdylay_zlib_inflate_hd_init(spdylay_zlib *inflater); +int spdylay_zlib_inflate_hd_init(spdylay_zlib *inflater, uint16_t version); /* * Deallocates any resources allocated for |deflater|. diff --git a/tests/main.c b/tests/main.c index b682e2ab..6786cbaf 100644 --- a/tests/main.c +++ b/tests/main.c @@ -67,7 +67,8 @@ int main(int argc, char* argv[]) !CU_add_test(pSuite, "map", test_spdylay_map) || !CU_add_test(pSuite, "queue", test_spdylay_queue) || !CU_add_test(pSuite, "buffer", test_spdylay_buffer) || - !CU_add_test(pSuite, "zlib", test_spdylay_zlib) || + !CU_add_test(pSuite, "zlib_spdy2", test_spdylay_zlib_spdy2) || + !CU_add_test(pSuite, "zlib_spdy3", test_spdylay_zlib_spdy3) || !CU_add_test(pSuite, "npn", test_spdylay_npn) || !CU_add_test(pSuite, "session_recv", test_spdylay_session_recv) || !CU_add_test(pSuite, "session_recv_invalid_stream_id", @@ -138,6 +139,10 @@ int main(int argc, char* argv[]) !CU_add_test(pSuite, "frame_pack_ping", test_spdylay_frame_pack_ping) || !CU_add_test(pSuite, "frame_pack_goaway", test_spdylay_frame_pack_goaway) || + !CU_add_test(pSuite, "frame_pack_syn_stream", + test_spdylay_frame_pack_syn_stream) || + !CU_add_test(pSuite, "frame_pack_syn_reply", + test_spdylay_frame_pack_syn_reply) || !CU_add_test(pSuite, "frame_pack_headers", test_spdylay_frame_pack_headers) || !CU_add_test(pSuite, "frame_pack_settings", diff --git a/tests/spdylay_frame_test.c b/tests/spdylay_frame_test.c index a0ec1501..186137ef 100644 --- a/tests/spdylay_frame_test.c +++ b/tests/spdylay_frame_test.c @@ -39,11 +39,10 @@ static const char *headers[] = { NULL }; -void test_spdylay_frame_unpack_nv() +void test_spdylay_frame_unpack_nv_with(size_t len_size) { uint8_t out[1024]; char **nv; - size_t len_size = 2; size_t inlen = spdylay_frame_pack_nv(out, (char**)headers, len_size); CU_ASSERT(0 == spdylay_frame_unpack_nv(&nv, out, inlen, len_size)); CU_ASSERT(strcmp("method", nv[0]) == 0); @@ -61,6 +60,12 @@ void test_spdylay_frame_unpack_nv() spdylay_frame_nv_del(nv); } +void test_spdylay_frame_unpack_nv() +{ + test_spdylay_frame_unpack_nv_with(2); + test_spdylay_frame_unpack_nv_with(4); +} + void test_spdylay_frame_pack_nv_duplicate_keys() { uint8_t out[1024]; @@ -151,6 +156,8 @@ void test_spdylay_frame_count_nv_space() { size_t len_size = 2; CU_ASSERT(74 == spdylay_frame_count_nv_space((char**)headers, len_size)); + len_size = 4; + CU_ASSERT(96 == spdylay_frame_count_nv_space((char**)headers, len_size)); } void test_spdylay_frame_count_unpack_nv_space() @@ -232,7 +239,7 @@ void test_spdylay_frame_pack_goaway() spdylay_frame_goaway_free(&frame.goaway); } -void test_spdylay_frame_pack_headers() +void test_spdylay_frame_pack_syn_stream_with(uint16_t version) { spdylay_zlib deflater, inflater; spdylay_frame frame, oframe; @@ -241,9 +248,106 @@ void test_spdylay_frame_pack_headers() spdylay_buffer inflatebuf; ssize_t framelen; spdylay_buffer_init(&inflatebuf, 4096); - spdylay_zlib_deflate_hd_init(&deflater); - spdylay_zlib_inflate_hd_init(&inflater); - spdylay_frame_headers_init(&frame.headers, SPDYLAY_PROTO_SPDY2, + spdylay_zlib_deflate_hd_init(&deflater, version); + spdylay_zlib_inflate_hd_init(&inflater, version); + spdylay_frame_syn_stream_init(&frame.syn_stream, version, + SPDYLAY_CTRL_FLAG_FIN, 65536, 1000000007, 3, + spdylay_frame_nv_copy(headers)); + framelen = spdylay_frame_pack_syn_stream(&buf, &buflen, + &nvbuf, &nvbuflen, + &frame.syn_stream, &deflater); + CU_ASSERT(0 == spdylay_frame_unpack_syn_stream + (&oframe.syn_stream, + &inflatebuf, + &nvbuf, &nvbuflen, + &buf[0], SPDYLAY_FRAME_HEAD_LENGTH, + &buf[SPDYLAY_FRAME_HEAD_LENGTH], + framelen-SPDYLAY_FRAME_HEAD_LENGTH, + &inflater)); + CU_ASSERT(65536 == oframe.syn_stream.stream_id); + CU_ASSERT(1000000007 == oframe.syn_stream.assoc_stream_id); + CU_ASSERT(version == oframe.syn_stream.hd.version); + CU_ASSERT(SPDYLAY_SYN_STREAM == oframe.syn_stream.hd.type); + CU_ASSERT(SPDYLAY_CTRL_FLAG_FIN == oframe.syn_stream.hd.flags); + CU_ASSERT(framelen-SPDYLAY_FRAME_HEAD_LENGTH == oframe.ping.hd.length); + CU_ASSERT(strcmp("method", oframe.syn_stream.nv[0]) == 0); + CU_ASSERT(strcmp("GET", oframe.syn_stream.nv[1]) == 0); + CU_ASSERT(NULL == oframe.syn_stream.nv[12]); + free(buf); + free(nvbuf); + spdylay_frame_syn_stream_free(&oframe.syn_stream); + spdylay_frame_syn_stream_free(&frame.syn_stream); + spdylay_zlib_inflate_free(&inflater); + spdylay_zlib_deflate_free(&deflater); + spdylay_buffer_free(&inflatebuf); +} + +void test_spdylay_frame_pack_syn_stream() +{ + test_spdylay_frame_pack_syn_stream_with(SPDYLAY_PROTO_SPDY2); + test_spdylay_frame_pack_syn_stream_with(SPDYLAY_PROTO_SPDY3); +} + +void test_spdylay_frame_pack_syn_reply_with(uint16_t version) +{ + spdylay_zlib deflater, inflater; + spdylay_frame frame, oframe; + uint8_t *buf = NULL, *nvbuf = NULL; + size_t buflen = 0, nvbuflen = 0; + spdylay_buffer inflatebuf; + ssize_t framelen; + spdylay_buffer_init(&inflatebuf, 4096); + spdylay_zlib_deflate_hd_init(&deflater, version); + spdylay_zlib_inflate_hd_init(&inflater, version); + spdylay_frame_syn_reply_init(&frame.syn_reply, version, + SPDYLAY_CTRL_FLAG_FIN, 3, + spdylay_frame_nv_copy(headers)); + framelen = spdylay_frame_pack_syn_reply(&buf, &buflen, + &nvbuf, &nvbuflen, + &frame.syn_reply, &deflater); + CU_ASSERT(0 == spdylay_frame_unpack_syn_reply + (&oframe.syn_reply, + &inflatebuf, + &nvbuf, &nvbuflen, + &buf[0], SPDYLAY_FRAME_HEAD_LENGTH, + &buf[SPDYLAY_FRAME_HEAD_LENGTH], + framelen-SPDYLAY_FRAME_HEAD_LENGTH, + &inflater)); + CU_ASSERT(3 == oframe.syn_reply.stream_id); + CU_ASSERT(version == oframe.syn_reply.hd.version); + CU_ASSERT(SPDYLAY_SYN_REPLY == oframe.syn_reply.hd.type); + CU_ASSERT(SPDYLAY_CTRL_FLAG_FIN == oframe.syn_reply.hd.flags); + CU_ASSERT(framelen-SPDYLAY_FRAME_HEAD_LENGTH == oframe.ping.hd.length); + CU_ASSERT(strcmp("method", oframe.syn_reply.nv[0]) == 0); + CU_ASSERT(strcmp("GET", oframe.syn_reply.nv[1]) == 0); + CU_ASSERT(NULL == oframe.syn_reply.nv[12]); + free(buf); + free(nvbuf); + spdylay_frame_syn_reply_free(&oframe.syn_reply); + spdylay_frame_syn_reply_free(&frame.syn_reply); + spdylay_zlib_inflate_free(&inflater); + spdylay_zlib_deflate_free(&deflater); + spdylay_buffer_free(&inflatebuf); +} + +void test_spdylay_frame_pack_syn_reply() +{ + test_spdylay_frame_pack_syn_reply_with(SPDYLAY_PROTO_SPDY2); + test_spdylay_frame_pack_syn_reply_with(SPDYLAY_PROTO_SPDY3); +} + +void test_spdylay_frame_pack_headers_with(uint16_t version) +{ + spdylay_zlib deflater, inflater; + spdylay_frame frame, oframe; + uint8_t *buf = NULL, *nvbuf = NULL; + size_t buflen = 0, nvbuflen = 0; + spdylay_buffer inflatebuf; + ssize_t framelen; + spdylay_buffer_init(&inflatebuf, 4096); + spdylay_zlib_deflate_hd_init(&deflater, version); + spdylay_zlib_inflate_hd_init(&inflater, version); + spdylay_frame_headers_init(&frame.headers, version, SPDYLAY_CTRL_FLAG_FIN, 3, spdylay_frame_nv_copy(headers)); framelen = spdylay_frame_pack_headers(&buf, &buflen, @@ -258,7 +362,7 @@ void test_spdylay_frame_pack_headers() framelen-SPDYLAY_FRAME_HEAD_LENGTH, &inflater)); CU_ASSERT(3 == oframe.headers.stream_id); - CU_ASSERT(SPDYLAY_PROTO_SPDY2 == oframe.headers.hd.version); + CU_ASSERT(version == oframe.headers.hd.version); CU_ASSERT(SPDYLAY_HEADERS == oframe.headers.hd.type); CU_ASSERT(SPDYLAY_CTRL_FLAG_FIN == oframe.headers.hd.flags); CU_ASSERT(framelen-SPDYLAY_FRAME_HEAD_LENGTH == oframe.ping.hd.length); @@ -274,6 +378,12 @@ void test_spdylay_frame_pack_headers() spdylay_buffer_free(&inflatebuf); } +void test_spdylay_frame_pack_headers() +{ + test_spdylay_frame_pack_headers_with(SPDYLAY_PROTO_SPDY2); + test_spdylay_frame_pack_headers_with(SPDYLAY_PROTO_SPDY3); +} + void test_spdylay_frame_pack_settings() { spdylay_frame frame, oframe; diff --git a/tests/spdylay_frame_test.h b/tests/spdylay_frame_test.h index 7c62e836..3c30e5e8 100644 --- a/tests/spdylay_frame_test.h +++ b/tests/spdylay_frame_test.h @@ -31,6 +31,8 @@ void test_spdylay_frame_count_nv_space(); void test_spdylay_frame_count_unpack_nv_space(); void test_spdylay_frame_pack_ping(); void test_spdylay_frame_pack_goaway(); +void test_spdylay_frame_pack_syn_stream(); +void test_spdylay_frame_pack_syn_reply(); void test_spdylay_frame_pack_headers(); void test_spdylay_frame_pack_settings(); void test_spdylay_frame_nv_sort(); diff --git a/tests/spdylay_zlib_test.c b/tests/spdylay_zlib_test.c index 9fced8c1..b7dfa133 100644 --- a/tests/spdylay_zlib_test.c +++ b/tests/spdylay_zlib_test.c @@ -30,7 +30,7 @@ #include "spdylay_zlib.h" -void test_spdylay_zlib() +void test_spdylay_zlib_with(uint16_t version) { spdylay_zlib deflater, inflater; const char msg[] = @@ -53,8 +53,8 @@ void test_spdylay_zlib() deflatebuf_max = spdylay_zlib_deflate_hd_bound(&deflater, sizeof(msg)); deflatebuf = malloc(deflatebuf_max); - CU_ASSERT(0 == spdylay_zlib_deflate_hd_init(&deflater)); - CU_ASSERT(0 == spdylay_zlib_inflate_hd_init(&inflater)); + CU_ASSERT(0 == spdylay_zlib_deflate_hd_init(&deflater, version)); + CU_ASSERT(0 == spdylay_zlib_inflate_hd_init(&inflater, version)); CU_ASSERT(0 < (deflatebuf_len = spdylay_zlib_deflate_hd (&deflater, deflatebuf, deflatebuf_max, @@ -69,3 +69,13 @@ void test_spdylay_zlib() spdylay_buffer_free(&buf); } + +void test_spdylay_zlib_spdy2() +{ + test_spdylay_zlib_with(SPDYLAY_PROTO_SPDY2); +} + +void test_spdylay_zlib_spdy3() +{ + test_spdylay_zlib_with(SPDYLAY_PROTO_SPDY3); +} diff --git a/tests/spdylay_zlib_test.h b/tests/spdylay_zlib_test.h index 94d08501..b610663e 100644 --- a/tests/spdylay_zlib_test.h +++ b/tests/spdylay_zlib_test.h @@ -25,6 +25,7 @@ #ifndef SPDYLAY_ZLIB_TEST_H #define SPDYLAY_ZLIB_TEST_H -void test_spdylay_zlib(); +void test_spdylay_zlib_spdy2(); +void test_spdylay_zlib_spdy3(); #endif // SPDYLAY_ZLIB_TEST_H