Added support for 4 bytes length in name/value pair.
This commit is contained in:
parent
cf7da38598
commit
7652d3f4ca
|
@ -31,15 +31,23 @@
|
||||||
|
|
||||||
#include "spdylay_helper.h"
|
#include "spdylay_helper.h"
|
||||||
|
|
||||||
|
#define spdylay_frame_get_nv_len(IN, LEN_SIZE) \
|
||||||
|
(LEN_SIZE == 2 ? spdylay_get_uint16(IN) : spdylay_get_uint32(IN))
|
||||||
|
|
||||||
|
#define spdylay_frame_put_nv_len(OUT, VAL, LEN_SIZE) \
|
||||||
|
(LEN_SIZE == 2 ? \
|
||||||
|
spdylay_put_uint16be(OUT, VAL) : spdylay_put_uint32be(OUT, VAL))
|
||||||
|
|
||||||
static uint8_t spdylay_unpack_pri(const uint8_t *data)
|
static uint8_t spdylay_unpack_pri(const uint8_t *data)
|
||||||
{
|
{
|
||||||
return (data[0] >> 6) & 0x3;
|
return (data[0] >> 6) & 0x3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t* spdylay_pack_str(uint8_t *buf, const char *str, size_t len)
|
static uint8_t* spdylay_pack_str(uint8_t *buf, const char *str, size_t len,
|
||||||
|
size_t len_size)
|
||||||
{
|
{
|
||||||
spdylay_put_uint16be(buf, len);
|
spdylay_frame_put_nv_len(buf, len, len_size);
|
||||||
buf += 2;
|
buf += len_size;
|
||||||
memcpy(buf, str, len);
|
memcpy(buf, str, len);
|
||||||
return buf+len;
|
return buf+len;
|
||||||
}
|
}
|
||||||
|
@ -82,13 +90,14 @@ static ssize_t spdylay_frame_alloc_pack_nv(uint8_t **buf_ptr,
|
||||||
uint8_t **nvbuf_ptr,
|
uint8_t **nvbuf_ptr,
|
||||||
size_t *nvbuflen_ptr,
|
size_t *nvbuflen_ptr,
|
||||||
char **nv, size_t nv_offset,
|
char **nv, size_t nv_offset,
|
||||||
|
size_t len_size,
|
||||||
spdylay_zlib *deflater)
|
spdylay_zlib *deflater)
|
||||||
{
|
{
|
||||||
size_t nvspace;
|
size_t nvspace;
|
||||||
size_t maxframelen;
|
size_t maxframelen;
|
||||||
ssize_t framelen;
|
ssize_t framelen;
|
||||||
int r;
|
int r;
|
||||||
nvspace = spdylay_frame_count_nv_space(nv);
|
nvspace = spdylay_frame_count_nv_space(nv, len_size);
|
||||||
r = spdylay_reserve_buffer(nvbuf_ptr, nvbuflen_ptr, nvspace);
|
r = spdylay_reserve_buffer(nvbuf_ptr, nvbuflen_ptr, nvspace);
|
||||||
if(r != 0) {
|
if(r != 0) {
|
||||||
return SPDYLAY_ERR_NOMEM;
|
return SPDYLAY_ERR_NOMEM;
|
||||||
|
@ -98,7 +107,7 @@ static ssize_t spdylay_frame_alloc_pack_nv(uint8_t **buf_ptr,
|
||||||
if(r != 0) {
|
if(r != 0) {
|
||||||
return SPDYLAY_ERR_NOMEM;
|
return SPDYLAY_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
spdylay_frame_pack_nv(*nvbuf_ptr, nv);
|
spdylay_frame_pack_nv(*nvbuf_ptr, nv, len_size);
|
||||||
framelen = spdylay_zlib_deflate_hd(deflater,
|
framelen = spdylay_zlib_deflate_hd(deflater,
|
||||||
(*buf_ptr)+nv_offset,
|
(*buf_ptr)+nv_offset,
|
||||||
maxframelen-nv_offset,
|
maxframelen-nv_offset,
|
||||||
|
@ -111,28 +120,29 @@ static ssize_t spdylay_frame_alloc_pack_nv(uint8_t **buf_ptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
int spdylay_frame_count_unpack_nv_space
|
int spdylay_frame_count_unpack_nv_space
|
||||||
(size_t *nvlen_ptr, size_t *buflen_ptr, const uint8_t *in, size_t inlen)
|
(size_t *nvlen_ptr, size_t *buflen_ptr, const uint8_t *in, size_t inlen,
|
||||||
|
size_t len_size)
|
||||||
{
|
{
|
||||||
uint16_t n;
|
uint32_t n;
|
||||||
size_t buflen = 0;
|
size_t buflen = 0;
|
||||||
size_t nvlen = 0;
|
size_t nvlen = 0;
|
||||||
size_t off = 0;
|
size_t off = 0;
|
||||||
const size_t len_size = sizeof(uint16_t);
|
|
||||||
int i;
|
int i;
|
||||||
if(inlen < len_size) {
|
if(inlen < len_size) {
|
||||||
return SPDYLAY_ERR_INVALID_FRAME;
|
return SPDYLAY_ERR_INVALID_FRAME;
|
||||||
}
|
}
|
||||||
n = spdylay_get_uint16(in);
|
/* TODO limit n in a reasonable number */
|
||||||
|
n = spdylay_frame_get_nv_len(in, len_size);
|
||||||
off += len_size;
|
off += len_size;
|
||||||
for(i = 0; i < n; ++i) {
|
for(i = 0; i < n; ++i) {
|
||||||
uint16_t len;
|
uint32_t len;
|
||||||
int j;
|
int j;
|
||||||
for(j = 0; j < 2; ++j) {
|
for(j = 0; j < 2; ++j) {
|
||||||
if(inlen-off < len_size) {
|
if(inlen-off < len_size) {
|
||||||
return SPDYLAY_ERR_INVALID_FRAME;
|
return SPDYLAY_ERR_INVALID_FRAME;
|
||||||
}
|
}
|
||||||
len = spdylay_get_uint16(in+off);
|
len = spdylay_frame_get_nv_len(in+off, len_size);
|
||||||
off += 2;
|
off += len_size;
|
||||||
if(inlen-off < len) {
|
if(inlen-off < len) {
|
||||||
return SPDYLAY_ERR_INVALID_FRAME;
|
return SPDYLAY_ERR_INVALID_FRAME;
|
||||||
}
|
}
|
||||||
|
@ -155,13 +165,14 @@ int spdylay_frame_count_unpack_nv_space
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int spdylay_frame_unpack_nv(char ***nv_ptr, const uint8_t *in, size_t inlen)
|
int spdylay_frame_unpack_nv(char ***nv_ptr, const uint8_t *in, size_t inlen,
|
||||||
|
size_t len_size)
|
||||||
{
|
{
|
||||||
size_t nvlen, buflen;
|
size_t nvlen, buflen;
|
||||||
int r, i;
|
int r, i;
|
||||||
char *buf, **index, *data;
|
char *buf, **index, *data;
|
||||||
uint16_t n;
|
uint32_t n;
|
||||||
r = spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, in, inlen);
|
r = spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, in, inlen, len_size);
|
||||||
if(r != 0) {
|
if(r != 0) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -171,14 +182,14 @@ int spdylay_frame_unpack_nv(char ***nv_ptr, const uint8_t *in, size_t inlen)
|
||||||
}
|
}
|
||||||
index = (char**)buf;
|
index = (char**)buf;
|
||||||
data = buf+(nvlen*2+1)*sizeof(char*);
|
data = buf+(nvlen*2+1)*sizeof(char*);
|
||||||
n = spdylay_get_uint16(in);
|
n = spdylay_frame_get_nv_len(in, len_size);
|
||||||
in += 2;
|
in += len_size;
|
||||||
for(i = 0; i < n; ++i) {
|
for(i = 0; i < n; ++i) {
|
||||||
uint16_t len;
|
uint32_t len;
|
||||||
char *name, *val;
|
char *name, *val;
|
||||||
char *stop;
|
char *stop;
|
||||||
len = spdylay_get_uint16(in);
|
len = spdylay_frame_get_nv_len(in, len_size);
|
||||||
in += 2;
|
in += len_size;
|
||||||
name = data;
|
name = data;
|
||||||
memcpy(data, in, len);
|
memcpy(data, in, len);
|
||||||
data += len;
|
data += len;
|
||||||
|
@ -186,8 +197,8 @@ int spdylay_frame_unpack_nv(char ***nv_ptr, const uint8_t *in, size_t inlen)
|
||||||
++data;
|
++data;
|
||||||
in += len;
|
in += len;
|
||||||
|
|
||||||
len = spdylay_get_uint16(in);
|
len = spdylay_frame_get_nv_len(in, len_size);
|
||||||
in += 2;
|
in += len_size;
|
||||||
val = data;
|
val = data;
|
||||||
memcpy(data, in, len);
|
memcpy(data, in, len);
|
||||||
|
|
||||||
|
@ -217,6 +228,8 @@ int spdylay_frame_unpack_nv(char ***nv_ptr, const uint8_t *in, size_t inlen)
|
||||||
* pointer is assigned to |nv_ptr|. |inflatebuf| is used for inflate
|
* pointer is assigned to |nv_ptr|. |inflatebuf| is used for inflate
|
||||||
* operation. |*nvbuf_ptr| is used for temporarily stored inflated
|
* operation. |*nvbuf_ptr| is used for temporarily stored inflated
|
||||||
* name/value pair in wire format. It is expanded as necessary.
|
* name/value pair in wire format. It is expanded as necessary.
|
||||||
|
* |len_size| is the number of bytes used in name/value length. It
|
||||||
|
* must be either 2 or 4.
|
||||||
*
|
*
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
* negative error codes:
|
* negative error codes:
|
||||||
|
@ -231,6 +244,7 @@ static int spdylay_frame_alloc_unpack_nv(char ***nv_ptr,
|
||||||
uint8_t **nvbuf_ptr,
|
uint8_t **nvbuf_ptr,
|
||||||
size_t *nvbuflen_ptr,
|
size_t *nvbuflen_ptr,
|
||||||
const uint8_t *in, size_t inlen,
|
const uint8_t *in, size_t inlen,
|
||||||
|
size_t len_size,
|
||||||
spdylay_zlib *inflater)
|
spdylay_zlib *inflater)
|
||||||
{
|
{
|
||||||
ssize_t nvspace;
|
ssize_t nvspace;
|
||||||
|
@ -244,14 +258,14 @@ static int spdylay_frame_alloc_unpack_nv(char ***nv_ptr,
|
||||||
return SPDYLAY_ERR_NOMEM;
|
return SPDYLAY_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
spdylay_buffer_serialize(inflatebuf, *nvbuf_ptr);
|
spdylay_buffer_serialize(inflatebuf, *nvbuf_ptr);
|
||||||
r = spdylay_frame_unpack_nv(nv_ptr, *nvbuf_ptr, nvspace);
|
r = spdylay_frame_unpack_nv(nv_ptr, *nvbuf_ptr, nvspace, len_size);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t spdylay_frame_count_nv_space(char **nv)
|
size_t spdylay_frame_count_nv_space(char **nv, size_t len_size)
|
||||||
{
|
{
|
||||||
size_t sum = 2;
|
size_t sum = len_size;
|
||||||
int i;
|
int i;
|
||||||
const char *prev = "";
|
const char *prev = "";
|
||||||
size_t prevlen = 0;
|
size_t prevlen = 0;
|
||||||
|
@ -267,21 +281,21 @@ size_t spdylay_frame_count_nv_space(char **nv)
|
||||||
prev = key;
|
prev = key;
|
||||||
prevlen = keylen;
|
prevlen = keylen;
|
||||||
/* SPDY NV header does not include terminating NULL byte */
|
/* SPDY NV header does not include terminating NULL byte */
|
||||||
sum += keylen+vallen+4;
|
sum += keylen+vallen+len_size*2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t spdylay_frame_pack_nv(uint8_t *buf, char **nv)
|
ssize_t spdylay_frame_pack_nv(uint8_t *buf, char **nv, size_t len_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint8_t *bufp = buf+2;
|
uint8_t *bufp = buf+len_size;
|
||||||
uint16_t num_nv = 0;
|
uint32_t num_nv = 0;
|
||||||
/* TODO Join values with same keys, using '\0' as a delimiter */
|
/* TODO Join values with same keys, using '\0' as a delimiter */
|
||||||
const char *prev = "";
|
const char *prev = "";
|
||||||
uint8_t *prev_vallen_buf = NULL;
|
uint8_t *prev_vallen_buf = NULL;
|
||||||
uint16_t prev_vallen = 0;
|
uint32_t prev_vallen = 0;
|
||||||
for(i = 0; nv[i]; i += 2) {
|
for(i = 0; nv[i]; i += 2) {
|
||||||
const char *key = nv[i];
|
const char *key = nv[i];
|
||||||
const char *val = nv[i+1];
|
const char *val = nv[i+1];
|
||||||
|
@ -289,21 +303,21 @@ ssize_t spdylay_frame_pack_nv(uint8_t *buf, char **nv)
|
||||||
size_t vallen = strlen(val);
|
size_t vallen = strlen(val);
|
||||||
if(strcmp(prev, key) == 0) {
|
if(strcmp(prev, key) == 0) {
|
||||||
prev_vallen += vallen+1;
|
prev_vallen += vallen+1;
|
||||||
spdylay_put_uint16be(prev_vallen_buf, prev_vallen);
|
spdylay_frame_put_nv_len(prev_vallen_buf, prev_vallen, len_size);
|
||||||
*bufp = '\0';
|
*bufp = '\0';
|
||||||
++bufp;
|
++bufp;
|
||||||
memcpy(bufp, val, vallen);
|
memcpy(bufp, val, vallen);
|
||||||
bufp += vallen;
|
bufp += vallen;
|
||||||
} else {
|
} else {
|
||||||
++num_nv;
|
++num_nv;
|
||||||
bufp = spdylay_pack_str(bufp, key, keylen);
|
bufp = spdylay_pack_str(bufp, key, keylen, len_size);
|
||||||
prev = key;
|
prev = key;
|
||||||
prev_vallen_buf = bufp;
|
prev_vallen_buf = bufp;
|
||||||
prev_vallen = vallen;
|
prev_vallen = vallen;
|
||||||
bufp = spdylay_pack_str(bufp, val, vallen);
|
bufp = spdylay_pack_str(bufp, val, vallen, len_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spdylay_put_uint16be(buf, num_nv);
|
spdylay_frame_put_nv_len(buf, num_nv, len_size);
|
||||||
return bufp-buf;
|
return bufp-buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,6 +518,7 @@ ssize_t spdylay_frame_pack_syn_stream(uint8_t **buf_ptr,
|
||||||
nvbuf_ptr, nvbuflen_ptr,
|
nvbuf_ptr, nvbuflen_ptr,
|
||||||
frame->nv,
|
frame->nv,
|
||||||
SPDYLAY_SYN_STREAM_NV_OFFSET,
|
SPDYLAY_SYN_STREAM_NV_OFFSET,
|
||||||
|
2,
|
||||||
deflater);
|
deflater);
|
||||||
if(framelen < 0) {
|
if(framelen < 0) {
|
||||||
return framelen;
|
return framelen;
|
||||||
|
@ -538,6 +553,7 @@ int spdylay_frame_unpack_syn_stream(spdylay_syn_stream *frame,
|
||||||
r = spdylay_frame_alloc_unpack_nv(&frame->nv, inflatebuf,
|
r = spdylay_frame_alloc_unpack_nv(&frame->nv, inflatebuf,
|
||||||
nvbuf_ptr, nvbuflen_ptr,
|
nvbuf_ptr, nvbuflen_ptr,
|
||||||
payload+10, payloadlen-10,
|
payload+10, payloadlen-10,
|
||||||
|
2,
|
||||||
inflater);
|
inflater);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -555,7 +571,9 @@ ssize_t spdylay_frame_pack_syn_reply(uint8_t **buf_ptr,
|
||||||
framelen = spdylay_frame_alloc_pack_nv(buf_ptr, buflen_ptr,
|
framelen = spdylay_frame_alloc_pack_nv(buf_ptr, buflen_ptr,
|
||||||
nvbuf_ptr, nvbuflen_ptr,
|
nvbuf_ptr, nvbuflen_ptr,
|
||||||
frame->nv,
|
frame->nv,
|
||||||
SPDYLAY_SYN_REPLY_NV_OFFSET, deflater);
|
SPDYLAY_SYN_REPLY_NV_OFFSET,
|
||||||
|
2,
|
||||||
|
deflater);
|
||||||
if(framelen < 0) {
|
if(framelen < 0) {
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
|
@ -583,6 +601,7 @@ int spdylay_frame_unpack_syn_reply(spdylay_syn_reply *frame,
|
||||||
r = spdylay_frame_alloc_unpack_nv(&frame->nv, inflatebuf,
|
r = spdylay_frame_alloc_unpack_nv(&frame->nv, inflatebuf,
|
||||||
nvbuf_ptr, nvbuflen_ptr,
|
nvbuf_ptr, nvbuflen_ptr,
|
||||||
payload+6, payloadlen-6,
|
payload+6, payloadlen-6,
|
||||||
|
2,
|
||||||
inflater);
|
inflater);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -653,7 +672,9 @@ ssize_t spdylay_frame_pack_headers(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
framelen = spdylay_frame_alloc_pack_nv(buf_ptr, buflen_ptr,
|
framelen = spdylay_frame_alloc_pack_nv(buf_ptr, buflen_ptr,
|
||||||
nvbuf_ptr, nvbuflen_ptr,
|
nvbuf_ptr, nvbuflen_ptr,
|
||||||
frame->nv,
|
frame->nv,
|
||||||
SPDYLAY_HEADERS_NV_OFFSET, deflater);
|
SPDYLAY_HEADERS_NV_OFFSET,
|
||||||
|
2,
|
||||||
|
deflater);
|
||||||
if(framelen < 0) {
|
if(framelen < 0) {
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
|
@ -681,6 +702,7 @@ int spdylay_frame_unpack_headers(spdylay_headers *frame,
|
||||||
r = spdylay_frame_alloc_unpack_nv(&frame->nv, inflatebuf,
|
r = spdylay_frame_alloc_unpack_nv(&frame->nv, inflatebuf,
|
||||||
nvbuf_ptr, nvbuflen_ptr,
|
nvbuf_ptr, nvbuflen_ptr,
|
||||||
payload+6, payloadlen-6,
|
payload+6, payloadlen-6,
|
||||||
|
2,
|
||||||
inflater);
|
inflater);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -328,35 +328,40 @@ int spdylay_frame_unpack_settings(spdylay_settings *frame,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns number of bytes to pack name/value pairs |nv|. This
|
* Returns number of bytes to pack name/value pairs |nv|. This
|
||||||
* function expects |nv| is sorted in ascending order of key. This
|
* function expects |nv| is sorted in ascending order of key.
|
||||||
* function can handles duplicate keys and concatenation of thier
|
* |len_size| is the number of bytes in length of name/value pair and
|
||||||
|
* it must be 2 or 4.
|
||||||
|
*
|
||||||
|
* This function can handles duplicate keys and concatenation of thier
|
||||||
* values with '\0'.
|
* values with '\0'.
|
||||||
*/
|
*/
|
||||||
size_t spdylay_frame_count_nv_space(char **nv);
|
size_t spdylay_frame_count_nv_space(char **nv, size_t len_size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packs name/value pairs in |nv| in |buf|. |buf| must have at least
|
* Packs name/value pairs in |nv| in |buf|. |buf| must have at least
|
||||||
* spdylay_frame_count_nv_space(nv) bytes.
|
* spdylay_frame_count_nv_space(nv) bytes. |len_size| is the number
|
||||||
|
* of bytes in length of name/value pair and it must be 2 or 4.
|
||||||
*/
|
*/
|
||||||
ssize_t spdylay_frame_pack_nv(uint8_t *buf, char **nv);
|
ssize_t spdylay_frame_pack_nv(uint8_t *buf, char **nv, size_t len_size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Counts number of name/value pair in |in| and computes length of
|
* Counts number of name/value pair in |in| and computes length of
|
||||||
* buffers to store unpacked name/value pair and store them in
|
* buffers to store unpacked name/value pair and store them in
|
||||||
* |*num_nv_ptr| and |*buf_size_ptr| respectively. We use folloing
|
* |*num_nv_ptr| and |*buf_size_ptr| respectively. |len_size| is the
|
||||||
* data structure in |*buf_size_ptr|. First part of the data is array
|
* number of bytes in length of name/value pair and it must be 2 or
|
||||||
* of pointer to name/value pair. Supporse the buf pointer points to
|
* 4. We use folloing data structure in |*buf_size_ptr|. First part
|
||||||
* the data region and N is the number of name/value pair. First
|
* of the data is array of pointer to name/value pair. Supporse the
|
||||||
* (N*2+1)*sizeof(char*) bytes contain array of pointer to name/value
|
* buf pointer points to the data region and N is the number of
|
||||||
* pair and terminating NULL. Each pointer to name/value pair points
|
* name/value pair. First (N*2+1)*sizeof(char*) bytes contain array
|
||||||
* to the string in remaining data. For each name/value pair, the
|
* of pointer to name/value pair and terminating NULL. Each pointer
|
||||||
* name is copied to the remaining data with terminating NULL
|
* to name/value pair points to the string in remaining data. For
|
||||||
* character. The value is also copied to the position after the data
|
* each name/value pair, the name is copied to the remaining data with
|
||||||
* with terminating NULL character. The corresponding index is
|
* terminating NULL character. The value is also copied to the
|
||||||
* assigned to these pointers. If the value contains multiple values
|
* position after the data with terminating NULL character. The
|
||||||
* (delimited by single NULL), for each such data, corresponding index
|
* corresponding index is assigned to these pointers. If the value
|
||||||
* is assigned to name/value pointers. In this case, the name string
|
* contains multiple values (delimited by single NULL), for each such
|
||||||
* is reused.
|
* data, corresponding index is assigned to name/value pointers. In
|
||||||
|
* this case, the name string is reused.
|
||||||
*
|
*
|
||||||
* With the above stragety, |*buf_size_ptr| is calculated as
|
* With the above stragety, |*buf_size_ptr| is calculated as
|
||||||
* (N*2+1)*sizeof(char*)+sum(strlen(name)+1+strlen(value)+1){for each
|
* (N*2+1)*sizeof(char*)+sum(strlen(name)+1+strlen(value)+1){for each
|
||||||
|
@ -369,12 +374,14 @@ ssize_t spdylay_frame_pack_nv(uint8_t *buf, char **nv);
|
||||||
* The input data are invalid.
|
* The input data are invalid.
|
||||||
*/
|
*/
|
||||||
int spdylay_frame_count_unpack_nv_space
|
int spdylay_frame_count_unpack_nv_space
|
||||||
(size_t *num_nv_ptr, size_t *buf_size_ptr, const uint8_t *in, size_t inlen);
|
(size_t *num_nv_ptr, size_t *buf_size_ptr, const uint8_t *in, size_t inlen,
|
||||||
|
size_t len_size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unpacks name/value pairs in wire format |in| with length |inlen|
|
* Unpacks name/value pairs in wire format |in| with length |inlen|
|
||||||
* and stores them in |*nv_ptr|. Thif function allocates enough
|
* and stores them in |*nv_ptr|. Thif function allocates enough
|
||||||
* memory to store name/value pairs in |*nv_ptr|.
|
* memory to store name/value pairs in |*nv_ptr|. |len_size| is the
|
||||||
|
* number of bytes in length of name/value pair and it must be 2 or 4.
|
||||||
*
|
*
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
* negative error codes:
|
* negative error codes:
|
||||||
|
@ -382,7 +389,8 @@ int spdylay_frame_count_unpack_nv_space
|
||||||
* SPDYLAY_ERR_NOMEM
|
* SPDYLAY_ERR_NOMEM
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
int spdylay_frame_unpack_nv(char ***nv_ptr, const uint8_t *in, size_t inlen);
|
int spdylay_frame_unpack_nv(char ***nv_ptr, const uint8_t *in, size_t inlen,
|
||||||
|
size_t len_size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes SYN_STREAM frame |frame| with given values. |frame|
|
* Initializes SYN_STREAM frame |frame| with given values. |frame|
|
||||||
|
|
|
@ -43,8 +43,9 @@ void test_spdylay_frame_unpack_nv()
|
||||||
{
|
{
|
||||||
uint8_t out[1024];
|
uint8_t out[1024];
|
||||||
char **nv;
|
char **nv;
|
||||||
size_t inlen = spdylay_frame_pack_nv(out, (char**)headers);
|
size_t len_size = 2;
|
||||||
CU_ASSERT(0 == spdylay_frame_unpack_nv(&nv, out, inlen));
|
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);
|
CU_ASSERT(strcmp("method", nv[0]) == 0);
|
||||||
CU_ASSERT(strcmp("GET", nv[1]) == 0);
|
CU_ASSERT(strcmp("GET", nv[1]) == 0);
|
||||||
CU_ASSERT(strcmp("scheme", nv[2]) == 0);
|
CU_ASSERT(strcmp("scheme", nv[2]) == 0);
|
||||||
|
@ -63,6 +64,7 @@ void test_spdylay_frame_unpack_nv()
|
||||||
void test_spdylay_frame_pack_nv_duplicate_keys()
|
void test_spdylay_frame_pack_nv_duplicate_keys()
|
||||||
{
|
{
|
||||||
uint8_t out[1024];
|
uint8_t out[1024];
|
||||||
|
size_t len_size = 2;
|
||||||
const char *nv_src[] = {
|
const char *nv_src[] = {
|
||||||
"method", "GET",
|
"method", "GET",
|
||||||
"scheme", "https",
|
"scheme", "https",
|
||||||
|
@ -75,7 +77,7 @@ void test_spdylay_frame_pack_nv_duplicate_keys()
|
||||||
char **nv = spdylay_frame_nv_copy(nv_src);
|
char **nv = spdylay_frame_nv_copy(nv_src);
|
||||||
spdylay_frame_nv_downcase(nv);
|
spdylay_frame_nv_downcase(nv);
|
||||||
spdylay_frame_nv_sort(nv);
|
spdylay_frame_nv_sort(nv);
|
||||||
/* size_t inlen = */ spdylay_frame_pack_nv(out, nv);
|
/* size_t inlen = */ spdylay_frame_pack_nv(out, nv, len_size);
|
||||||
const uint8_t *outptr = out;
|
const uint8_t *outptr = out;
|
||||||
int pairs = spdylay_get_uint16(outptr);
|
int pairs = spdylay_get_uint16(outptr);
|
||||||
CU_ASSERT(pairs == 5);
|
CU_ASSERT(pairs == 5);
|
||||||
|
@ -147,40 +149,45 @@ void test_spdylay_frame_pack_nv_duplicate_keys()
|
||||||
|
|
||||||
void test_spdylay_frame_count_nv_space()
|
void test_spdylay_frame_count_nv_space()
|
||||||
{
|
{
|
||||||
CU_ASSERT(74 == spdylay_frame_count_nv_space((char**)headers));
|
size_t len_size = 2;
|
||||||
|
CU_ASSERT(74 == spdylay_frame_count_nv_space((char**)headers, len_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_spdylay_frame_count_unpack_nv_space()
|
void test_spdylay_frame_count_unpack_nv_space()
|
||||||
{
|
{
|
||||||
size_t nvlen, buflen;
|
size_t nvlen, buflen;
|
||||||
uint8_t out[1024];
|
uint8_t out[1024];
|
||||||
size_t inlen = spdylay_frame_pack_nv(out, (char**)headers);
|
size_t len_size = 2;
|
||||||
|
size_t inlen = spdylay_frame_pack_nv(out, (char**)headers, len_size);
|
||||||
uint16_t temp;
|
uint16_t temp;
|
||||||
CU_ASSERT(0 == spdylay_frame_count_unpack_nv_space(&nvlen, &buflen,
|
CU_ASSERT(0 == spdylay_frame_count_unpack_nv_space(&nvlen, &buflen,
|
||||||
out, inlen));
|
out, inlen, len_size));
|
||||||
CU_ASSERT(6 == nvlen);
|
CU_ASSERT(6 == nvlen);
|
||||||
CU_ASSERT(166 == buflen);
|
CU_ASSERT(166 == buflen);
|
||||||
|
|
||||||
/* Trailing garbage */
|
/* Trailing garbage */
|
||||||
CU_ASSERT(SPDYLAY_ERR_INVALID_FRAME ==
|
CU_ASSERT(SPDYLAY_ERR_INVALID_FRAME ==
|
||||||
spdylay_frame_count_unpack_nv_space(&nvlen, &buflen,
|
spdylay_frame_count_unpack_nv_space(&nvlen, &buflen,
|
||||||
out, inlen+2));
|
out, inlen+2, len_size));
|
||||||
|
|
||||||
/* Change number of nv pair to a bogus value */
|
/* Change number of nv pair to a bogus value */
|
||||||
temp = spdylay_get_uint16(out);
|
temp = spdylay_get_uint16(out);
|
||||||
spdylay_put_uint16be(out, temp+1);
|
spdylay_put_uint16be(out, temp+1);
|
||||||
CU_ASSERT(SPDYLAY_ERR_INVALID_FRAME ==
|
CU_ASSERT(SPDYLAY_ERR_INVALID_FRAME ==
|
||||||
spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, out, inlen));
|
spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, out, inlen,
|
||||||
|
len_size));
|
||||||
spdylay_put_uint16be(out, temp);
|
spdylay_put_uint16be(out, temp);
|
||||||
|
|
||||||
/* Change the length of name to a bogus value */
|
/* Change the length of name to a bogus value */
|
||||||
temp = spdylay_get_uint16(out+2);
|
temp = spdylay_get_uint16(out+2);
|
||||||
spdylay_put_uint16be(out+2, temp+1);
|
spdylay_put_uint16be(out+2, temp+1);
|
||||||
CU_ASSERT(SPDYLAY_ERR_INVALID_FRAME ==
|
CU_ASSERT(SPDYLAY_ERR_INVALID_FRAME ==
|
||||||
spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, out, inlen));
|
spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, out, inlen,
|
||||||
|
len_size));
|
||||||
spdylay_put_uint16be(out+2, 65535);
|
spdylay_put_uint16be(out+2, 65535);
|
||||||
CU_ASSERT(SPDYLAY_ERR_INVALID_FRAME ==
|
CU_ASSERT(SPDYLAY_ERR_INVALID_FRAME ==
|
||||||
spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, out, inlen));
|
spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, out, inlen,
|
||||||
|
len_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_spdylay_frame_pack_ping()
|
void test_spdylay_frame_pack_ping()
|
||||||
|
|
Loading…
Reference in New Issue