Support DEBUG_DATA in GOAWAY again

This commit is contained in:
Tatsuhiro Tsujikawa 2014-03-22 18:59:59 +09:00
parent 01586f473d
commit e1eebf08fb
5 changed files with 89 additions and 13 deletions

View File

@ -562,13 +562,44 @@ int nghttp2_frame_pack_goaway(nghttp2_bufs *bufs, nghttp2_goaway *frame)
void nghttp2_frame_unpack_goaway_payload(nghttp2_goaway *frame,
const uint8_t *payload,
size_t payloadlen)
size_t payloadlen,
uint8_t *var_gift_payload,
size_t var_gift_payloadlen)
{
frame->last_stream_id = nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK;
frame->error_code = nghttp2_get_uint32(payload+4);
/* TODO Currently we don't buffer debug data */
frame->opaque_data = NULL;
frame->opaque_data_len = 0;
frame->opaque_data = var_gift_payload;
frame->opaque_data_len = var_gift_payloadlen;
}
int nghttp2_frame_unpack_goaway_payload2(nghttp2_goaway *frame,
const uint8_t *payload,
size_t payloadlen)
{
uint8_t *var_gift_payload;
size_t var_gift_payloadlen;
if(payloadlen > 8) {
var_gift_payloadlen = payloadlen - 8;
} else {
var_gift_payloadlen = 0;
}
payloadlen -= var_gift_payloadlen;
var_gift_payload = malloc(var_gift_payloadlen);
if(var_gift_payload == NULL) {
return NGHTTP2_ERR_NOMEM;
}
memcpy(var_gift_payload, payload + 8, var_gift_payloadlen);
nghttp2_frame_unpack_goaway_payload(frame, payload, payloadlen,
var_gift_payload, var_gift_payloadlen);
return 0;
}
int nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,

View File

@ -330,9 +330,31 @@ void nghttp2_frame_unpack_ping_payload(nghttp2_ping *frame,
int nghttp2_frame_pack_goaway(nghttp2_bufs *bufs, nghttp2_goaway *frame);
/*
* Unpacks GOAWAY wire format into |frame|.
* Unpacks GOAWAY wire format into |frame|. The |payload| of length
* |payloadlen| contains first 8 bytes of payload. The
* |var_gift_payload| of length |var_gift_payloadlen| contains
* remaining payload and its buffer is gifted to the function and then
* |frame|. The |var_gift_payloadlen| must be freed by
* nghttp2_frame_goaway_free().
*/
void nghttp2_frame_unpack_goaway_payload(nghttp2_goaway *frame,
const uint8_t *payload,
size_t payloadlen,
uint8_t *var_gift_payload,
size_t var_gift_payloadlen);
/*
* Unpacks GOAWAY wire format into |frame|. This function only exists
* for unit test. After allocating buffer for debug data, this
* function internally calls nghttp2_frame_unpack_goaway_payload().
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_frame_unpack_goaway_payload2(nghttp2_goaway *frame,
const uint8_t *payload,
size_t payloadlen);

View File

@ -3099,7 +3099,11 @@ static int session_process_goaway_frame(nghttp2_session *session)
nghttp2_frame_unpack_goaway_payload(&frame->goaway,
iframe->sbuf.pos,
nghttp2_buf_len(&iframe->sbuf));
nghttp2_buf_len(&iframe->sbuf),
iframe->lbuf.pos,
nghttp2_buf_len(&iframe->lbuf));
nghttp2_buf_wrap_init(&iframe->lbuf, NULL, 0);
return nghttp2_session_on_goaway_received(session, frame);
}
@ -4009,12 +4013,28 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
nghttp2_inbound_frame_reset(session);
break;
case NGHTTP2_GOAWAY:
case NGHTTP2_GOAWAY: {
size_t debuglen;
/* 8 is Last-stream-ID + Error Code */
debuglen = iframe->frame.hd.length - 8;
if(debuglen > 0) {
iframe->raw_lbuf = malloc(debuglen);
if(iframe->raw_lbuf == NULL) {
return NGHTTP2_ERR_NOMEM;
}
nghttp2_buf_wrap_init(&iframe->lbuf, iframe->raw_lbuf, debuglen);
}
busy = 1;
iframe->state = NGHTTP2_IB_READ_GOAWAY_DEBUG;
break;
}
case NGHTTP2_WINDOW_UPDATE:
rv = session_process_window_update_frame(session);
if(nghttp2_is_fatal(rv)) {
@ -4224,6 +4244,9 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
DEBUGF(fprintf(stderr, "recv: [IB_READ_GOAWAY_DEBUG]\n"));
readlen = inbound_frame_payload_readlen(iframe, in, last);
iframe->lbuf.last = nghttp2_cpymem(iframe->lbuf.last, in, readlen);
iframe->payloadleft -= readlen;
in += readlen;
@ -4231,6 +4254,8 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
readlen, iframe->payloadleft));
if(iframe->payloadleft) {
assert(nghttp2_buf_avail(&iframe->lbuf) > 0);
break;
}

View File

@ -373,11 +373,9 @@ void test_nghttp2_frame_pack_goaway()
check_frame_header(24, NGHTTP2_GOAWAY, NGHTTP2_FLAG_NONE, 0, &oframe.hd);
CU_ASSERT(1000000007 == oframe.last_stream_id);
CU_ASSERT(NGHTTP2_PROTOCOL_ERROR == oframe.error_code);
/* TODO Currently, opaque data is discarded */
CU_ASSERT(0 == oframe.opaque_data_len);
CU_ASSERT(NULL == oframe.opaque_data);
/* CU_ASSERT(opaque_data_len == oframe.opaque_data_len); */
/* CU_ASSERT(memcmp(opaque_data, oframe.opaque_data, opaque_data_len) == 0); */
CU_ASSERT(opaque_data_len == oframe.opaque_data_len);
CU_ASSERT(memcmp(opaque_data, oframe.opaque_data, opaque_data_len) == 0);
nghttp2_bufs_free(&bufs);
nghttp2_frame_goaway_free(&oframe);

View File

@ -77,7 +77,7 @@ int unpack_frame(nghttp2_frame *frame, const uint8_t *in, size_t len)
(&frame->ping, payload, payloadlen);
break;
case NGHTTP2_GOAWAY:
nghttp2_frame_unpack_goaway_payload
nghttp2_frame_unpack_goaway_payload2
(&frame->goaway, payload, payloadlen);
break;
case NGHTTP2_WINDOW_UPDATE: