diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h index 65365071..837bb1ff 100644 --- a/lib/includes/nghttp2/nghttp2.h +++ b/lib/includes/nghttp2/nghttp2.h @@ -396,7 +396,8 @@ typedef struct { /** * @enum - * The control frame types in HTTP/2. + * + * The frame types in HTTP/2 specification. */ typedef enum { /** @@ -438,17 +439,28 @@ typedef enum { /** * The CONTINUATION frame. */ - NGHTTP2_CONTINUATION = 0x09, - /** - * The ALTSVC frame. - */ - NGHTTP2_ALTSVC = 0x0a, - /** - * The BLOCKED frame. - */ - NGHTTP2_BLOCKED = 0x0b + NGHTTP2_CONTINUATION = 0x09 } nghttp2_frame_type; +/** + * @enum + * + * The extension frame types. + * + * TODO: The assigned frame types were carried from draft-12, and now + * actually TBD. + */ +typedef enum { + /** + * The ALTSVC extension frame. + */ + NGHTTP2_EXT_ALTSVC = 0x0a, + /** + * The BLOCKED extension frame. + */ + NGHTTP2_EXT_BLOCKED = 0x0b +} nghttp2_ext_frame_type; + /** * @enum * @@ -938,16 +950,30 @@ typedef struct { int32_t window_size_increment; } nghttp2_window_update; -/** - * @struct - * - * The ALTSVC frame. It has following members: - */ typedef struct { /** * The frame header. */ nghttp2_frame_hd hd; + /** + * The pointer to extension payload. The exact pointer type is + * determined by hd.type. + * + * If hd.type == :enum:`NGHTTP2_EXT_ALTSVC`, it is a pointer to + * :type:`nghttp2_ext_altsvc`. + * + * If hd.type == :enum:`NGHTTP2_EXT_BLOCKED`, it points to ``NULL``, + * since BLOCKED extension frame has no payload. + */ + void *payload; +} nghttp2_extension; + +/** + * @struct + * + * The ALTSVC extension frame payload. It has following members: + */ +typedef struct { /** * Protocol ID */ @@ -980,19 +1006,7 @@ typedef struct { * Port */ uint16_t port; -} nghttp2_altsvc; - -/** - * @struct - * - * The BLOCKED frame. It has following members: - */ -typedef struct { - /** - * The frame header. - */ - nghttp2_frame_hd hd; -} nghttp2_blocked; +} nghttp2_ext_altsvc; /** * @union @@ -1043,13 +1057,9 @@ typedef union { */ nghttp2_window_update window_update; /** - * The ALTSVC frame. + * The extension frame. */ - nghttp2_altsvc altsvc; - /** - * The BLOCKED frame. - */ - nghttp2_blocked blocked; + nghttp2_extension ext; } nghttp2_frame; /** diff --git a/lib/nghttp2_frame.c b/lib/nghttp2_frame.c index c42b057c..105d03bd 100644 --- a/lib/nghttp2_frame.c +++ b/lib/nghttp2_frame.c @@ -186,7 +186,7 @@ void nghttp2_frame_window_update_init(nghttp2_window_update *frame, void nghttp2_frame_window_update_free(nghttp2_window_update *frame) {} -void nghttp2_frame_altsvc_init(nghttp2_altsvc *frame, int32_t stream_id, +void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id, uint32_t max_age, uint16_t port, uint8_t *protocol_id, @@ -195,34 +195,45 @@ void nghttp2_frame_altsvc_init(nghttp2_altsvc *frame, int32_t stream_id, uint8_t *origin, size_t origin_len) { size_t payloadlen; + nghttp2_ext_altsvc *altsvc; + + altsvc = frame->payload; payloadlen = NGHTTP2_ALTSVC_MINLEN + protocol_id_len + host_len + origin_len; - frame_set_hd(&frame->hd, payloadlen, NGHTTP2_ALTSVC, NGHTTP2_FLAG_NONE, + frame_set_hd(&frame->hd, payloadlen, NGHTTP2_EXT_ALTSVC, NGHTTP2_FLAG_NONE, stream_id); - frame->max_age = max_age; - frame->port = port; - frame->protocol_id = protocol_id; - frame->protocol_id_len = protocol_id_len; - frame->host = host; - frame->host_len = host_len; - frame->origin = origin; - frame->origin_len = origin_len; + altsvc->max_age = max_age; + altsvc->port = port; + altsvc->protocol_id = protocol_id; + altsvc->protocol_id_len = protocol_id_len; + altsvc->host = host; + altsvc->host_len = host_len; + altsvc->origin = origin; + altsvc->origin_len = origin_len; } -void nghttp2_frame_altsvc_free(nghttp2_altsvc *frame) +void nghttp2_frame_altsvc_free(nghttp2_extension *frame) { - free(frame->protocol_id); + nghttp2_ext_altsvc *altsvc; + + altsvc = frame->payload; + + if(altsvc == NULL) { + return; + } + + free(altsvc->protocol_id); } -void nghttp2_frame_blocked_init(nghttp2_blocked *frame, int32_t stream_id) +void nghttp2_frame_blocked_init(nghttp2_extension *frame, int32_t stream_id) { - frame_set_hd(&frame->hd, 0, NGHTTP2_BLOCKED, NGHTTP2_FLAG_NONE, + frame_set_hd(&frame->hd, 0, NGHTTP2_EXT_BLOCKED, NGHTTP2_FLAG_NONE, stream_id); } -void nghttp2_frame_blocked_free(nghttp2_blocked *frame) +void nghttp2_frame_blocked_free(nghttp2_extension *frame) {} void nghttp2_frame_data_init(nghttp2_data *frame, nghttp2_private_data *pdata) @@ -757,44 +768,47 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame, NGHTTP2_WINDOW_SIZE_INCREMENT_MASK; } -int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_altsvc *frame) +int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) { int rv; nghttp2_buf *buf; + nghttp2_ext_altsvc *altsvc; assert(bufs->head == bufs->cur); + altsvc = frame->payload; + buf = &bufs->head->buf; buf->pos -= NGHTTP2_FRAME_HDLEN; nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); - nghttp2_put_uint32be(buf->last, frame->max_age); + nghttp2_put_uint32be(buf->last, altsvc->max_age); buf->last += 4; - nghttp2_put_uint16be(buf->last, frame->port); + nghttp2_put_uint16be(buf->last, altsvc->port); buf->last += 2; - buf->last[0] = frame->protocol_id_len; + buf->last[0] = altsvc->protocol_id_len; ++buf->last; - rv = nghttp2_bufs_add(bufs, frame->protocol_id, frame->protocol_id_len); + rv = nghttp2_bufs_add(bufs, altsvc->protocol_id, altsvc->protocol_id_len); if(rv != 0) { goto fail; } - rv = nghttp2_bufs_addb(bufs, frame->host_len); + rv = nghttp2_bufs_addb(bufs, altsvc->host_len); if(rv != 0) { goto fail; } - rv = nghttp2_bufs_add(bufs, frame->host, frame->host_len); + rv = nghttp2_bufs_add(bufs, altsvc->host, altsvc->host_len); if(rv != 0) { goto fail; } - rv = nghttp2_bufs_add(bufs, frame->origin, frame->origin_len); + rv = nghttp2_bufs_add(bufs, altsvc->origin, altsvc->origin_len); if(rv != 0) { goto fail; } @@ -810,50 +824,53 @@ int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_altsvc *frame) return rv; } -int nghttp2_frame_unpack_altsvc_payload(nghttp2_altsvc *frame, +int nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame, const uint8_t *payload, size_t payloadlen, uint8_t *var_gift_payload, size_t var_gift_payloadlen) { nghttp2_buf buf; + nghttp2_ext_altsvc *altsvc; - frame->max_age = nghttp2_get_uint32(payload); + altsvc = frame->payload; + + altsvc->max_age = nghttp2_get_uint32(payload); payload += 4; - frame->port = nghttp2_get_uint16(payload); + altsvc->port = nghttp2_get_uint16(payload); payload += 2; - frame->protocol_id_len = *payload; + altsvc->protocol_id_len = *payload; nghttp2_buf_wrap_init(&buf, var_gift_payload, var_gift_payloadlen); buf.last += var_gift_payloadlen; /* 1 for Host-Len */ - if(nghttp2_buf_len(&buf) < 1 + (ssize_t)frame->protocol_id_len) { + if(nghttp2_buf_len(&buf) < 1 + (ssize_t)altsvc->protocol_id_len) { return NGHTTP2_ERR_FRAME_SIZE_ERROR; } - frame->protocol_id = buf.pos; - buf.pos += frame->protocol_id_len; + altsvc->protocol_id = buf.pos; + buf.pos += altsvc->protocol_id_len; - frame->host_len = *buf.pos; + altsvc->host_len = *buf.pos; ++buf.pos; - if(nghttp2_buf_len(&buf) < (ssize_t)frame->host_len) { + if(nghttp2_buf_len(&buf) < (ssize_t)altsvc->host_len) { return NGHTTP2_ERR_FRAME_SIZE_ERROR; } - frame->host = buf.pos; - buf.pos += frame->host_len; + altsvc->host = buf.pos; + buf.pos += altsvc->host_len; - frame->origin = buf.pos; - frame->origin_len = nghttp2_buf_len(&buf); + altsvc->origin = buf.pos; + altsvc->origin_len = nghttp2_buf_len(&buf); return 0; } -int nghttp2_frame_pack_blocked(nghttp2_bufs *bufs, nghttp2_blocked *frame) +int nghttp2_frame_pack_blocked(nghttp2_bufs *bufs, nghttp2_extension *frame) { nghttp2_buf *buf; diff --git a/lib/nghttp2_frame.h b/lib/nghttp2_frame.h index e8531507..662345e5 100644 --- a/lib/nghttp2_frame.h +++ b/lib/nghttp2_frame.h @@ -66,11 +66,10 @@ Max-Age, Port and Proto-Len. */ #define NGHTTP2_ALTSVC_FIXED_PARTLEN 7 -/* Minimum length of ALTSVC frame. NGHTTP2_ALTSVC_FIXED_PARTLEN + - Host-Len. */ +/* Minimum length of ALTSVC extension frame payload. + NGHTTP2_ALTSVC_FIXED_PARTLEN + Host-Len. */ #define NGHTTP2_ALTSVC_MINLEN 8 - /* Category of frames. */ typedef enum { /* non-DATA frame */ @@ -79,6 +78,11 @@ typedef enum { NGHTTP2_CAT_DATA } nghttp2_frame_category; +/* Union of extension frame payload */ +typedef union { + nghttp2_ext_altsvc altsvc; +} nghttp2_ext_frame_payload; + /** * @struct * @@ -402,6 +406,9 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame, * The caller must make sure that nghttp2_bufs_reset(bufs) is called * before calling this function. * + * The caller must make sure that frame->payload points to + * nghttp2_ext_altsvc object. + * * This function returns 0 if it succeeds or one of the following * negative error codes: * @@ -410,7 +417,7 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame, * NGHTTP2_ERR_FRAME_SIZE_ERROR * The length of the frame is too large. */ -int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_altsvc *frame); +int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame); /* @@ -421,13 +428,16 @@ int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_altsvc *frame); * and then |frame|. The |var_gift_payloadlen| must be freed by * nghttp2_frame_altsvc_free(). * + * The caller must make sure that frame->payload points to + * nghttp2_ext_altsvc object. + * * This function returns 0 if it succeeds or one of the following * negative error codes: * * NGHTTP2_ERR_FRAME_SIZE_ERROR * The |var_gift_payload| does not contain required data. */ -int nghttp2_frame_unpack_altsvc_payload(nghttp2_altsvc *frame, +int nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame, const uint8_t *payload, size_t payloadlen, uint8_t *var_gift_payload, @@ -441,7 +451,7 @@ int nghttp2_frame_unpack_altsvc_payload(nghttp2_altsvc *frame, * * This function always returns 0. */ -int nghttp2_frame_pack_blocked(nghttp2_bufs *bufs, nghttp2_blocked *frame); +int nghttp2_frame_pack_blocked(nghttp2_bufs *bufs, nghttp2_extension *frame); /* * Initializes HEADERS frame |frame| with given values. |frame| takes @@ -524,7 +534,7 @@ void nghttp2_frame_window_update_free(nghttp2_window_update *frame); |protocol_id_len| == 0 and |host_len| + |origin_len| > 0. If |protocol_id_len|, |host_len| and |origin_len| are all zero, |protocol_id| can be NULL. */ -void nghttp2_frame_altsvc_init(nghttp2_altsvc *frame, int32_t stream_id, +void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id, uint32_t max_age, uint16_t port, uint8_t *protocol_id, @@ -532,11 +542,15 @@ void nghttp2_frame_altsvc_init(nghttp2_altsvc *frame, int32_t stream_id, uint8_t *host, size_t host_len, uint8_t *origin, size_t origin_len); -void nghttp2_frame_altsvc_free(nghttp2_altsvc *frame); +/* + * Frees resources used by |frame|. This function does not free + * frame->payload itself. + */ +void nghttp2_frame_altsvc_free(nghttp2_extension *frame); -void nghttp2_frame_blocked_init(nghttp2_blocked *frame, int32_t stream_id); +void nghttp2_frame_blocked_init(nghttp2_extension *frame, int32_t stream_id); -void nghttp2_frame_blocked_free(nghttp2_blocked *frame); +void nghttp2_frame_blocked_free(nghttp2_extension *frame); void nghttp2_frame_data_init(nghttp2_data *frame, nghttp2_private_data *pdata); diff --git a/lib/nghttp2_outbound_item.c b/lib/nghttp2_outbound_item.c index db308f14..b5db10c1 100644 --- a/lib/nghttp2_outbound_item.c +++ b/lib/nghttp2_outbound_item.c @@ -62,8 +62,9 @@ void nghttp2_outbound_item_free(nghttp2_outbound_item *item) case NGHTTP2_WINDOW_UPDATE: nghttp2_frame_window_update_free(&frame->window_update); break; - case NGHTTP2_ALTSVC: - nghttp2_frame_altsvc_free(&frame->altsvc); + case NGHTTP2_EXT_ALTSVC: + nghttp2_frame_altsvc_free(&frame->ext); + free(frame->ext.payload); break; } } else if(item->frame_cat == NGHTTP2_CAT_DATA) { diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c index 824bb232..5f8aad73 100644 --- a/lib/nghttp2_session.c +++ b/lib/nghttp2_session.c @@ -230,14 +230,16 @@ static void session_inbound_frame_reset(nghttp2_session *session) case NGHTTP2_WINDOW_UPDATE: nghttp2_frame_window_update_free(&iframe->frame.window_update); break; - case NGHTTP2_ALTSVC: - nghttp2_frame_altsvc_free(&iframe->frame.altsvc); + case NGHTTP2_EXT_ALTSVC: + nghttp2_frame_altsvc_free(&iframe->frame.ext); break; - case NGHTTP2_BLOCKED: - nghttp2_frame_blocked_free(&iframe->frame.blocked); + case NGHTTP2_EXT_BLOCKED: + nghttp2_frame_blocked_free(&iframe->frame.ext); break; } + memset(&iframe->frame, 0, sizeof(nghttp2_frame)); + memset(&iframe->ext_frame_payload, 0, sizeof(nghttp2_ext_frame_payload)); iframe->state = NGHTTP2_IB_READ_HEAD; @@ -1504,12 +1506,14 @@ static int session_add_blocked(nghttp2_session *session, int32_t stream_id) return NGHTTP2_ERR_NOMEM; } - nghttp2_frame_blocked_init(&frame->blocked, stream_id); + frame->ext.payload = NULL; + + nghttp2_frame_blocked_init(&frame->ext, stream_id); rv = nghttp2_session_add_frame(session, NGHTTP2_CAT_CTRL, frame, NULL); if(rv != 0) { - nghttp2_frame_blocked_free(&frame->blocked); + nghttp2_frame_blocked_free(&frame->ext); free(frame); return rv; @@ -1751,28 +1755,28 @@ static int session_prep_frame(nghttp2_session *session, return framerv; } break; - case NGHTTP2_ALTSVC: + case NGHTTP2_EXT_ALTSVC: rv = session_predicate_altsvc_send(session, frame->hd.stream_id); if(rv != 0) { return rv; } framerv = nghttp2_frame_pack_altsvc(&session->aob.framebufs, - &frame->altsvc); + &frame->ext); if(framerv < 0) { return framerv; } break; - case NGHTTP2_BLOCKED: + case NGHTTP2_EXT_BLOCKED: rv = session_predicate_blocked_send(session, frame->hd.stream_id); if(rv != 0) { return rv; } framerv = nghttp2_frame_pack_blocked(&session->aob.framebufs, - &frame->blocked); + &frame->ext); if(framerv < 0) { return framerv; @@ -3650,7 +3654,9 @@ static int session_process_altsvc_frame(nghttp2_session *session) nghttp2_frame *frame = &iframe->frame; int rv; - rv = nghttp2_frame_unpack_altsvc_payload(&frame->altsvc, + frame->ext.payload = &iframe->ext_frame_payload; + + rv = nghttp2_frame_unpack_altsvc_payload(&frame->ext, iframe->sbuf.pos, nghttp2_buf_len(&iframe->sbuf), iframe->lbuf.pos, @@ -3677,6 +3683,8 @@ static int session_process_blocked_frame(nghttp2_session *session) nghttp2_inbound_frame *iframe = &session->iframe; nghttp2_frame *frame = &iframe->frame; + frame->ext.payload = NULL; + return nghttp2_session_on_blocked_received(session, frame); } @@ -4463,7 +4471,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, iframe->state = NGHTTP2_IB_IGN_PAYLOAD; break; - case NGHTTP2_ALTSVC: + case NGHTTP2_EXT_ALTSVC: DEBUGF(fprintf(stderr, "recv: ALTSVC\n")); iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; @@ -4494,7 +4502,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, inbound_frame_set_mark(iframe, NGHTTP2_ALTSVC_FIXED_PARTLEN); break; - case NGHTTP2_BLOCKED: + case NGHTTP2_EXT_BLOCKED: DEBUGF(fprintf(stderr, "recv: BLOCKED\n")); iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; @@ -4694,7 +4702,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, session_inbound_frame_reset(session); break; - case NGHTTP2_ALTSVC: { + case NGHTTP2_EXT_ALTSVC: { size_t varlen; varlen = iframe->frame.hd.length - NGHTTP2_ALTSVC_FIXED_PARTLEN; diff --git a/lib/nghttp2_session.h b/lib/nghttp2_session.h index 514adf8c..891c457f 100644 --- a/lib/nghttp2_session.h +++ b/lib/nghttp2_session.h @@ -83,6 +83,9 @@ typedef enum { typedef struct { nghttp2_frame frame; + /* Storage for extension frame payload. frame->ext.payload points + to this structure to avoid frequent memory allocation. */ + nghttp2_ext_frame_payload ext_frame_payload; /* The received SETTINGS entry. The protocol says that we only cares about the defined settings ID. If unknown ID is received, it is subject to connection error */ diff --git a/lib/nghttp2_submit.c b/lib/nghttp2_submit.c index 4a2e8427..310addb8 100644 --- a/lib/nghttp2_submit.c +++ b/lib/nghttp2_submit.c @@ -379,6 +379,7 @@ int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags, size_t varlen; uint8_t *var, *varp; nghttp2_frame *frame; + nghttp2_ext_altsvc *altsvc; uint8_t *copy_protocol_id, *copy_host, *copy_origin; if(!session->server) { @@ -392,6 +393,14 @@ int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags, return NGHTTP2_ERR_INVALID_ARGUMENT; } + altsvc = malloc(sizeof(nghttp2_ext_altsvc)); + + if(altsvc == NULL) { + rv = NGHTTP2_ERR_NOMEM; + + goto fail; + } + if(varlen == 0) { var = NULL; copy_protocol_id = NULL; @@ -401,7 +410,9 @@ int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags, var = malloc(varlen); if(var == NULL) { - return NGHTTP2_ERR_NOMEM; + rv = NGHTTP2_ERR_NOMEM; + + goto var_alloc_fail; } varp = var; @@ -424,25 +435,37 @@ int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags, frame = malloc(sizeof(nghttp2_frame)); if(frame == NULL) { - free(var); + rv = NGHTTP2_ERR_NOMEM; - return NGHTTP2_ERR_NOMEM; + goto frame_alloc_fail; } - nghttp2_frame_altsvc_init(&frame->altsvc, stream_id, max_age, port, + frame->ext.payload = altsvc; + + nghttp2_frame_altsvc_init(&frame->ext, stream_id, max_age, port, copy_protocol_id, protocol_id_len, copy_host, host_len, copy_origin, origin_len); rv = nghttp2_session_add_frame(session, NGHTTP2_CAT_CTRL, frame, NULL); if(rv != 0) { - nghttp2_frame_altsvc_free(&frame->altsvc); + nghttp2_frame_altsvc_free(&frame->ext); free(frame); + free(altsvc); return rv; } return 0; + + frame_alloc_fail: + free(var); + + var_alloc_fail: + free(altsvc); + + fail: + return rv; } static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec, diff --git a/src/app_helper.cc b/src/app_helper.cc index f7e1905b..449a492b 100644 --- a/src/app_helper.cc +++ b/src/app_helper.cc @@ -127,9 +127,9 @@ const char* strframetype(uint8_t type) return "GOAWAY"; case NGHTTP2_WINDOW_UPDATE: return "WINDOW_UPDATE"; - case NGHTTP2_ALTSVC: + case NGHTTP2_EXT_ALTSVC: return "ALTSVC"; - case NGHTTP2_BLOCKED: + case NGHTTP2_EXT_BLOCKED: return "BLOCKED"; default: return "UNKNOWN"; @@ -427,25 +427,34 @@ void print_frame(print_type ptype, const nghttp2_frame *frame) fprintf(outfile, "(window_size_increment=%d)\n", frame->window_update.window_size_increment); break; - case NGHTTP2_ALTSVC: + case NGHTTP2_EXT_ALTSVC: { print_frame_attr_indent(); + + auto altsvc = static_cast(frame->ext.payload); + fprintf(outfile, "(max-age=%u, port=%u, protocol_id=", - frame->altsvc.max_age, frame->altsvc.port); - if(frame->altsvc.protocol_id_len) { - fwrite(frame->altsvc.protocol_id, frame->altsvc.protocol_id_len, 1, - outfile); + altsvc->max_age, altsvc->port); + + if(altsvc->protocol_id_len) { + fwrite(altsvc->protocol_id, altsvc->protocol_id_len, 1, outfile); } + fprintf(outfile, ", host="); - if(frame->altsvc.host_len) { - fwrite(frame->altsvc.host, frame->altsvc.host_len, 1, outfile); + + if(altsvc->host_len) { + fwrite(altsvc->host, altsvc->host_len, 1, outfile); } + fprintf(outfile, ", origin="); - if(frame->altsvc.origin_len) { - fwrite(frame->altsvc.origin, frame->altsvc.origin_len, 1, outfile); + + if(altsvc->origin_len) { + fwrite(altsvc->origin, altsvc->origin_len, 1, outfile); } + fprintf(outfile, ")\n"); break; + } default: break; } diff --git a/tests/nghttp2_frame_test.c b/tests/nghttp2_frame_test.c index a343cdc8..99351242 100644 --- a/tests/nghttp2_frame_test.c +++ b/tests/nghttp2_frame_test.c @@ -435,7 +435,8 @@ void test_nghttp2_frame_pack_window_update(void) void test_nghttp2_frame_pack_altsvc(void) { - nghttp2_altsvc frame, oframe; + nghttp2_extension frame, oframe; + nghttp2_ext_altsvc altsvc, oaltsvc; nghttp2_bufs bufs; nghttp2_buf *buf; size_t protocol_id_len, host_len, origin_len; @@ -464,6 +465,8 @@ void test_nghttp2_frame_pack_altsvc(void) frame_pack_bufs_init(&bufs); + frame.payload = &altsvc; + nghttp2_frame_altsvc_init(&frame, 1000000007, 1u << 31, 4000, protocol_id, protocol_id_len, host, host_len, origin, origin_len); @@ -475,27 +478,30 @@ void test_nghttp2_frame_pack_altsvc(void) CU_ASSERT((ssize_t)(NGHTTP2_FRAME_HDLEN + NGHTTP2_ALTSVC_MINLEN + datalen) == nghttp2_bufs_len(&bufs)); + oframe.payload = &oaltsvc; + CU_ASSERT(0 == unpack_framebuf((nghttp2_frame*)&oframe, &bufs)); check_frame_header(NGHTTP2_ALTSVC_MINLEN + datalen, - NGHTTP2_ALTSVC, NGHTTP2_FLAG_NONE, + NGHTTP2_EXT_ALTSVC, NGHTTP2_FLAG_NONE, 1000000007, &oframe.hd); - CU_ASSERT(1u << 31 == oframe.max_age); - CU_ASSERT(4000 == oframe.port); + CU_ASSERT(1u << 31 == oaltsvc.max_age); + CU_ASSERT(4000 == oaltsvc.port); - CU_ASSERT(protocol_id_len == oframe.protocol_id_len); - CU_ASSERT(memcmp(protocol_id, oframe.protocol_id, protocol_id_len) == 0); + CU_ASSERT(protocol_id_len == oaltsvc.protocol_id_len); + CU_ASSERT(memcmp(protocol_id, oaltsvc.protocol_id, protocol_id_len) == 0); - CU_ASSERT(host_len == oframe.host_len); - CU_ASSERT(memcmp(host, oframe.host, host_len) == 0); + CU_ASSERT(host_len == oaltsvc.host_len); + CU_ASSERT(memcmp(host, oaltsvc.host, host_len) == 0); - CU_ASSERT(origin_len == oframe.origin_len); - CU_ASSERT(memcmp(origin, oframe.origin, origin_len) == 0); + CU_ASSERT(origin_len == oaltsvc.origin_len); + CU_ASSERT(memcmp(origin, oaltsvc.origin, origin_len) == 0); nghttp2_frame_altsvc_free(&oframe); nghttp2_frame_altsvc_free(&frame); memset(&oframe, 0, sizeof(oframe)); + memset(&oaltsvc, 0, sizeof(oaltsvc)); buf = &bufs.head->buf; @@ -506,6 +512,8 @@ void test_nghttp2_frame_pack_altsvc(void) payloadlen = NGHTTP2_ALTSVC_MINLEN + protocol_id_len + host_len; nghttp2_put_uint16be(buf->pos, payloadlen); + oframe.payload = &oaltsvc; + CU_ASSERT(0 == nghttp2_frame_unpack_altsvc_payload (&oframe, @@ -514,13 +522,19 @@ void test_nghttp2_frame_pack_altsvc(void) buf->pos + NGHTTP2_FRAME_HDLEN + NGHTTP2_ALTSVC_FIXED_PARTLEN, payloadlen - NGHTTP2_ALTSVC_FIXED_PARTLEN)); - CU_ASSERT(host_len == oframe.host_len); - CU_ASSERT(0 == oframe.origin_len); + CU_ASSERT(protocol_id_len == oaltsvc.protocol_id_len); + CU_ASSERT(host_len == oaltsvc.host_len); + CU_ASSERT(0 == oaltsvc.origin_len); + + memset(&oframe, 0, sizeof(oframe)); + memset(&oaltsvc, 0, sizeof(oaltsvc)); /* Check insufficient payload length for host */ payloadlen = NGHTTP2_ALTSVC_MINLEN + protocol_id_len + host_len - 1; nghttp2_put_uint16be(buf->pos, payloadlen); + oframe.payload = &oaltsvc; + CU_ASSERT(NGHTTP2_ERR_FRAME_SIZE_ERROR == nghttp2_frame_unpack_altsvc_payload (&oframe, @@ -529,12 +543,17 @@ void test_nghttp2_frame_pack_altsvc(void) buf->pos + NGHTTP2_FRAME_HDLEN + NGHTTP2_ALTSVC_FIXED_PARTLEN, payloadlen - NGHTTP2_ALTSVC_FIXED_PARTLEN)); + memset(&oframe, 0, sizeof(oframe)); + memset(&oaltsvc, 0, sizeof(oaltsvc)); + /* Check no host case */ payloadlen = NGHTTP2_ALTSVC_MINLEN + protocol_id_len; nghttp2_put_uint16be(buf->pos, payloadlen); buf->pos[NGHTTP2_FRAME_HDLEN + NGHTTP2_ALTSVC_FIXED_PARTLEN + protocol_id_len] = 0; + oframe.payload = &oaltsvc; + CU_ASSERT(0 == nghttp2_frame_unpack_altsvc_payload (&oframe, @@ -543,13 +562,19 @@ void test_nghttp2_frame_pack_altsvc(void) buf->pos + NGHTTP2_FRAME_HDLEN + NGHTTP2_ALTSVC_FIXED_PARTLEN, payloadlen - NGHTTP2_ALTSVC_FIXED_PARTLEN)); - CU_ASSERT(0 == oframe.host_len); - CU_ASSERT(0 == oframe.origin_len); + CU_ASSERT(protocol_id_len == oaltsvc.protocol_id_len); + CU_ASSERT(0 == oaltsvc.host_len); + CU_ASSERT(0 == oaltsvc.origin_len); + + memset(&oframe, 0, sizeof(oframe)); + memset(&oaltsvc, 0, sizeof(oaltsvc)); /* Check missing Host-Len */ payloadlen = NGHTTP2_ALTSVC_FIXED_PARTLEN + protocol_id_len; nghttp2_put_uint16be(buf->pos, payloadlen); + oframe.payload = &oaltsvc; + CU_ASSERT(NGHTTP2_ERR_FRAME_SIZE_ERROR == nghttp2_frame_unpack_altsvc_payload (&oframe, @@ -558,6 +583,9 @@ void test_nghttp2_frame_pack_altsvc(void) buf->pos + NGHTTP2_FRAME_HDLEN + NGHTTP2_ALTSVC_FIXED_PARTLEN, payloadlen - NGHTTP2_ALTSVC_FIXED_PARTLEN)); + memset(&oframe, 0, sizeof(oframe)); + memset(&oaltsvc, 0, sizeof(oaltsvc)); + nghttp2_bufs_free(&bufs); } diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c index 9a04bdd0..e8586394 100644 --- a/tests/nghttp2_session_test.c +++ b/tests/nghttp2_session_test.c @@ -57,11 +57,11 @@ typedef struct { accumulator *acc; scripted_data_feed *df; int frame_recv_cb_called, invalid_frame_recv_cb_called; - nghttp2_frame_type recv_frame_type; + uint8_t recv_frame_type; int frame_send_cb_called; - nghttp2_frame_type sent_frame_type; + uint8_t sent_frame_type; int frame_not_send_cb_called; - nghttp2_frame_type not_sent_frame_type; + uint8_t not_sent_frame_type; int not_sent_error; int stream_close_cb_called; size_t data_source_length; @@ -1055,6 +1055,7 @@ void test_nghttp2_session_recv_altsvc(void) nghttp2_session *session; nghttp2_session_callbacks callbacks; nghttp2_frame frame; + nghttp2_ext_altsvc altsvc; size_t protocol_id_len, host_len, origin_len; uint8_t *protocol_id, *host, *origin; uint8_t *data; @@ -1087,16 +1088,18 @@ void test_nghttp2_session_recv_altsvc(void) "http://www.example.org", origin_len); origin = data + protocol_id_len + host_len; - nghttp2_frame_altsvc_init(&frame.altsvc, 1000000007, 1u << 31, 4000, + frame.ext.payload = &altsvc; + + nghttp2_frame_altsvc_init(&frame.ext, 1000000007, 1u << 31, 4000, protocol_id, protocol_id_len, host, host_len, origin, origin_len); - rv = nghttp2_frame_pack_altsvc(&bufs, &frame.altsvc); + rv = nghttp2_frame_pack_altsvc(&bufs, &frame.ext); CU_ASSERT(0 == rv); CU_ASSERT(nghttp2_bufs_len(&bufs) > 0); - nghttp2_frame_altsvc_free(&frame.altsvc); + nghttp2_frame_altsvc_free(&frame.ext); buf = &bufs.head->buf; assert(nghttp2_bufs_len(&bufs) == nghttp2_buf_len(buf)); @@ -1124,7 +1127,7 @@ void test_nghttp2_session_recv_altsvc(void) CU_ASSERT(rv == nghttp2_buf_len(buf)); CU_ASSERT(1 == ud.frame_recv_cb_called); - CU_ASSERT(NGHTTP2_ALTSVC == ud.recv_frame_type); + CU_ASSERT(NGHTTP2_EXT_ALTSVC == ud.recv_frame_type); /* premature payload */ nghttp2_put_uint16be(buf->pos, 8); @@ -3529,6 +3532,7 @@ void test_nghttp2_submit_altsvc(void) const char host[] = "localhost"; const char origin[] = "http://localhost/"; nghttp2_frame *frame; + nghttp2_ext_altsvc *altsvc; nghttp2_outbound_item *item; my_user_data ud; @@ -3564,28 +3568,30 @@ void test_nghttp2_submit_altsvc(void) frame = OB_CTRL(item); - CU_ASSERT(NGHTTP2_ALTSVC == frame->hd.type); + CU_ASSERT(NGHTTP2_EXT_ALTSVC == frame->hd.type); CU_ASSERT(9 == frame->hd.stream_id); - CU_ASSERT(12345 == frame->altsvc.max_age); - CU_ASSERT(3000 == frame->altsvc.port); + altsvc = frame->ext.payload; - CU_ASSERT(strlen(protocol_id) == frame->altsvc.protocol_id_len); - CU_ASSERT(strlen(host) == frame->altsvc.host_len); - CU_ASSERT(strlen(origin) == frame->altsvc.origin_len); + CU_ASSERT(12345 == altsvc->max_age); + CU_ASSERT(3000 == altsvc->port); - CU_ASSERT(0 == memcmp(protocol_id, frame->altsvc.protocol_id, - frame->altsvc.protocol_id_len)); - CU_ASSERT(0 == memcmp(host, frame->altsvc.host, frame->altsvc.host_len)); - CU_ASSERT(0 == memcmp(origin, frame->altsvc.origin, - frame->altsvc.origin_len)); + CU_ASSERT(strlen(protocol_id) == altsvc->protocol_id_len); + CU_ASSERT(strlen(host) == altsvc->host_len); + CU_ASSERT(strlen(origin) == altsvc->origin_len); + + CU_ASSERT(0 == memcmp(protocol_id, altsvc->protocol_id, + altsvc->protocol_id_len)); + CU_ASSERT(0 == memcmp(host, altsvc->host, altsvc->host_len)); + CU_ASSERT(0 == memcmp(origin, altsvc->origin, + altsvc->origin_len)); ud.frame_send_cb_called = 0; CU_ASSERT(0 == nghttp2_session_send(session)); CU_ASSERT(1 == ud.frame_send_cb_called); - CU_ASSERT(NGHTTP2_ALTSVC == ud.sent_frame_type); + CU_ASSERT(NGHTTP2_EXT_ALTSVC == ud.sent_frame_type); nghttp2_session_del(session); } diff --git a/tests/nghttp2_test_helper.c b/tests/nghttp2_test_helper.c index c5e05664..171d0648 100644 --- a/tests/nghttp2_test_helper.c +++ b/tests/nghttp2_test_helper.c @@ -86,7 +86,7 @@ int unpack_frame(nghttp2_frame *frame, const uint8_t *in, size_t len) nghttp2_frame_unpack_window_update_payload (&frame->window_update, payload, payloadlen); break; - case NGHTTP2_ALTSVC: + case NGHTTP2_EXT_ALTSVC: gift_payloadlen = payloadlen - NGHTTP2_ALTSVC_FIXED_PARTLEN; gift_payload = malloc(gift_payloadlen); @@ -95,7 +95,7 @@ int unpack_frame(nghttp2_frame *frame, const uint8_t *in, size_t len) payloadlen -= NGHTTP2_ALTSVC_FIXED_PARTLEN; - rv = nghttp2_frame_unpack_altsvc_payload(&frame->altsvc, + rv = nghttp2_frame_unpack_altsvc_payload(&frame->ext, payload, payloadlen, gift_payload, gift_payloadlen); break;