Reuse buffers when unpacking frames.

This commit is contained in:
Tatsuhiro Tsujikawa 2012-02-16 22:01:34 +09:00
parent 050f33e8f9
commit ac1629e61b
9 changed files with 160 additions and 96 deletions

View File

@ -29,7 +29,9 @@
void spdylay_buffer_init(spdylay_buffer *buffer, size_t chunk_capacity) void spdylay_buffer_init(spdylay_buffer *buffer, size_t chunk_capacity)
{ {
spdylay_queue_init(&buffer->q); buffer->root.data = NULL;
buffer->root.next = NULL;
buffer->current = &buffer->root;
buffer->capacity = chunk_capacity; buffer->capacity = chunk_capacity;
buffer->len = 0; buffer->len = 0;
/* /*
@ -41,22 +43,35 @@ void spdylay_buffer_init(spdylay_buffer *buffer, size_t chunk_capacity)
void spdylay_buffer_free(spdylay_buffer *buffer) void spdylay_buffer_free(spdylay_buffer *buffer)
{ {
while(!spdylay_queue_empty(&buffer->q)) { spdylay_buffer_chunk *p = buffer->root.next;
free(spdylay_queue_front(&buffer->q)); while(p) {
spdylay_queue_pop(&buffer->q); spdylay_buffer_chunk *next = p->next;
free(p->data);
free(p);
p = next;
} }
} }
int spdylay_buffer_alloc(spdylay_buffer *buffer) int spdylay_buffer_alloc(spdylay_buffer *buffer)
{ {
int r; if(buffer->current->next == NULL) {
uint8_t *buf = (uint8_t*)malloc(buffer->capacity); spdylay_buffer_chunk *chunk;
if(buf == NULL) { uint8_t *buf;
chunk = malloc(sizeof(spdylay_buffer_chunk));
if(chunk == NULL) {
return SPDYLAY_ERR_NOMEM; return SPDYLAY_ERR_NOMEM;
} }
if((r = spdylay_queue_push(&buffer->q, buf)) != 0) { buf = malloc(buffer->capacity);
free(buf); if(buf == NULL) {
return r; free(chunk);
return SPDYLAY_ERR_NOMEM;
}
chunk->data = buf;
chunk->next = NULL;
buffer->current->next = chunk;
buffer->current = chunk;
} else {
buffer->current = buffer->current->next;
} }
buffer->len += buffer->capacity-buffer->last_offset; buffer->len += buffer->capacity-buffer->last_offset;
buffer->last_offset = 0; buffer->last_offset = 0;
@ -65,10 +80,10 @@ int spdylay_buffer_alloc(spdylay_buffer *buffer)
uint8_t* spdylay_buffer_get(spdylay_buffer *buffer) uint8_t* spdylay_buffer_get(spdylay_buffer *buffer)
{ {
if(spdylay_queue_empty(&buffer->q)) { if(buffer->current->data == NULL) {
return NULL; return NULL;
} else { } else {
return spdylay_queue_back(&buffer->q)+buffer->last_offset; return buffer->current->data+buffer->last_offset;
} }
} }
@ -89,40 +104,6 @@ size_t spdylay_buffer_length(spdylay_buffer *buffer)
return buffer->len; return buffer->len;
} }
size_t spdylay_buffer_front_length(spdylay_buffer *buffer)
{
if(spdylay_queue_empty(&buffer->q)) {
return 0;
} else if(buffer->len >= buffer->capacity) {
return buffer->capacity;
} else {
return buffer->len;
}
}
uint8_t* spdylay_buffer_front_data(spdylay_buffer *buffer)
{
if(spdylay_queue_empty(&buffer->q)) {
return NULL;
} else {
return spdylay_queue_front(&buffer->q);
}
}
void spdylay_buffer_pop(spdylay_buffer *buffer)
{
if(!spdylay_queue_empty(&buffer->q)) {
if(buffer->len >= buffer->capacity) {
buffer->len -= buffer->capacity;
} else {
buffer->len = 0;
buffer->last_offset = buffer->capacity;
}
free(spdylay_queue_front(&buffer->q));
spdylay_queue_pop(&buffer->q);
}
}
size_t spdylay_buffer_capacity(spdylay_buffer *buffer) size_t spdylay_buffer_capacity(spdylay_buffer *buffer)
{ {
return buffer->capacity; return buffer->capacity;
@ -130,10 +111,22 @@ size_t spdylay_buffer_capacity(spdylay_buffer *buffer)
void spdylay_buffer_serialize(spdylay_buffer *buffer, uint8_t *buf) void spdylay_buffer_serialize(spdylay_buffer *buffer, uint8_t *buf)
{ {
while(spdylay_buffer_length(buffer)) { spdylay_buffer_chunk *p = buffer->root.next;
size_t len = spdylay_buffer_front_length(buffer); for(; p; p = p->next) {
memcpy(buf, spdylay_buffer_front_data(buffer), len); size_t len;
if(p == buffer->current) {
len = buffer->last_offset;
} else {
len = buffer->capacity;
}
memcpy(buf, p->data, len);
buf += len; buf += len;
spdylay_buffer_pop(buffer);
} }
} }
void spdylay_buffer_reset(spdylay_buffer *buffer)
{
buffer->current = &buffer->root;
buffer->len = 0;
buffer->last_offset = buffer->capacity;
}

View File

@ -32,14 +32,22 @@
#include <spdylay/spdylay.h> #include <spdylay/spdylay.h>
#include "spdylay_queue.h" #include "spdylay_queue.h"
typedef struct spdylay_buffer_chunk {
uint8_t *data;
struct spdylay_buffer_chunk *next;
} spdylay_buffer_chunk;
/* /*
* Fixed sized buffers backed by queue. * List of fixed sized chunks
*/ */
typedef struct { typedef struct {
/* Capacity of each chunk buffer */ /* Capacity of each chunk buffer */
size_t capacity; size_t capacity;
/* Queue of chunk buffers */ /* Root of list of chunk buffers. The root is dummy and its data
spdylay_queue q; member is always NULL. */
spdylay_buffer_chunk root;
/* Points to the current chunk to write */
spdylay_buffer_chunk *current;
/* Total length of this buffer */ /* Total length of this buffer */
size_t len; size_t len;
/* Offset of last chunk buffer */ /* Offset of last chunk buffer */
@ -66,20 +74,17 @@ int spdylay_buffer_alloc(spdylay_buffer *buffer);
/* Returns total length of buffer */ /* Returns total length of buffer */
size_t spdylay_buffer_length(spdylay_buffer *buffer); size_t spdylay_buffer_length(spdylay_buffer *buffer);
/* Returns first chunk buffer length. If the chunk buffer is the last
one, last_offset will be returned. */
size_t spdylay_buffer_front_length(spdylay_buffer *buffer);
/* Returns first chunk buffer pointer */
uint8_t* spdylay_buffer_front_data(spdylay_buffer *buffer);
/* Pops first chunk buffer and decreases total length of buffer by the
size of poped chunk buffer. */
void spdylay_buffer_pop(spdylay_buffer *buffer);
/* Returns capacity of each fixed chunk buffer */ /* Returns capacity of each fixed chunk buffer */
size_t spdylay_buffer_capacity(spdylay_buffer *buffer); size_t spdylay_buffer_capacity(spdylay_buffer *buffer);
/* Stores the contents of buffer into buf. buf must be at least /* Stores the contents of buffer into |buf|. |buf| must be at least
spdylay_buffer_length(buffer) bytes long. */ spdylay_buffer_length(buffer) bytes long. */
void spdylay_buffer_serialize(spdylay_buffer *buffer, uint8_t *buf); void spdylay_buffer_serialize(spdylay_buffer *buffer, uint8_t *buf);
/* Reset |buffer| for reuse. Set the total length of buffer to 0.
Next spdylay_buffer_avail() returns 0. This function does not free
allocated memory space; they are reused. */
void spdylay_buffer_reset(spdylay_buffer *buffer);
#endif /* SPDYLAY_BUFFER_H */ #endif /* SPDYLAY_BUFFER_H */

View File

@ -193,26 +193,24 @@ int spdylay_frame_unpack_nv(char ***nv_ptr, const uint8_t *in, size_t inlen)
} }
static int spdylay_frame_alloc_unpack_nv(char ***nv_ptr, static int spdylay_frame_alloc_unpack_nv(char ***nv_ptr,
spdylay_buffer *inflatebuf,
uint8_t **nvbuf_ptr,
size_t *nvbuflen_ptr,
const uint8_t *in, size_t inlen, const uint8_t *in, size_t inlen,
spdylay_zlib *inflater) spdylay_zlib *inflater)
{ {
ssize_t r; ssize_t nvspace;
spdylay_buffer outbuffer; int r;
spdylay_buffer_init(&outbuffer, 4096); nvspace = spdylay_zlib_inflate_hd(inflater, inflatebuf, in, inlen);
r = spdylay_zlib_inflate_hd(inflater, &outbuffer, in, inlen); if(nvspace < 0) {
if(r < 0) { return nvspace;
spdylay_buffer_free(&outbuffer);
return r;
} else { } else {
uint8_t *buf = malloc(r); r = spdylay_reserve_buffer(nvbuf_ptr, nvbuflen_ptr, nvspace);
if(buf == NULL) { if(r != 0) {
spdylay_buffer_free(&outbuffer);
return SPDYLAY_ERR_NOMEM; return SPDYLAY_ERR_NOMEM;
} }
spdylay_buffer_serialize(&outbuffer, buf); spdylay_buffer_serialize(inflatebuf, *nvbuf_ptr);
spdylay_buffer_free(&outbuffer); r = spdylay_frame_unpack_nv(nv_ptr, *nvbuf_ptr, nvspace);
r = spdylay_frame_unpack_nv(nv_ptr, buf, r);
free(buf);
return r; return r;
} }
} }
@ -485,6 +483,9 @@ ssize_t spdylay_frame_pack_syn_stream(uint8_t **buf_ptr,
} }
int spdylay_frame_unpack_syn_stream(spdylay_syn_stream *frame, int spdylay_frame_unpack_syn_stream(spdylay_syn_stream *frame,
spdylay_buffer *inflatebuf,
uint8_t **nvbuf_ptr,
size_t *nvbuflen_ptr,
const uint8_t *head, size_t headlen, const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen, const uint8_t *payload, size_t payloadlen,
spdylay_zlib *inflater) spdylay_zlib *inflater)
@ -498,7 +499,9 @@ int spdylay_frame_unpack_syn_stream(spdylay_syn_stream *frame,
frame->assoc_stream_id = frame->assoc_stream_id =
spdylay_get_uint32(payload+4) & SPDYLAY_STREAM_ID_MASK; spdylay_get_uint32(payload+4) & SPDYLAY_STREAM_ID_MASK;
frame->pri = spdylay_unpack_pri(payload+8); frame->pri = spdylay_unpack_pri(payload+8);
r = spdylay_frame_alloc_unpack_nv(&frame->nv, payload+10, payloadlen-10, r = spdylay_frame_alloc_unpack_nv(&frame->nv, inflatebuf,
nvbuf_ptr, nvbuflen_ptr,
payload+10, payloadlen-10,
inflater); inflater);
return r; return r;
} }
@ -528,6 +531,9 @@ ssize_t spdylay_frame_pack_syn_reply(uint8_t **buf_ptr,
} }
int spdylay_frame_unpack_syn_reply(spdylay_syn_reply *frame, int spdylay_frame_unpack_syn_reply(spdylay_syn_reply *frame,
spdylay_buffer *inflatebuf,
uint8_t **nvbuf_ptr,
size_t *nvbuflen_ptr,
const uint8_t *head, size_t headlen, const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen, const uint8_t *payload, size_t payloadlen,
spdylay_zlib *inflater) spdylay_zlib *inflater)
@ -538,7 +544,9 @@ int spdylay_frame_unpack_syn_reply(spdylay_syn_reply *frame,
} }
spdylay_frame_unpack_ctrl_hd(&frame->hd, head); spdylay_frame_unpack_ctrl_hd(&frame->hd, head);
frame->stream_id = spdylay_get_uint32(payload) & SPDYLAY_STREAM_ID_MASK; frame->stream_id = spdylay_get_uint32(payload) & SPDYLAY_STREAM_ID_MASK;
r = spdylay_frame_alloc_unpack_nv(&frame->nv, payload+6, payloadlen-6, r = spdylay_frame_alloc_unpack_nv(&frame->nv, inflatebuf,
nvbuf_ptr, nvbuflen_ptr,
payload+6, payloadlen-6,
inflater); inflater);
return r; return r;
} }
@ -621,6 +629,9 @@ ssize_t spdylay_frame_pack_headers(uint8_t **buf_ptr, size_t *buflen_ptr,
} }
int spdylay_frame_unpack_headers(spdylay_headers *frame, int spdylay_frame_unpack_headers(spdylay_headers *frame,
spdylay_buffer *inflatebuf,
uint8_t **nvbuf_ptr,
size_t *nvbuflen_ptr,
const uint8_t *head, size_t headlen, const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen, const uint8_t *payload, size_t payloadlen,
spdylay_zlib *inflater) spdylay_zlib *inflater)
@ -631,7 +642,9 @@ int spdylay_frame_unpack_headers(spdylay_headers *frame,
} }
spdylay_frame_unpack_ctrl_hd(&frame->hd, head); spdylay_frame_unpack_ctrl_hd(&frame->hd, head);
frame->stream_id = spdylay_get_uint32(payload) & SPDYLAY_STREAM_ID_MASK; frame->stream_id = spdylay_get_uint32(payload) & SPDYLAY_STREAM_ID_MASK;
r = spdylay_frame_alloc_unpack_nv(&frame->nv, payload+6, payloadlen-6, r = spdylay_frame_alloc_unpack_nv(&frame->nv, inflatebuf,
nvbuf_ptr, nvbuflen_ptr,
payload+6, payloadlen-6,
inflater); inflater);
return r; return r;
} }

