Change SETTINGS payload format according to the spec

This commit is contained in:
Tatsuhiro Tsujikawa 2014-02-06 22:06:42 +09:00
parent d584888601
commit f26270b5b4
6 changed files with 25 additions and 19 deletions

View File

@ -110,7 +110,8 @@ void nghttp2_frame_settings_init(nghttp2_settings *frame, uint8_t flags,
nghttp2_settings_entry *iv, size_t niv) nghttp2_settings_entry *iv, size_t niv)
{ {
memset(frame, 0, sizeof(nghttp2_settings)); memset(frame, 0, sizeof(nghttp2_settings));
nghttp2_frame_set_hd(&frame->hd, niv*8, NGHTTP2_SETTINGS, flags, 0); nghttp2_frame_set_hd(&frame->hd, niv * NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH,
NGHTTP2_SETTINGS, flags, 0);
frame->niv = niv; frame->niv = niv;
frame->iv = iv; frame->iv = iv;
} }
@ -341,11 +342,11 @@ size_t nghttp2_frame_pack_settings_payload(uint8_t *buf,
size_t niv) size_t niv)
{ {
size_t i; size_t i;
for(i = 0; i < niv; ++i, buf += 8) { for(i = 0; i < niv; ++i, buf += NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH) {
nghttp2_put_uint32be(buf, iv[i].settings_id); buf[0] = iv[i].settings_id;
nghttp2_put_uint32be(buf + 4, iv[i].value); nghttp2_put_uint32be(buf + 1, iv[i].value);
} }
return 8 * niv; return NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH * niv;
} }
int nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame, int nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
@ -366,9 +367,8 @@ int nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv, void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
const uint8_t *payload) const uint8_t *payload)
{ {
iv->settings_id = nghttp2_get_uint32(&payload[0]) & iv->settings_id = payload[0];
NGHTTP2_SETTINGS_ID_MASK; iv->value = nghttp2_get_uint32(&payload[1]);
iv->value = nghttp2_get_uint32(&payload[4]);
} }
int nghttp2_frame_unpack_settings_payload2(nghttp2_settings_entry **iv_ptr, int nghttp2_frame_unpack_settings_payload2(nghttp2_settings_entry **iv_ptr,
@ -377,13 +377,13 @@ int nghttp2_frame_unpack_settings_payload2(nghttp2_settings_entry **iv_ptr,
size_t payloadlen) size_t payloadlen)
{ {
size_t i; size_t i;
*niv_ptr = payloadlen / 8; *niv_ptr = payloadlen / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH;
*iv_ptr = malloc((*niv_ptr)*sizeof(nghttp2_settings_entry)); *iv_ptr = malloc((*niv_ptr)*sizeof(nghttp2_settings_entry));
if(*iv_ptr == NULL) { if(*iv_ptr == NULL) {
return NGHTTP2_ERR_NOMEM; return NGHTTP2_ERR_NOMEM;
} }
for(i = 0; i < *niv_ptr; ++i) { for(i = 0; i < *niv_ptr; ++i) {
size_t off = i*8; size_t off = i * NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH;
nghttp2_frame_unpack_settings_entry(&(*iv_ptr)[i], &payload[off]); nghttp2_frame_unpack_settings_entry(&(*iv_ptr)[i], &payload[off]);
} }
return 0; return 0;

View File

@ -48,6 +48,9 @@
/* The number of bytes of frame header. */ /* The number of bytes of frame header. */
#define NGHTTP2_FRAME_HEAD_LENGTH 8 #define NGHTTP2_FRAME_HEAD_LENGTH 8
/* The number of bytes for each SETTINGS entry */
#define NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH 5
/* Category of frames. */ /* Category of frames. */
typedef enum { typedef enum {
/* non-DATA frame */ /* non-DATA frame */

View File

@ -3390,7 +3390,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
break; break;
case NGHTTP2_SETTINGS: case NGHTTP2_SETTINGS:
DEBUGF(fprintf(stderr, "SETTINGS\n")); DEBUGF(fprintf(stderr, "SETTINGS\n"));
if((iframe->frame.hd.length & 0x7) || if((iframe->frame.hd.length % NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH) ||
((iframe->frame.hd.flags & NGHTTP2_FLAG_ACK) && ((iframe->frame.hd.flags & NGHTTP2_FLAG_ACK) &&
iframe->payloadleft > 0)) { iframe->payloadleft > 0)) {
busy = 1; busy = 1;
@ -3399,7 +3399,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
} }
iframe->state = NGHTTP2_IB_READ_SETTINGS; iframe->state = NGHTTP2_IB_READ_SETTINGS;
if(iframe->payloadleft) { if(iframe->payloadleft) {
iframe->left = 8; iframe->left = NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH;
break; break;
} }
busy = 1; busy = 1;
@ -3629,7 +3629,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
} }
} }
if(iframe->payloadleft) { if(iframe->payloadleft) {
iframe->left = 8; iframe->left = NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH;
iframe->buflen = 0; iframe->buflen = 0;
break; break;
} }
@ -4070,7 +4070,7 @@ int nghttp2_session_upgrade(nghttp2_session *session,
(session->server && session->last_recv_stream_id >= 1)) { (session->server && session->last_recv_stream_id >= 1)) {
return NGHTTP2_ERR_PROTO; return NGHTTP2_ERR_PROTO;
} }
if(settings_payloadlen % 8) { if(settings_payloadlen % NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH) {
return NGHTTP2_ERR_INVALID_ARGUMENT; return NGHTTP2_ERR_INVALID_ARGUMENT;
} }
rv = nghttp2_frame_unpack_settings_payload2(&iv, &niv, settings_payload, rv = nghttp2_frame_unpack_settings_payload2(&iv, &niv, settings_payload,

View File

@ -323,8 +323,9 @@ ssize_t nghttp2_pack_settings_payload(uint8_t *buf,
return NGHTTP2_ERR_INVALID_ARGUMENT; return NGHTTP2_ERR_INVALID_ARGUMENT;
} }
if(buflen < (niv * 8)) if(buflen < (niv * NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH)) {
return NGHTTP2_ERR_INSUFF_BUFSIZE; return NGHTTP2_ERR_INSUFF_BUFSIZE;
}
return nghttp2_frame_pack_settings_payload(buf, iv, niv); return nghttp2_frame_pack_settings_payload(buf, iv, niv);
} }

