Added SPDY/3 SETTINGS frame pack/unpack
This commit is contained in:
parent
643238813d
commit
d05d29b507
|
@ -901,6 +901,10 @@ ssize_t spdylay_frame_pack_settings(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
{
|
{
|
||||||
ssize_t framelen = SPDYLAY_FRAME_HEAD_LENGTH+frame->hd.length;
|
ssize_t framelen = SPDYLAY_FRAME_HEAD_LENGTH+frame->hd.length;
|
||||||
int i, r;
|
int i, r;
|
||||||
|
if(frame->hd.version != SPDYLAY_PROTO_SPDY2 &&
|
||||||
|
frame->hd.version != SPDYLAY_PROTO_SPDY3) {
|
||||||
|
return SPDYLAY_ERR_UNSUPPORTED_VERSION;
|
||||||
|
}
|
||||||
r = spdylay_reserve_buffer(buf_ptr, buflen_ptr, framelen);
|
r = spdylay_reserve_buffer(buf_ptr, buflen_ptr, framelen);
|
||||||
if(r != 0) {
|
if(r != 0) {
|
||||||
return r;
|
return r;
|
||||||
|
@ -908,20 +912,29 @@ ssize_t spdylay_frame_pack_settings(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
memset(*buf_ptr, 0, framelen);
|
memset(*buf_ptr, 0, framelen);
|
||||||
spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd);
|
spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd);
|
||||||
spdylay_put_uint32be(&(*buf_ptr)[8], frame->niv);
|
spdylay_put_uint32be(&(*buf_ptr)[8], frame->niv);
|
||||||
for(i = 0; i < frame->niv; ++i) {
|
if(frame->hd.version == SPDYLAY_PROTO_SPDY2) {
|
||||||
int off = i*8;
|
for(i = 0; i < frame->niv; ++i) {
|
||||||
/* spdy/2 spec says ID is network byte order, but publicly
|
int off = i*8;
|
||||||
deployed server sends little endian host byte order. */
|
/* spdy/2 spec says ID is network byte order, but publicly
|
||||||
char *id_ptr = (char*)(&frame->iv[i].settings_id);
|
deployed server sends little endian host byte order. */
|
||||||
|
char *id_ptr = (char*)(&frame->iv[i].settings_id);
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
(*buf_ptr)[12+off] = id_ptr[3];
|
(*buf_ptr)[12+off] = id_ptr[3];
|
||||||
(*buf_ptr)[12+off+1] = id_ptr[2];
|
(*buf_ptr)[12+off+1] = id_ptr[2];
|
||||||
(*buf_ptr)[12+off+2] = id_ptr[1];
|
(*buf_ptr)[12+off+2] = id_ptr[1];
|
||||||
#else /* !WORDS_BIGENDIAN */
|
#else /* !WORDS_BIGENDIAN */
|
||||||
memcpy(&(*buf_ptr)[12+off], id_ptr, 3);
|
memcpy(&(*buf_ptr)[12+off], id_ptr, 3);
|
||||||
#endif /* !WORDS_BIGENDIAN */
|
#endif /* !WORDS_BIGENDIAN */
|
||||||
(*buf_ptr)[15+off] = frame->iv[i].flags;
|
(*buf_ptr)[15+off] = frame->iv[i].flags;
|
||||||
spdylay_put_uint32be(&(*buf_ptr)[16+off], frame->iv[i].value);
|
spdylay_put_uint32be(&(*buf_ptr)[16+off], frame->iv[i].value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(i = 0; i < frame->niv; ++i) {
|
||||||
|
int off = i*8;
|
||||||
|
spdylay_put_uint32be(&(*buf_ptr)[12+off], frame->iv[i].settings_id);
|
||||||
|
(*buf_ptr)[12+off] = frame->iv[i].flags;
|
||||||
|
spdylay_put_uint32be(&(*buf_ptr)[16+off], frame->iv[i].value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
|
@ -935,6 +948,10 @@ int spdylay_frame_unpack_settings(spdylay_settings *frame,
|
||||||
return SPDYLAY_ERR_INVALID_FRAME;
|
return SPDYLAY_ERR_INVALID_FRAME;
|
||||||
}
|
}
|
||||||
spdylay_frame_unpack_ctrl_hd(&frame->hd, head);
|
spdylay_frame_unpack_ctrl_hd(&frame->hd, head);
|
||||||
|
if(frame->hd.version != SPDYLAY_PROTO_SPDY2 &&
|
||||||
|
frame->hd.version != SPDYLAY_PROTO_SPDY3) {
|
||||||
|
return SPDYLAY_ERR_UNSUPPORTED_VERSION;
|
||||||
|
}
|
||||||
frame->niv = spdylay_get_uint32(payload);
|
frame->niv = spdylay_get_uint32(payload);
|
||||||
if(payloadlen != 4+frame->niv*8) {
|
if(payloadlen != 4+frame->niv*8) {
|
||||||
return SPDYLAY_ERR_INVALID_FRAME;
|
return SPDYLAY_ERR_INVALID_FRAME;
|
||||||
|
@ -943,20 +960,30 @@ int spdylay_frame_unpack_settings(spdylay_settings *frame,
|
||||||
if(frame->iv == NULL) {
|
if(frame->iv == NULL) {
|
||||||
return SPDYLAY_ERR_NOMEM;
|
return SPDYLAY_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
for(i = 0; i < frame->niv; ++i) {
|
if(frame->hd.version == SPDYLAY_PROTO_SPDY2) {
|
||||||
int off = i*8;
|
for(i = 0; i < frame->niv; ++i) {
|
||||||
/* ID is little endian. See comments in
|
int off = i*8;
|
||||||
spdylay_frame_pack_settings(). */
|
/* ID is little endian. See comments in
|
||||||
frame->iv[i].settings_id = 0;
|
spdylay_frame_pack_settings(). */
|
||||||
|
frame->iv[i].settings_id = 0;
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
*(char*)(&frame->iv[i].settings_id[1]) = &payload[4+off+2];
|
*(char*)(&frame->iv[i].settings_id[1]) = &payload[4+off+2];
|
||||||
*(char*)(&frame->iv[i].settings_id[2]) = &payload[4+off+1];
|
*(char*)(&frame->iv[i].settings_id[2]) = &payload[4+off+1];
|
||||||
*(char*)(&frame->iv[i].settings_id[3]) = &payload[4+off+0];
|
*(char*)(&frame->iv[i].settings_id[3]) = &payload[4+off+0];
|
||||||
#else /* !WORDS_BIGENDIAN */
|
#else /* !WORDS_BIGENDIAN */
|
||||||
memcpy(&frame->iv[i].settings_id, &payload[4+off], 3);
|
memcpy(&frame->iv[i].settings_id, &payload[4+off], 3);
|
||||||
#endif /* !WORDS_BIGENDIAN */
|
#endif /* !WORDS_BIGENDIAN */
|
||||||
frame->iv[i].flags = payload[7+off];
|
frame->iv[i].flags = payload[7+off];
|
||||||
frame->iv[i].value = spdylay_get_uint32(&payload[8+off]);
|
frame->iv[i].value = spdylay_get_uint32(&payload[8+off]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(i = 0; i < frame->niv; ++i) {
|
||||||
|
int off = i*8;
|
||||||
|
frame->iv[i].settings_id = spdylay_get_uint32(&payload[4+off]) &
|
||||||
|
SPDYLAY_SETTINGS_ID_MASK;
|
||||||
|
frame->iv[i].flags = payload[4+off];
|
||||||
|
frame->iv[i].value = spdylay_get_uint32(&payload[8+off]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#define SPDYLAY_LENGTH_MASK 0xffffff
|
#define SPDYLAY_LENGTH_MASK 0xffffff
|
||||||
#define SPDYLAY_VERSION_MASK 0x7fff
|
#define SPDYLAY_VERSION_MASK 0x7fff
|
||||||
#define SPDYLAY_DELTA_WINDOW_SIZE_MASK 0x7fffffff
|
#define SPDYLAY_DELTA_WINDOW_SIZE_MASK 0x7fffffff
|
||||||
|
#define SPDYLAY_SETTINGS_ID_MASK 0xffffff
|
||||||
|
|
||||||
/* The length of DATA frame payload. */
|
/* The length of DATA frame payload. */
|
||||||
#define SPDYLAY_DATA_PAYLOAD_LENGTH 4096
|
#define SPDYLAY_DATA_PAYLOAD_LENGTH 4096
|
||||||
|
@ -353,6 +354,8 @@ int spdylay_frame_unpack_window_update(spdylay_window_update *frame,
|
||||||
* This function returns the size of packed frame if it succeeds, or
|
* This function returns the size of packed frame if it succeeds, or
|
||||||
* returns one of the following negative error codes:
|
* returns one of the following negative error codes:
|
||||||
*
|
*
|
||||||
|
* SPDYLAY_ERR_UNSUPPORTED_VERSION
|
||||||
|
* The version is not supported.
|
||||||
* SPDYLAY_ERR_NOMEM
|
* SPDYLAY_ERR_NOMEM
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
|
@ -365,6 +368,8 @@ ssize_t spdylay_frame_pack_settings(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
* 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:
|
||||||
*
|
*
|
||||||
|
* SPDYLAY_ERR_UNSUPPORTED_VERSION
|
||||||
|
* The version is not supported.
|
||||||
* SPDYLAY_ERR_INVALID_FRAME
|
* SPDYLAY_ERR_INVALID_FRAME
|
||||||
* The input data are invalid.
|
* The input data are invalid.
|
||||||
* SPDYLAY_ERR_NOMEM
|
* SPDYLAY_ERR_NOMEM
|
||||||
|
|
|
@ -165,8 +165,10 @@ int main(int argc, char* argv[])
|
||||||
test_spdylay_frame_pack_headers_spdy3) ||
|
test_spdylay_frame_pack_headers_spdy3) ||
|
||||||
!CU_add_test(pSuite, "frame_pack_window_update",
|
!CU_add_test(pSuite, "frame_pack_window_update",
|
||||||
test_spdylay_frame_pack_window_update) ||
|
test_spdylay_frame_pack_window_update) ||
|
||||||
!CU_add_test(pSuite, "frame_pack_settings",
|
!CU_add_test(pSuite, "frame_pack_settings_spdy2",
|
||||||
test_spdylay_frame_pack_settings) ||
|
test_spdylay_frame_pack_settings_spdy2) ||
|
||||||
|
!CU_add_test(pSuite, "frame_pack_settings_spdy3",
|
||||||
|
test_spdylay_frame_pack_settings_spdy3) ||
|
||||||
!CU_add_test(pSuite, "frame_nv_sort", test_spdylay_frame_nv_sort) ||
|
!CU_add_test(pSuite, "frame_nv_sort", test_spdylay_frame_nv_sort) ||
|
||||||
!CU_add_test(pSuite, "frame_nv_downcase",
|
!CU_add_test(pSuite, "frame_nv_downcase",
|
||||||
test_spdylay_frame_nv_downcase) ||
|
test_spdylay_frame_nv_downcase) ||
|
||||||
|
|
|
@ -442,7 +442,7 @@ void test_spdylay_frame_pack_window_update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void test_spdylay_frame_pack_settings()
|
void test_spdylay_frame_pack_settings_version(uint16_t version)
|
||||||
{
|
{
|
||||||
spdylay_frame frame, oframe;
|
spdylay_frame frame, oframe;
|
||||||
uint8_t *buf = NULL;
|
uint8_t *buf = NULL;
|
||||||
|
@ -461,7 +461,7 @@ void test_spdylay_frame_pack_settings()
|
||||||
iv[2].value = 65536;
|
iv[2].value = 65536;
|
||||||
|
|
||||||
spdylay_frame_settings_init
|
spdylay_frame_settings_init
|
||||||
(&frame.settings, SPDYLAY_PROTO_SPDY2,
|
(&frame.settings, version,
|
||||||
SPDYLAY_FLAG_SETTINGS_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS,
|
SPDYLAY_FLAG_SETTINGS_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS,
|
||||||
spdylay_frame_iv_copy(iv, 3), 3);
|
spdylay_frame_iv_copy(iv, 3), 3);
|
||||||
framelen = spdylay_frame_pack_settings(&buf, &buflen, &frame.settings);
|
framelen = spdylay_frame_pack_settings(&buf, &buflen, &frame.settings);
|
||||||
|
@ -473,7 +473,7 @@ void test_spdylay_frame_pack_settings()
|
||||||
&buf[SPDYLAY_FRAME_HEAD_LENGTH],
|
&buf[SPDYLAY_FRAME_HEAD_LENGTH],
|
||||||
framelen-SPDYLAY_FRAME_HEAD_LENGTH));
|
framelen-SPDYLAY_FRAME_HEAD_LENGTH));
|
||||||
|
|
||||||
CU_ASSERT(SPDYLAY_PROTO_SPDY2 == oframe.settings.hd.version);
|
CU_ASSERT(version == oframe.settings.hd.version);
|
||||||
CU_ASSERT(SPDYLAY_SETTINGS == oframe.settings.hd.type);
|
CU_ASSERT(SPDYLAY_SETTINGS == oframe.settings.hd.type);
|
||||||
CU_ASSERT(SPDYLAY_FLAG_SETTINGS_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS ==
|
CU_ASSERT(SPDYLAY_FLAG_SETTINGS_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS ==
|
||||||
oframe.settings.hd.flags);
|
oframe.settings.hd.flags);
|
||||||
|
@ -491,6 +491,16 @@ void test_spdylay_frame_pack_settings()
|
||||||
spdylay_frame_settings_free(&oframe.settings);
|
spdylay_frame_settings_free(&oframe.settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_spdylay_frame_pack_settings_spdy2()
|
||||||
|
{
|
||||||
|
test_spdylay_frame_pack_settings_version(SPDYLAY_PROTO_SPDY2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_spdylay_frame_pack_settings_spdy3()
|
||||||
|
{
|
||||||
|
test_spdylay_frame_pack_settings_version(SPDYLAY_PROTO_SPDY3);
|
||||||
|
}
|
||||||
|
|
||||||
void test_spdylay_frame_nv_sort()
|
void test_spdylay_frame_nv_sort()
|
||||||
{
|
{
|
||||||
char *nv[7];
|
char *nv[7];
|
||||||
|
|
|
@ -40,7 +40,8 @@ void test_spdylay_frame_pack_syn_reply_spdy3();
|
||||||
void test_spdylay_frame_pack_headers_spdy2();
|
void test_spdylay_frame_pack_headers_spdy2();
|
||||||
void test_spdylay_frame_pack_headers_spdy3();
|
void test_spdylay_frame_pack_headers_spdy3();
|
||||||
void test_spdylay_frame_pack_window_update();
|
void test_spdylay_frame_pack_window_update();
|
||||||
void test_spdylay_frame_pack_settings();
|
void test_spdylay_frame_pack_settings_spdy2();
|
||||||
|
void test_spdylay_frame_pack_settings_spdy3();
|
||||||
void test_spdylay_frame_nv_sort();
|
void test_spdylay_frame_nv_sort();
|
||||||
void test_spdylay_frame_nv_downcase();
|
void test_spdylay_frame_nv_downcase();
|
||||||
void test_spdylay_frame_nv_2to3();
|
void test_spdylay_frame_nv_2to3();
|
||||||
|
|
Loading…
Reference in New Issue