View File

@ -70,9 +70,19 @@ ssize_t spdylay_frame_pack_syn_stream(uint8_t **buf_ptr,
* Unpacks SYN_STREAM frame byte sequence into |frame|. Header is * Unpacks SYN_STREAM frame byte sequence into |frame|. Header is
* given in head and headlen. In spdy/2 spec, headlen is 8 * given in head and headlen. In spdy/2 spec, headlen is 8
* bytes. |payload| is the data after length field of the header. * bytes. |payload| is the data after length field of the header.
*
* |inflatebuf| is used to buffer name/value pairs while inflating
* them using |inflater|. The caller must reset |inflatebuf| before
* the call. |*nvbuf_ptr|, |*nvbuflen_ptr| is used to store temporal
* inflated name/value pairs. This function expands |*nvbuf_ptr| as
* necessary and updates these variables.
*
* This function returns 0 if it succeeds or negative error code. * This function returns 0 if it succeeds or negative error code.
*/ */
int spdylay_frame_unpack_syn_stream(spdylay_syn_stream *frame, int spdylay_frame_unpack_syn_stream(spdylay_syn_stream *frame,
spdylay_buffer *inflatebuf,
uint8_t **nvbuf_ptr,
size_t *nvbuflen_ptr,
const uint8_t *head, size_t headlen, const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen, const uint8_t *payload, size_t payloadlen,
spdylay_zlib *inflater); spdylay_zlib *inflater);
@ -99,10 +109,20 @@ ssize_t spdylay_frame_pack_syn_reply(uint8_t **buf_ptr,
spdylay_zlib *deflater); spdylay_zlib *deflater);
/* /*
* Unpacks SYN_REPLY frame byte sequence into |frame|. This function * Unpacks SYN_REPLY frame byte sequence into |frame|.
* returns 0 if it succeeds or negative error code. *
* |inflatebuf| is used to buffer name/value pairs while inflating
* them using |inflater|. The caller must reset |inflatebuf| before
* the call. |*nvbuf_ptr|, |*nvbuflen_ptr| is used to store temporal
* inflated name/value pairs. This function expands |*nvbuf_ptr| as
* necessary and updates these variables.
*
* This function returns 0 if it succeeds or negative error code.
*/ */
int spdylay_frame_unpack_syn_reply(spdylay_syn_reply *frame, int spdylay_frame_unpack_syn_reply(spdylay_syn_reply *frame,
spdylay_buffer *inflatebuf,
uint8_t **nvbuf_ptr,
size_t *nvbuflen_ptr,
const uint8_t *head, size_t headlen, const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen, const uint8_t *payload, size_t payloadlen,
spdylay_zlib *inflater); spdylay_zlib *inflater);
@ -163,10 +183,20 @@ ssize_t spdylay_frame_pack_headers(uint8_t **buf_ptr, size_t *buflen_ptr,
spdylay_zlib *deflater); spdylay_zlib *deflater);
/* /*
* Unpacks HEADERS wire format into |frame|. This function returns 0 * Unpacks HEADERS wire format into |frame|.
* if it succeeds or negative error code. *
* |inflatebuf| is used to buffer name/value pairs while inflating
* them using |inflater|. The caller must reset |inflatebuf| before
* the call. |*nvbuf_ptr|, |*nvbuflen_ptr| is used to store temporal
* inflated name/value pairs. This function expands |*nvbuf_ptr| as
* necessary and updates these variables.
*
* This function returns 0 if it succeeds or negative error code.
*/ */
int spdylay_frame_unpack_headers(spdylay_headers *frame, int spdylay_frame_unpack_headers(spdylay_headers *frame,
spdylay_buffer *inflatebuf,
uint8_t **nvbuf_ptr,
size_t *nvbuflen_ptr,
const uint8_t *head, size_t headlen, const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen, const uint8_t *payload, size_t payloadlen,
spdylay_zlib *inflater); spdylay_zlib *inflater);