View File

@ -226,9 +226,11 @@ void test_nghttp2_frame_pack_settings()
nghttp2_frame_settings_init(&frame, NGHTTP2_FLAG_NONE, nghttp2_frame_settings_init(&frame, NGHTTP2_FLAG_NONE,
nghttp2_frame_iv_copy(iv, 3), 3); nghttp2_frame_iv_copy(iv, 3), 3);
framelen = nghttp2_frame_pack_settings(&buf, &buflen, &frame); framelen = nghttp2_frame_pack_settings(&buf, &buflen, &frame);
CU_ASSERT(NGHTTP2_FRAME_HEAD_LENGTH+3*8 == framelen); CU_ASSERT(NGHTTP2_FRAME_HEAD_LENGTH +
3 * NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH == framelen);
CU_ASSERT(0 == unpack_frame((nghttp2_frame*)&oframe, buf, framelen)); CU_ASSERT(0 == unpack_frame((nghttp2_frame*)&oframe, buf, framelen));
check_frame_header(3*8, NGHTTP2_SETTINGS, NGHTTP2_FLAG_NONE, 0, &oframe.hd); check_frame_header(3 * NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH,
NGHTTP2_SETTINGS, NGHTTP2_FLAG_NONE, 0, &oframe.hd);
CU_ASSERT(3 == oframe.niv); CU_ASSERT(3 == oframe.niv);
for(i = 0; i < 3; ++i) { for(i = 0; i < 3; ++i) {
CU_ASSERT(iv[i].settings_id == oframe.iv[i].settings_id); CU_ASSERT(iv[i].settings_id == oframe.iv[i].settings_id);

View File

@ -3828,7 +3828,7 @@ void test_nghttp2_pack_settings_payload(void)
iv[1].value = 4095; iv[1].value = 4095;
len = nghttp2_pack_settings_payload(buf, sizeof(buf), iv, 2); len = nghttp2_pack_settings_payload(buf, sizeof(buf), iv, 2);
CU_ASSERT(16 == len); CU_ASSERT(2 * NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH == len);
CU_ASSERT(0 == nghttp2_frame_unpack_settings_payload2(&resiv, &resniv, CU_ASSERT(0 == nghttp2_frame_unpack_settings_payload2(&resiv, &resniv,
buf, len)); buf, len));
CU_ASSERT(2 == resniv); CU_ASSERT(2 == resniv);
@ -3839,6 +3839,6 @@ void test_nghttp2_pack_settings_payload(void)
free(resiv); free(resiv);
len = nghttp2_pack_settings_payload(buf, 15 /* too small */, iv, 2); len = nghttp2_pack_settings_payload(buf, 9 /* too small */, iv, 2);
CU_ASSERT(NGHTTP2_ERR_INSUFF_BUFSIZE == len); CU_ASSERT(NGHTTP2_ERR_INSUFF_BUFSIZE == len);
} }