Added HEADERS frame. Added SPDYLAY_FRAME_HEAD_LENGTH.

This commit is contained in:
Tatsuhiro Tsujikawa 2012-01-27 18:21:14 +09:00
parent 83b4e245d9
commit 1c0ec66a2b
6 changed files with 112 additions and 1 deletions

View File

@ -63,6 +63,7 @@ typedef enum {
SPDYLAY_NOOP = 5,
SPDYLAY_PING = 6,
SPDYLAY_GOAWAY = 7,
SPDYLAY_HEADERS = 8,
SPDYLAY_DATA = 100,
} spdylay_frame_type;
@ -104,6 +105,12 @@ typedef struct {
char **nv;
} spdylay_syn_reply;
typedef struct {
spdylay_ctrl_hd hd;
int32_t stream_id;
char **nv;
} spdylay_headers;
typedef struct {
spdylay_ctrl_hd hd;
int32_t stream_id;
@ -134,6 +141,7 @@ typedef union {
spdylay_syn_stream syn_stream;
spdylay_syn_reply syn_reply;
spdylay_rst_stream rst_stream;
spdylay_headers headers;
spdylay_data data;
} spdylay_frame;

View File

@ -374,6 +374,23 @@ void spdylay_frame_syn_reply_free(spdylay_syn_reply *frame)
free(frame->nv);
}
void spdylay_frame_headers_init(spdylay_headers *frame, uint8_t flags,
int32_t stream_id, char **nv)
{
memset(frame, 0, sizeof(spdylay_headers));
frame->hd.version = 2;
frame->hd.type = SPDYLAY_HEADERS;
frame->hd.flags = flags;
frame->stream_id = stream_id;
frame->nv = nv;
}
void spdylay_frame_headers_free(spdylay_headers *frame)
{
spdylay_frame_nv_free(frame->nv);
free(frame->nv);
}
void spdylay_frame_rst_stream_init(spdylay_rst_stream *frame,
int32_t stream_id, uint32_t status_code)
{
@ -472,6 +489,39 @@ int spdylay_frame_unpack_syn_reply(spdylay_syn_reply *frame,
return r;
}
#define SPDYLAY_HEADERS_NV_OFFSET 14
ssize_t spdylay_frame_pack_headers(uint8_t **buf_ptr,
spdylay_headers *frame,
spdylay_zlib *deflater)
{
uint8_t *framebuf = NULL;
ssize_t framelen;
framelen = spdylay_frame_alloc_pack_nv(&framebuf, frame->nv,
SPDYLAY_HEADERS_NV_OFFSET, deflater);
if(framelen < 0) {
return framelen;
}
frame->hd.length = framelen-SPDYLAY_FRAME_HEAD_LENGTH;
memset(framebuf, 0, SPDYLAY_HEADERS_NV_OFFSET);
spdylay_frame_pack_ctrl_hd(framebuf, &frame->hd);
spdylay_put_uint32be(&framebuf[8], frame->stream_id);
*buf_ptr = framebuf;
return framelen;
}
int spdylay_frame_unpack_headers(spdylay_headers *frame,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen,
spdylay_zlib *inflater)
{
int r;
spdylay_frame_unpack_ctrl_hd(&frame->hd, head);
frame->stream_id = spdylay_get_uint32(payload) & SPDYLAY_STREAM_ID_MASK;
r = spdylay_frame_alloc_unpack_nv(&frame->nv, payload+6, payloadlen-6,
inflater);
}
ssize_t spdylay_frame_pack_rst_stream(uint8_t **buf_ptr,
spdylay_rst_stream *frame)
{

View File

@ -39,6 +39,9 @@
#define SPDYLAY_DATA_FRAME_LENGTH 4096
/* The number of bytes of frame header. */
#define SPDYLAY_FRAME_HEAD_LENGTH 8
/*
* Packs SYN_STREAM frame |frame| in wire frame format and store it in
* |*buf_ptr|. This function allocates enough memory to store given
@ -82,6 +85,25 @@ int spdylay_frame_unpack_syn_reply(spdylay_syn_reply *frame,
const uint8_t *payload, size_t payloadlen,
spdylay_zlib *inflater);
/*
* Packs HEADERS frame |frame| in wire format and store it in
* |*buf_ptr|. This function allocates enough memory in |*buf_ptr| to
* store given |frame|. This function returns the size of packed frame
* it it succeeds, or returns negative error code. frame->hd.length is
* assigned after length is determined during packing process.
*/
ssize_t spdylay_frame_pack_headers(uint8_t **buf_ptr,
spdylay_headers *frame,
spdylay_zlib *deflater);
/*
* Unpacks HEADERS wire format into |frame|. This function returns 0
* if it succeeds or negative error code.
*/
int spdylay_frame_unpack_headers(spdylay_headers *frame,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen,
spdylay_zlib *inflater);
/*
* Packs RST_STREAM frame |frame| in wire frame format and store it in
* |*buf_ptr|. This function allocates enough memory to store given
@ -138,6 +160,11 @@ void spdylay_frame_syn_reply_init(spdylay_syn_reply *frame, uint8_t flags,
void spdylay_frame_syn_reply_free(spdylay_syn_reply *frame);
void spdylay_frame_headers_init(spdylay_headers *frame, uint8_t flags,
int32_t stream_id, char **nv);
void spdylay_frame_headers_free(spdylay_headers *frame);
void spdylay_frame_rst_stream_init(spdylay_rst_stream *frame,
int32_t stream_id, uint32_t status_code);

View File

@ -84,7 +84,9 @@ int main()
test_spdylay_session_reply_fail) ||
!CU_add_test(pSuite, "frame_unpack_nv", test_spdylay_frame_unpack_nv) ||
!CU_add_test(pSuite, "frame_count_nv_space",
test_spdylay_frame_count_nv_space)) {
test_spdylay_frame_count_nv_space) ||
!CU_add_test(pSuite, "frame_pack_headers",
test_spdylay_frame_pack_headers)) {
CU_cleanup_registry();
return CU_get_error();
}

View File

@ -53,3 +53,26 @@ void test_spdylay_frame_count_nv_space()
CU_ASSERT(83 == spdylay_frame_count_nv_space((char**)headers));
}
void test_spdylay_frame_pack_headers()
{
spdylay_zlib deflater, inflater;
spdylay_frame frame, oframe;
uint8_t *buf;
ssize_t buflen;
spdylay_zlib_deflate_hd_init(&deflater);
spdylay_zlib_inflate_hd_init(&inflater);
spdylay_frame_headers_init(&frame.headers, SPDYLAY_FLAG_FIN, 3,
spdylay_frame_nv_copy(headers));
buflen = spdylay_frame_pack_headers(&buf, &frame.headers, &deflater);
CU_ASSERT(0 == spdylay_frame_unpack_headers
(&oframe.headers,
&buf[0], SPDYLAY_FRAME_HEAD_LENGTH,
&buf[SPDYLAY_FRAME_HEAD_LENGTH],
buflen-SPDYLAY_FRAME_HEAD_LENGTH,
&inflater));
free(buf);
spdylay_frame_headers_free(&oframe.headers);
spdylay_frame_headers_free(&frame.headers);
spdylay_zlib_inflate_free(&inflater);
spdylay_zlib_deflate_free(&deflater);
}

View File

@ -27,5 +27,6 @@
void test_spdylay_frame_unpack_nv();
void test_spdylay_frame_count_nv_space();
void test_spdylay_frame_pack_headers();
#endif /* SPDYLAY_FRAME_TEST_H */