View File

@ -155,6 +155,8 @@ static int spdylay_session_new(spdylay_session **session_ptr,
} }
(*session_ptr)->nvbuflen = SPDYLAY_INITIAL_NV_BUFFER_LENGTH; (*session_ptr)->nvbuflen = SPDYLAY_INITIAL_NV_BUFFER_LENGTH;
spdylay_buffer_init(&(*session_ptr)->inflatebuf, 4096);
memset((*session_ptr)->settings, 0, sizeof((*session_ptr)->settings)); memset((*session_ptr)->settings, 0, sizeof((*session_ptr)->settings));
(*session_ptr)->settings[SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS] = (*session_ptr)->settings[SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS] =
SPDYLAY_CONCURRENT_STREAMS_MAX; SPDYLAY_CONCURRENT_STREAMS_MAX;
@ -271,6 +273,7 @@ void spdylay_session_del(spdylay_session *session)
free(session->iframe.buf); free(session->iframe.buf);
free(session->aob.framebuf); free(session->aob.framebuf);
free(session->nvbuf); free(session->nvbuf);
spdylay_buffer_free(&session->inflatebuf);
free(session); free(session);
} }
@ -1305,7 +1308,11 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
type = ntohs(type); type = ntohs(type);
switch(type) { switch(type) {
case SPDYLAY_SYN_STREAM: case SPDYLAY_SYN_STREAM:
spdylay_buffer_reset(&session->inflatebuf);
r = spdylay_frame_unpack_syn_stream(&frame.syn_stream, r = spdylay_frame_unpack_syn_stream(&frame.syn_stream,
&session->inflatebuf,
&session->nvbuf,
&session->nvbuflen,
session->iframe.headbuf, session->iframe.headbuf,
sizeof(session->iframe.headbuf), sizeof(session->iframe.headbuf),
session->iframe.buf, session->iframe.buf,
@ -1321,7 +1328,11 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
} }
break; break;
case SPDYLAY_SYN_REPLY: case SPDYLAY_SYN_REPLY:
spdylay_buffer_reset(&session->inflatebuf);
r = spdylay_frame_unpack_syn_reply(&frame.syn_reply, r = spdylay_frame_unpack_syn_reply(&frame.syn_reply,
&session->inflatebuf,
&session->nvbuf,
&session->nvbuflen,
session->iframe.headbuf, session->iframe.headbuf,
sizeof(session->iframe.headbuf), sizeof(session->iframe.headbuf),
session->iframe.buf, session->iframe.buf,
@ -1379,7 +1390,11 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
} }
break; break;
case SPDYLAY_HEADERS: case SPDYLAY_HEADERS:
spdylay_buffer_reset(&session->inflatebuf);
r = spdylay_frame_unpack_headers(&frame.headers, r = spdylay_frame_unpack_headers(&frame.headers,
&session->inflatebuf,
&session->nvbuf,
&session->nvbuflen,
session->iframe.headbuf, session->iframe.headbuf,
sizeof(session->iframe.headbuf), sizeof(session->iframe.headbuf),
session->iframe.buf, session->iframe.buf,

View File

@ -35,6 +35,7 @@
#include "spdylay_frame.h" #include "spdylay_frame.h"
#include "spdylay_zlib.h" #include "spdylay_zlib.h"
#include "spdylay_stream.h" #include "spdylay_stream.h"
#include "spdylay_buffer.h"
typedef struct { typedef struct {
spdylay_frame_type frame_type; spdylay_frame_type frame_type;
@ -130,6 +131,9 @@ struct spdylay_session {
uint8_t *nvbuf; uint8_t *nvbuf;
/* The number of bytes allocated for nvbuf */ /* The number of bytes allocated for nvbuf */
size_t nvbuflen; size_t nvbuflen;
/* Buffer used to store name/value pairs while inflating them using
zlib on unpack */
spdylay_buffer inflatebuf;
spdylay_zlib hd_deflater; spdylay_zlib hd_deflater;
spdylay_zlib hd_inflater; spdylay_zlib hd_inflater;

View File

@ -33,6 +33,7 @@
void test_spdylay_buffer() void test_spdylay_buffer()
{ {
spdylay_buffer buffer; spdylay_buffer buffer;
uint8_t out[1024];
spdylay_buffer_init(&buffer, 8); spdylay_buffer_init(&buffer, 8);
CU_ASSERT(0 == spdylay_buffer_length(&buffer)); CU_ASSERT(0 == spdylay_buffer_length(&buffer));
CU_ASSERT(0 == spdylay_buffer_avail(&buffer)); CU_ASSERT(0 == spdylay_buffer_avail(&buffer));
@ -58,26 +59,23 @@ void test_spdylay_buffer()
CU_ASSERT(1 == spdylay_buffer_avail(&buffer)); CU_ASSERT(1 == spdylay_buffer_avail(&buffer));
CU_ASSERT(8 == spdylay_buffer_front_length(&buffer)); spdylay_buffer_serialize(&buffer, out);
CU_ASSERT(memcmp("01234567", spdylay_buffer_front_data(&buffer), 8) == 0); CU_ASSERT(0 == memcmp("0123456789ABCDE", out, 15));
spdylay_buffer_pop(&buffer);
CU_ASSERT(7 == spdylay_buffer_length(&buffer)); spdylay_buffer_reset(&buffer);
CU_ASSERT(memcmp("89ABCDE", spdylay_buffer_front_data(&buffer), 7) == 0);
spdylay_buffer_pop(&buffer);
CU_ASSERT(0 == spdylay_buffer_length(&buffer)); CU_ASSERT(0 == spdylay_buffer_length(&buffer));
CU_ASSERT(0 == spdylay_buffer_avail(&buffer)); CU_ASSERT(0 == spdylay_buffer_avail(&buffer));
CU_ASSERT(NULL == spdylay_buffer_get(&buffer)); CU_ASSERT(NULL == spdylay_buffer_get(&buffer));
CU_ASSERT(0 == spdylay_buffer_alloc(&buffer)); CU_ASSERT(0 == spdylay_buffer_alloc(&buffer));
CU_ASSERT(8 == spdylay_buffer_avail(&buffer)); CU_ASSERT(8 == spdylay_buffer_avail(&buffer));
memcpy(spdylay_buffer_get(&buffer), "34567", 5); memcpy(spdylay_buffer_get(&buffer), "Hello", 5);
spdylay_buffer_advance(&buffer, 5); spdylay_buffer_advance(&buffer, 5);
CU_ASSERT(5 == spdylay_buffer_length(&buffer)); CU_ASSERT(5 == spdylay_buffer_length(&buffer));
CU_ASSERT(memcmp("34567", spdylay_buffer_front_data(&buffer), 5) == 0);
spdylay_buffer_serialize(&buffer, out);
CU_ASSERT(0 == memcmp("Hello", out, 5));
spdylay_buffer_free(&buffer); spdylay_buffer_free(&buffer);
} }

View File

@ -140,7 +140,9 @@ void test_spdylay_frame_pack_headers()
spdylay_frame frame, oframe; spdylay_frame frame, oframe;
uint8_t *buf = NULL, *nvbuf = NULL; uint8_t *buf = NULL, *nvbuf = NULL;
size_t buflen = 0, nvbuflen = 0; size_t buflen = 0, nvbuflen = 0;
spdylay_buffer inflatebuf;
ssize_t framelen; ssize_t framelen;
spdylay_buffer_init(&inflatebuf, 4096);
spdylay_zlib_deflate_hd_init(&deflater); spdylay_zlib_deflate_hd_init(&deflater);
spdylay_zlib_inflate_hd_init(&inflater); spdylay_zlib_inflate_hd_init(&inflater);
spdylay_frame_headers_init(&frame.headers, SPDYLAY_FLAG_FIN, 3, spdylay_frame_headers_init(&frame.headers, SPDYLAY_FLAG_FIN, 3,
@ -150,6 +152,8 @@ void test_spdylay_frame_pack_headers()
&frame.headers, &deflater); &frame.headers, &deflater);
CU_ASSERT(0 == spdylay_frame_unpack_headers CU_ASSERT(0 == spdylay_frame_unpack_headers
(&oframe.headers, (&oframe.headers,
&inflatebuf,
&nvbuf, &nvbuflen,
&buf[0], SPDYLAY_FRAME_HEAD_LENGTH, &buf[0], SPDYLAY_FRAME_HEAD_LENGTH,
&buf[SPDYLAY_FRAME_HEAD_LENGTH], &buf[SPDYLAY_FRAME_HEAD_LENGTH],
framelen-SPDYLAY_FRAME_HEAD_LENGTH, framelen-SPDYLAY_FRAME_HEAD_LENGTH,
@ -168,6 +172,7 @@ void test_spdylay_frame_pack_headers()
spdylay_frame_headers_free(&frame.headers); spdylay_frame_headers_free(&frame.headers);
spdylay_zlib_inflate_free(&inflater); spdylay_zlib_inflate_free(&inflater);
spdylay_zlib_deflate_free(&deflater); spdylay_zlib_deflate_free(&deflater);
spdylay_buffer_free(&inflatebuf);
} }
void test_spdylay_frame_pack_settings() void test_spdylay_frame_pack_settings()

View File

@ -64,7 +64,8 @@ void test_spdylay_zlib()
free(deflatebuf); free(deflatebuf);
spdylay_buffer_serialize(&buf, inflatebuf); spdylay_buffer_serialize(&buf, inflatebuf);
spdylay_zlib_deflate_free(&deflater); spdylay_zlib_deflate_free(&deflater);
spdylay_zlib_inflate_free(&inflater); spdylay_zlib_inflate_free(&inflater);
spdylay_buffer_free(&buf);
} }