Reuse buffers when unpacking frames.
This commit is contained in:
parent
050f33e8f9
commit
ac1629e61b
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue