Added function to pack and unpack WINDOW_UPDATE frame.
This commit is contained in:
parent
895562a15b
commit
4e62c75b02
|
@ -73,6 +73,8 @@ typedef enum {
|
|||
SPDYLAY_PING = 6,
|
||||
SPDYLAY_GOAWAY = 7,
|
||||
SPDYLAY_HEADERS = 8,
|
||||
/* Since SPDY/3 */
|
||||
SPDYLAY_WINDOW_UPDATE = 9,
|
||||
SPDYLAY_DATA = 100,
|
||||
} spdylay_frame_type;
|
||||
|
||||
|
@ -143,7 +145,7 @@ typedef struct {
|
|||
SPDYLAY_SPDY3_LOWEST_PRI (loweset), depending on the protocol
|
||||
version. */
|
||||
uint8_t pri;
|
||||
/* Use in spdy/3 only */
|
||||
/* Since SPDY/3 */
|
||||
uint8_t slot;
|
||||
char **nv;
|
||||
} spdylay_syn_stream;
|
||||
|
@ -187,10 +189,17 @@ typedef struct {
|
|||
typedef struct {
|
||||
spdylay_ctrl_hd hd;
|
||||
int32_t last_good_stream_id;
|
||||
/* spdy/3 only */
|
||||
/* Since SPDY/3 */
|
||||
uint32_t status_code;
|
||||
} spdylay_goaway;
|
||||
|
||||
/* WINDOW_UPDATE is introduced since SPDY/3 */
|
||||
typedef struct {
|
||||
spdylay_ctrl_hd hd;
|
||||
int32_t stream_id;
|
||||
int32_t delta_window_size;
|
||||
} spdylay_window_update;
|
||||
|
||||
typedef union {
|
||||
int fd;
|
||||
void *ptr;
|
||||
|
@ -237,6 +246,8 @@ typedef union {
|
|||
spdylay_ping ping;
|
||||
spdylay_goaway goaway;
|
||||
spdylay_headers headers;
|
||||
/* Since SPDY/3 */
|
||||
spdylay_window_update window_update;
|
||||
spdylay_data data;
|
||||
} spdylay_frame;
|
||||
|
||||
|
|
|
@ -495,6 +495,23 @@ void spdylay_frame_rst_stream_init(spdylay_rst_stream *frame,
|
|||
void spdylay_frame_rst_stream_free(spdylay_rst_stream *frame)
|
||||
{}
|
||||
|
||||
void spdylay_frame_window_update_init(spdylay_window_update *frame,
|
||||
uint16_t version,
|
||||
int32_t stream_id,
|
||||
int32_t delta_window_size)
|
||||
{
|
||||
memset(frame, 0, sizeof(spdylay_window_update));
|
||||
frame->hd.version = version;
|
||||
frame->hd.type = SPDYLAY_WINDOW_UPDATE;
|
||||
frame->hd.flags = 0;
|
||||
frame->hd.length = 8;
|
||||
frame->stream_id = stream_id;
|
||||
frame->delta_window_size = delta_window_size;
|
||||
}
|
||||
|
||||
void spdylay_frame_window_update_free(spdylay_window_update *frame)
|
||||
{}
|
||||
|
||||
void spdylay_frame_settings_init(spdylay_settings *frame,
|
||||
uint16_t version, uint8_t flags,
|
||||
spdylay_settings_entry *iv, size_t niv)
|
||||
|
@ -823,6 +840,37 @@ int spdylay_frame_unpack_rst_stream(spdylay_rst_stream *frame,
|
|||
return 0;
|
||||
}
|
||||
|
||||
ssize_t spdylay_frame_pack_window_update(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||
spdylay_window_update *frame)
|
||||
{
|
||||
ssize_t framelen = 16;
|
||||
int r;
|
||||
r = spdylay_reserve_buffer(buf_ptr, buflen_ptr, framelen);
|
||||
if(r != 0) {
|
||||
return r;
|
||||
}
|
||||
memset(*buf_ptr, 0, framelen);
|
||||
spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd);
|
||||
spdylay_put_uint32be(&(*buf_ptr)[8], frame->stream_id);
|
||||
spdylay_put_uint32be(&(*buf_ptr)[12], frame->delta_window_size);
|
||||
return framelen;
|
||||
}
|
||||
|
||||
int spdylay_frame_unpack_window_update(spdylay_window_update *frame,
|
||||
const uint8_t *head, size_t headlen,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen)
|
||||
{
|
||||
if(payloadlen != 8) {
|
||||
return SPDYLAY_ERR_INVALID_FRAME;
|
||||
}
|
||||
spdylay_frame_unpack_ctrl_hd(&frame->hd, head);
|
||||
frame->stream_id = spdylay_get_uint32(payload) & SPDYLAY_STREAM_ID_MASK;
|
||||
frame->delta_window_size = spdylay_get_uint32(&payload[4]) &
|
||||
SPDYLAY_DELTA_WINDOW_SIZE_MASK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t spdylay_frame_pack_settings(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||
spdylay_settings *frame)
|
||||
{
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#define SPDYLAY_STREAM_ID_MASK 0x7fffffff
|
||||
#define SPDYLAY_LENGTH_MASK 0xffffff
|
||||
#define SPDYLAY_VERSION_MASK 0x7fff
|
||||
#define SPDYLAY_DELTA_WINDOW_SIZE_MASK 0x7fffffff
|
||||
|
||||
/* The length of DATA frame payload. */
|
||||
#define SPDYLAY_DATA_PAYLOAD_LENGTH 4096
|
||||
|
@ -287,7 +288,7 @@ int spdylay_frame_unpack_headers(spdylay_headers *frame,
|
|||
* Packs RST_STREAM frame |frame| in wire frame format and store it in
|
||||
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
|
||||
* length. This function expands |*buf_ptr| as necessary to store
|
||||
* given |frame|. In spdy/2 spc, RST_STREAM wire format is always 16
|
||||
* given |frame|. In spdy/2 spec, RST_STREAM wire format is always 16
|
||||
* bytes long.
|
||||
*
|
||||
* This function returns the size of packed frame if it succeeds, or
|
||||
|
@ -312,6 +313,37 @@ int spdylay_frame_unpack_rst_stream(spdylay_rst_stream *frame,
|
|||
const uint8_t *head, size_t headlen,
|
||||
const uint8_t *payload, size_t payloadlen);
|
||||
|
||||
|
||||
/*
|
||||
* Packs WINDOW_UPDATE frame |frame| in wire frame format and store it
|
||||
* in |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
|
||||
* length. This function expands |*buf_ptr| as necessary to store
|
||||
* given |frame|. In SPDY/3 spec, WINDOW_UPDATE wire format is always 16
|
||||
* bytes long.
|
||||
*
|
||||
* This function returns the size of packed frame if it succeeds, or
|
||||
* returns one of the following negative error codes:
|
||||
*
|
||||
* SPDYLAY_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
ssize_t spdylay_frame_pack_window_update(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||
spdylay_window_update *frame);
|
||||
|
||||
/*
|
||||
* Unpacks WINDOW_UPDATE frame byte sequence into |frame|.
|
||||
*
|
||||
* This function returns 0 if it succeeds or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* SPDYLAY_ERR_INVALID_FRAME
|
||||
* The input data are invalid.
|
||||
*/
|
||||
int spdylay_frame_unpack_window_update(spdylay_window_update *frame,
|
||||
const uint8_t *head, size_t headlen,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen);
|
||||
|
||||
/*
|
||||
* Packs SETTINGS frame |frame| in wire format and store it in
|
||||
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
|
||||
|
@ -448,6 +480,13 @@ void spdylay_frame_rst_stream_init(spdylay_rst_stream *frame,
|
|||
|
||||
void spdylay_frame_rst_stream_free(spdylay_rst_stream *frame);
|
||||
|
||||
void spdylay_frame_window_update_init(spdylay_window_update *frame,
|
||||
uint16_t version,
|
||||
int32_t stream_id,
|
||||
int32_t delta_window_size);
|
||||
|
||||
void spdylay_frame_window_update_free(spdylay_window_update *frame);
|
||||
|
||||
/*
|
||||
* Initializes SETTINGS frame |frame| with given values. |frame| takes
|
||||
* ownership of |iv|, so caller must not free it.
|
||||
|
|
|
@ -145,6 +145,8 @@ int main(int argc, char* argv[])
|
|||
test_spdylay_frame_pack_syn_reply) ||
|
||||
!CU_add_test(pSuite, "frame_pack_headers",
|
||||
test_spdylay_frame_pack_headers) ||
|
||||
!CU_add_test(pSuite, "frame_pack_window_update",
|
||||
test_spdylay_frame_pack_window_update) ||
|
||||
!CU_add_test(pSuite, "frame_pack_settings",
|
||||
test_spdylay_frame_pack_settings) ||
|
||||
!CU_add_test(pSuite, "frame_nv_sort", test_spdylay_frame_nv_sort) ||
|
||||
|
|
|
@ -384,6 +384,33 @@ void test_spdylay_frame_pack_headers()
|
|||
test_spdylay_frame_pack_headers_with(SPDYLAY_PROTO_SPDY3);
|
||||
}
|
||||
|
||||
void test_spdylay_frame_pack_window_update()
|
||||
{
|
||||
spdylay_frame frame, oframe;
|
||||
uint8_t *buf = NULL;
|
||||
size_t buflen = 0;
|
||||
ssize_t framelen;
|
||||
spdylay_frame_window_update_init(&frame.window_update, SPDYLAY_PROTO_SPDY3,
|
||||
1000000007, 4096);
|
||||
framelen = spdylay_frame_pack_window_update(&buf, &buflen,
|
||||
&frame.window_update);
|
||||
CU_ASSERT(0 == spdylay_frame_unpack_window_update
|
||||
(&oframe.window_update,
|
||||
&buf[0], SPDYLAY_FRAME_HEAD_LENGTH,
|
||||
&buf[SPDYLAY_FRAME_HEAD_LENGTH],
|
||||
framelen-SPDYLAY_FRAME_HEAD_LENGTH));
|
||||
CU_ASSERT(1000000007 == oframe.window_update.stream_id);
|
||||
CU_ASSERT(4096 == oframe.window_update.delta_window_size);
|
||||
CU_ASSERT(SPDYLAY_PROTO_SPDY3 == oframe.headers.hd.version);
|
||||
CU_ASSERT(SPDYLAY_WINDOW_UPDATE == oframe.headers.hd.type);
|
||||
CU_ASSERT(SPDYLAY_CTRL_FLAG_NONE == oframe.headers.hd.flags);
|
||||
CU_ASSERT(framelen-SPDYLAY_FRAME_HEAD_LENGTH == oframe.ping.hd.length);
|
||||
free(buf);
|
||||
spdylay_frame_window_update_free(&oframe.window_update);
|
||||
spdylay_frame_window_update_free(&frame.window_update);
|
||||
}
|
||||
|
||||
|
||||
void test_spdylay_frame_pack_settings()
|
||||
{
|
||||
spdylay_frame frame, oframe;
|
||||
|
|
|
@ -34,6 +34,7 @@ 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_window_update();
|
||||
void test_spdylay_frame_pack_settings();
|
||||
void test_spdylay_frame_nv_sort();
|
||||
void test_spdylay_frame_nv_downcase();
|
||||
|
|
Loading…
Reference in New Issue