Remove altsvc
This commit is contained in:
parent
e13c9102b8
commit
21b48d24e4
12
README.rst
12
README.rst
|
@ -22,9 +22,7 @@ Development Status
|
||||||
We started to implement h2-14
|
We started to implement h2-14
|
||||||
(http://tools.ietf.org/html/draft-ietf-httpbis-http2-14), the header
|
(http://tools.ietf.org/html/draft-ietf-httpbis-http2-14), the header
|
||||||
compression
|
compression
|
||||||
(http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09)
|
(http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09).
|
||||||
and HTTP Alternative Services
|
|
||||||
(http://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-04).
|
|
||||||
|
|
||||||
The nghttp2 code base was forked from spdylay project.
|
The nghttp2 code base was forked from spdylay project.
|
||||||
|
|
||||||
|
@ -34,7 +32,6 @@ HTTP/2 Features Support
|
||||||
Core frames handling Yes
|
Core frames handling Yes
|
||||||
Dependency Tree Yes
|
Dependency Tree Yes
|
||||||
Large header (CONTINUATION) Yes
|
Large header (CONTINUATION) Yes
|
||||||
ALTSVC extension Yes
|
|
||||||
=========================== =======
|
=========================== =======
|
||||||
|
|
||||||
Public Test Server
|
Public Test Server
|
||||||
|
@ -51,10 +48,7 @@ implementation.
|
||||||
|
|
||||||
* http://nghttp2.org/ (Upgrade / Direct)
|
* http://nghttp2.org/ (Upgrade / Direct)
|
||||||
|
|
||||||
``h2c-14`` and ``http/1.1``. We configured this server to send
|
``h2c-14`` and ``http/1.1``.
|
||||||
ALTSVC frame or Alt-Svc header field to announce that alternative
|
|
||||||
service is available at port 443.
|
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
|
@ -283,8 +277,6 @@ The HTTP Upgrade is performed like this::
|
||||||
(niv=2)
|
(niv=2)
|
||||||
[SETTINGS_MAX_CONCURRENT_STREAMS(3):100]
|
[SETTINGS_MAX_CONCURRENT_STREAMS(3):100]
|
||||||
[SETTINGS_INITIAL_WINDOW_SIZE(4):65535]
|
[SETTINGS_INITIAL_WINDOW_SIZE(4):65535]
|
||||||
[ 0.024] recv ALTSVC frame <length=43, flags=0x00, stream_id=0>
|
|
||||||
(max-age=86400, port=443, protocol_id=h2-14, host=nghttp2.org, origin=http://nghttp2.org)
|
|
||||||
[ 0.024] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
|
[ 0.024] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
|
||||||
; ACK
|
; ACK
|
||||||
(niv=0)
|
(niv=0)
|
||||||
|
|
|
@ -48,4 +48,3 @@ Resources
|
||||||
|
|
||||||
* http://tools.ietf.org/html/draft-ietf-httpbis-http2-14
|
* http://tools.ietf.org/html/draft-ietf-httpbis-http2-14
|
||||||
* http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09
|
* http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09
|
||||||
* http://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-04
|
|
||||||
|
|
|
@ -2929,32 +2929,9 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
* Submits ALTSVC frame with given parameters.
|
* This function previously submits ALTSVC frame with given
|
||||||
*
|
* parameters, but is deprecated and will be removed in a future
|
||||||
* The |flags| is currently ignored and should be
|
* release. This function does nothing and just return 0.
|
||||||
* :enum:`NGHTTP2_FLAG_NONE`.
|
|
||||||
*
|
|
||||||
* Only the server can send the ALTSVC frame. If |session| is
|
|
||||||
* initialized as client, this function fails and returns
|
|
||||||
* :enum:`NGHTTP2_ERR_PROTO`.
|
|
||||||
*
|
|
||||||
* If the |protocol_id_len| is 0, the |protocol_id| could be ``NULL``.
|
|
||||||
*
|
|
||||||
* If the |host_len| is 0, the |host| could be ``NULL``.
|
|
||||||
*
|
|
||||||
* If the |origin_len| is 0, the |origin| could be ``NULL``.
|
|
||||||
*
|
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
|
||||||
* negative error codes:
|
|
||||||
*
|
|
||||||
* :enum:`NGHTTP2_ERR_NOMEM`
|
|
||||||
* Out of memory.
|
|
||||||
* :enum:`NGHTTP2_ERR_PROTO`
|
|
||||||
* The function is invoked with |session| which was initialized as
|
|
||||||
* client.
|
|
||||||
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
|
|
||||||
* The combined length of |protocol_id_len|, |host_len| and
|
|
||||||
* |origin_len| is is too large.
|
|
||||||
*/
|
*/
|
||||||
int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags,
|
int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags,
|
||||||
int32_t stream_id, uint32_t max_age, uint16_t port,
|
int32_t stream_id, uint32_t max_age, uint16_t port,
|
||||||
|
|
|
@ -161,43 +161,6 @@ void nghttp2_frame_window_update_init(nghttp2_window_update *frame,
|
||||||
|
|
||||||
void nghttp2_frame_window_update_free(nghttp2_window_update *frame _U_) {}
|
void nghttp2_frame_window_update_free(nghttp2_window_update *frame _U_) {}
|
||||||
|
|
||||||
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
|
|
||||||
uint32_t max_age, uint16_t port,
|
|
||||||
uint8_t *protocol_id, size_t protocol_id_len,
|
|
||||||
uint8_t *host, size_t host_len, 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;
|
|
||||||
|
|
||||||
nghttp2_frame_hd_init(&frame->hd, payloadlen, NGHTTP2_EXT_ALTSVC,
|
|
||||||
NGHTTP2_FLAG_NONE, stream_id);
|
|
||||||
|
|
||||||
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_extension *frame) {
|
|
||||||
nghttp2_ext_altsvc *altsvc;
|
|
||||||
|
|
||||||
altsvc = frame->payload;
|
|
||||||
|
|
||||||
if (altsvc == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(altsvc->protocol_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nghttp2_frame_trail_padlen(nghttp2_frame *frame, size_t padlen) {
|
size_t nghttp2_frame_trail_padlen(nghttp2_frame *frame, size_t padlen) {
|
||||||
return padlen - ((frame->hd.flags & NGHTTP2_FLAG_PADDED) > 0);
|
return padlen - ((frame->hd.flags & NGHTTP2_FLAG_PADDED) > 0);
|
||||||
}
|
}
|
||||||
|
@ -684,106 +647,6 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
|
||||||
nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK;
|
nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
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, altsvc->max_age);
|
|
||||||
buf->last += 4;
|
|
||||||
|
|
||||||
nghttp2_put_uint16be(buf->last, altsvc->port);
|
|
||||||
buf->last += 2;
|
|
||||||
|
|
||||||
buf->last[0] = altsvc->protocol_id_len;
|
|
||||||
++buf->last;
|
|
||||||
|
|
||||||
rv = nghttp2_bufs_add(bufs, altsvc->protocol_id, altsvc->protocol_id_len);
|
|
||||||
if (rv != 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = nghttp2_bufs_addb(bufs, altsvc->host_len);
|
|
||||||
if (rv != 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = nghttp2_bufs_add(bufs, altsvc->host, altsvc->host_len);
|
|
||||||
if (rv != 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = nghttp2_bufs_add(bufs, altsvc->origin, altsvc->origin_len);
|
|
||||||
if (rv != 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
|
|
||||||
if (rv == NGHTTP2_ERR_BUFFER_ERROR) {
|
|
||||||
return NGHTTP2_ERR_FRAME_SIZE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
|
|
||||||
const uint8_t *payload,
|
|
||||||
size_t payloadlen _U_,
|
|
||||||
uint8_t *var_gift_payload,
|
|
||||||
size_t var_gift_payloadlen) {
|
|
||||||
nghttp2_buf buf;
|
|
||||||
nghttp2_ext_altsvc *altsvc;
|
|
||||||
|
|
||||||
altsvc = frame->payload;
|
|
||||||
|
|
||||||
altsvc->max_age = nghttp2_get_uint32(payload);
|
|
||||||
payload += 4;
|
|
||||||
|
|
||||||
altsvc->port = nghttp2_get_uint16(payload);
|
|
||||||
payload += 2;
|
|
||||||
|
|
||||||
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)altsvc->protocol_id_len) {
|
|
||||||
return NGHTTP2_ERR_FRAME_SIZE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
altsvc->protocol_id = buf.pos;
|
|
||||||
buf.pos += altsvc->protocol_id_len;
|
|
||||||
|
|
||||||
altsvc->host_len = *buf.pos;
|
|
||||||
++buf.pos;
|
|
||||||
|
|
||||||
if (nghttp2_buf_len(&buf) < (ssize_t)altsvc->host_len) {
|
|
||||||
return NGHTTP2_ERR_FRAME_SIZE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
altsvc->host = buf.pos;
|
|
||||||
buf.pos += altsvc->host_len;
|
|
||||||
|
|
||||||
altsvc->origin = buf.pos;
|
|
||||||
altsvc->origin_len = nghttp2_buf_len(&buf);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
|
nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
|
||||||
size_t niv) {
|
size_t niv) {
|
||||||
nghttp2_settings_entry *iv_copy;
|
nghttp2_settings_entry *iv_copy;
|
||||||
|
|
|
@ -73,14 +73,6 @@
|
||||||
/* Length of priority related fields in HEADERS/PRIORITY frames */
|
/* Length of priority related fields in HEADERS/PRIORITY frames */
|
||||||
#define NGHTTP2_PRIORITY_SPECLEN 5
|
#define NGHTTP2_PRIORITY_SPECLEN 5
|
||||||
|
|
||||||
/* Length of fixed part in ALTSVC frame, that is the sum of fields of
|
|
||||||
Max-Age, Port and Proto-Len. */
|
|
||||||
#define NGHTTP2_ALTSVC_FIXED_PARTLEN 7
|
|
||||||
|
|
||||||
/* Minimum length of ALTSVC extension frame payload.
|
|
||||||
NGHTTP2_ALTSVC_FIXED_PARTLEN + Host-Len. */
|
|
||||||
#define NGHTTP2_ALTSVC_MINLEN 8
|
|
||||||
|
|
||||||
/* Maximum length of padding in bytes. */
|
/* Maximum length of padding in bytes. */
|
||||||
#define NGHTTP2_MAX_PADLEN 256
|
#define NGHTTP2_MAX_PADLEN 256
|
||||||
|
|
||||||
|
@ -380,49 +372,6 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
|
||||||
const uint8_t *payload,
|
const uint8_t *payload,
|
||||||
size_t payloadlen);
|
size_t payloadlen);
|
||||||
|
|
||||||
/*
|
|
||||||
* Packs ALTSVC frame |frame| in wire format and store it in |bufs|.
|
|
||||||
* This function expands |bufs| as necessary to store 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:
|
|
||||||
*
|
|
||||||
* NGHTTP2_ERR_NOMEM
|
|
||||||
* Out of memory.
|
|
||||||
* NGHTTP2_ERR_FRAME_SIZE_ERROR
|
|
||||||
* The length of the frame is too large.
|
|
||||||
*/
|
|
||||||
int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Unpacks ALTSVC frame byte sequence 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_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_extension *frame,
|
|
||||||
const uint8_t *payload,
|
|
||||||
size_t payloadlen,
|
|
||||||
uint8_t *var_gift_payload,
|
|
||||||
size_t var_gift_payloadlen);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes HEADERS frame |frame| with given values. |frame| takes
|
* Initializes HEADERS frame |frame| with given values. |frame| takes
|
||||||
* ownership of |nva|, so caller must not free it. If |stream_id| is
|
* ownership of |nva|, so caller must not free it. If |stream_id| is
|
||||||
|
@ -494,24 +443,6 @@ void nghttp2_frame_window_update_init(nghttp2_window_update *frame,
|
||||||
|
|
||||||
void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
|
void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
|
||||||
|
|
||||||
/* protocol_id, host and origin must be allocated to the one chunk of
|
|
||||||
memory region and protocol_id must point to it. We only free
|
|
||||||
protocol_id. This means that |protocol_id| is not NULL even if
|
|
||||||
|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_extension *frame, int32_t stream_id,
|
|
||||||
uint32_t max_age, uint16_t port,
|
|
||||||
uint8_t *protocol_id, size_t protocol_id_len,
|
|
||||||
uint8_t *host, size_t host_len, uint8_t *origin,
|
|
||||||
size_t origin_len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Frees resources used by |frame|. This function does not free
|
|
||||||
* frame->payload itself.
|
|
||||||
*/
|
|
||||||
void nghttp2_frame_altsvc_free(nghttp2_extension *frame);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the number of padding bytes after payload. The total
|
* Returns the number of padding bytes after payload. The total
|
||||||
* padding length is given in the |padlen|. The returned value does
|
* padding length is given in the |padlen|. The returned value does
|
||||||
|
|
|
@ -63,9 +63,5 @@ void nghttp2_outbound_item_free(nghttp2_outbound_item *item) {
|
||||||
case NGHTTP2_WINDOW_UPDATE:
|
case NGHTTP2_WINDOW_UPDATE:
|
||||||
nghttp2_frame_window_update_free(&frame->window_update);
|
nghttp2_frame_window_update_free(&frame->window_update);
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_EXT_ALTSVC:
|
|
||||||
nghttp2_frame_altsvc_free(&frame->ext);
|
|
||||||
free(frame->ext.payload);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,9 +246,6 @@ static void session_inbound_frame_reset(nghttp2_session *session) {
|
||||||
case NGHTTP2_WINDOW_UPDATE:
|
case NGHTTP2_WINDOW_UPDATE:
|
||||||
nghttp2_frame_window_update_free(&iframe->frame.window_update);
|
nghttp2_frame_window_update_free(&iframe->frame.window_update);
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_EXT_ALTSVC:
|
|
||||||
nghttp2_frame_altsvc_free(&iframe->frame.ext);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&iframe->frame, 0, sizeof(nghttp2_frame));
|
memset(&iframe->frame, 0, sizeof(nghttp2_frame));
|
||||||
|
@ -1402,40 +1399,6 @@ static int session_predicate_window_update_send(nghttp2_session *session,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function checks ALTSVC with the stream ID |stream_id| can be
|
|
||||||
* sent at this time. If |stream_id| is 0, ATLSVC frame is always
|
|
||||||
* allowed to send.
|
|
||||||
*
|
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
|
||||||
* negative error codes:
|
|
||||||
*
|
|
||||||
* NGHTTP2_ERR_STREAM_CLOSED
|
|
||||||
* The stream is already closed or does not exist.
|
|
||||||
* NGHTTP2_ERR_STREAM_CLOSING
|
|
||||||
* RST_STREAM was queued for this stream.
|
|
||||||
*/
|
|
||||||
static int session_predicate_altsvc_send(nghttp2_session *session,
|
|
||||||
int32_t stream_id) {
|
|
||||||
nghttp2_stream *stream;
|
|
||||||
|
|
||||||
if (stream_id == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream = nghttp2_session_get_stream(session, stream_id);
|
|
||||||
|
|
||||||
if (stream == NULL) {
|
|
||||||
return NGHTTP2_ERR_STREAM_CLOSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream->state == NGHTTP2_STREAM_CLOSING) {
|
|
||||||
return NGHTTP2_ERR_STREAM_CLOSING;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function checks SETTINGS can be sent at this time.
|
* This function checks SETTINGS can be sent at this time.
|
||||||
*
|
*
|
||||||
|
@ -1832,19 +1795,6 @@ static int session_prep_frame(nghttp2_session *session,
|
||||||
}
|
}
|
||||||
session->local_last_stream_id = frame->goaway.last_stream_id;
|
session->local_last_stream_id = frame->goaway.last_stream_id;
|
||||||
|
|
||||||
break;
|
|
||||||
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->ext);
|
|
||||||
|
|
||||||
if (framerv < 0) {
|
|
||||||
return framerv;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||||
|
@ -3942,40 +3892,6 @@ static int session_process_goaway_frame(nghttp2_session *session) {
|
||||||
return nghttp2_session_on_goaway_received(session, frame);
|
return nghttp2_session_on_goaway_received(session, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_session_on_altsvc_received(nghttp2_session *session,
|
|
||||||
nghttp2_frame *frame) {
|
|
||||||
/* ALTSVC is exptected to be received by client only. We have
|
|
||||||
already rejected ALTSVC if it is received by server. */
|
|
||||||
if (frame->hd.stream_id != 0 &&
|
|
||||||
!nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) {
|
|
||||||
return session_handle_invalid_connection(
|
|
||||||
session, frame, NGHTTP2_PROTOCOL_ERROR, "ALTSVC: invalid stream_id");
|
|
||||||
}
|
|
||||||
|
|
||||||
return session_call_on_frame_received(session, frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int session_process_altsvc_frame(nghttp2_session *session) {
|
|
||||||
nghttp2_inbound_frame *iframe = &session->iframe;
|
|
||||||
nghttp2_frame *frame = &iframe->frame;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
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, nghttp2_buf_len(&iframe->lbuf));
|
|
||||||
|
|
||||||
if (rv != 0) {
|
|
||||||
return session_handle_invalid_connection(
|
|
||||||
session, frame, NGHTTP2_FRAME_SIZE_ERROR, "ALTSVC: could not unpack");
|
|
||||||
}
|
|
||||||
|
|
||||||
nghttp2_buf_wrap_init(&iframe->lbuf, NULL, 0);
|
|
||||||
|
|
||||||
return nghttp2_session_on_altsvc_received(session, frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
session_on_connection_window_update_received(nghttp2_session *session,
|
session_on_connection_window_update_received(nghttp2_session *session,
|
||||||
nghttp2_frame *frame) {
|
nghttp2_frame *frame) {
|
||||||
|
@ -4828,38 +4744,6 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||||
|
|
||||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||||
|
|
||||||
break;
|
|
||||||
case NGHTTP2_EXT_ALTSVC:
|
|
||||||
DEBUGF(fprintf(stderr, "recv: ALTSVC\n"));
|
|
||||||
|
|
||||||
iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
|
|
||||||
|
|
||||||
if (session->server) {
|
|
||||||
rv = nghttp2_session_terminate_session_with_reason(
|
|
||||||
session, NGHTTP2_PROTOCOL_ERROR,
|
|
||||||
"ALTSVC: reserved for server only");
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
busy = 1;
|
|
||||||
|
|
||||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iframe->payloadleft < NGHTTP2_ALTSVC_MINLEN) {
|
|
||||||
busy = 1;
|
|
||||||
|
|
||||||
iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
iframe->state = NGHTTP2_IB_READ_NBYTE;
|
|
||||||
inbound_frame_set_mark(iframe, NGHTTP2_ALTSVC_FIXED_PARTLEN);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DEBUGF(fprintf(stderr, "recv: unknown frame\n"));
|
DEBUGF(fprintf(stderr, "recv: unknown frame\n"));
|
||||||
|
@ -5059,27 +4943,6 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||||
session_inbound_frame_reset(session);
|
session_inbound_frame_reset(session);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_EXT_ALTSVC: {
|
|
||||||
size_t varlen;
|
|
||||||
|
|
||||||
varlen = iframe->frame.hd.length - NGHTTP2_ALTSVC_FIXED_PARTLEN;
|
|
||||||
|
|
||||||
if (varlen > 0) {
|
|
||||||
iframe->raw_lbuf = malloc(varlen);
|
|
||||||
|
|
||||||
if (iframe->raw_lbuf == NULL) {
|
|
||||||
return NGHTTP2_ERR_NOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
nghttp2_buf_wrap_init(&iframe->lbuf, iframe->raw_lbuf, varlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
busy = 1;
|
|
||||||
|
|
||||||
iframe->state = NGHTTP2_IB_READ_ALTSVC;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
/* This is unknown frame */
|
/* This is unknown frame */
|
||||||
session_inbound_frame_reset(session);
|
session_inbound_frame_reset(session);
|
||||||
|
@ -5265,14 +5128,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_IB_READ_GOAWAY_DEBUG:
|
case NGHTTP2_IB_READ_GOAWAY_DEBUG:
|
||||||
case NGHTTP2_IB_READ_ALTSVC:
|
DEBUGF(fprintf(stderr, "recv: [IB_READ_GOAWAY_DEBUG]\n"));
|
||||||
#ifdef DEBUGBUILD
|
|
||||||
if (iframe->state == NGHTTP2_IB_READ_GOAWAY_DEBUG) {
|
|
||||||
fprintf(stderr, "recv: [IB_READ_GOAWAY_DEBUG]\n");
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "recv: [IB_READ_ALTSVC]\n");
|
|
||||||
}
|
|
||||||
#endif /* DEBUGBUILD */
|
|
||||||
|
|
||||||
readlen = inbound_frame_payload_readlen(iframe, in, last);
|
readlen = inbound_frame_payload_readlen(iframe, in, last);
|
||||||
|
|
||||||
|
@ -5290,11 +5146,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iframe->state == NGHTTP2_IB_READ_GOAWAY_DEBUG) {
|
rv = session_process_goaway_frame(session);
|
||||||
rv = session_process_goaway_frame(session);
|
|
||||||
} else {
|
|
||||||
rv = session_process_altsvc_frame(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
if (nghttp2_is_fatal(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -76,7 +76,6 @@ typedef enum {
|
||||||
NGHTTP2_IB_FRAME_SIZE_ERROR,
|
NGHTTP2_IB_FRAME_SIZE_ERROR,
|
||||||
NGHTTP2_IB_READ_SETTINGS,
|
NGHTTP2_IB_READ_SETTINGS,
|
||||||
NGHTTP2_IB_READ_GOAWAY_DEBUG,
|
NGHTTP2_IB_READ_GOAWAY_DEBUG,
|
||||||
NGHTTP2_IB_READ_ALTSVC,
|
|
||||||
NGHTTP2_IB_EXPECT_CONTINUATION,
|
NGHTTP2_IB_EXPECT_CONTINUATION,
|
||||||
NGHTTP2_IB_IGN_CONTINUATION,
|
NGHTTP2_IB_IGN_CONTINUATION,
|
||||||
NGHTTP2_IB_READ_PAD_DATA,
|
NGHTTP2_IB_READ_PAD_DATA,
|
||||||
|
@ -619,21 +618,6 @@ int nghttp2_session_on_goaway_received(nghttp2_session *session,
|
||||||
int nghttp2_session_on_window_update_received(nghttp2_session *session,
|
int nghttp2_session_on_window_update_received(nghttp2_session *session,
|
||||||
nghttp2_frame *frame);
|
nghttp2_frame *frame);
|
||||||
|
|
||||||
/*
|
|
||||||
* Called when ALTSVC is received, assuming |frame| is properly
|
|
||||||
* initialized.
|
|
||||||
*
|
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
|
||||||
* negative error codes:
|
|
||||||
*
|
|
||||||
* NGHTTP2_ERR_NOMEM
|
|
||||||
* Out of memory.
|
|
||||||
* NGHTTP2_ERR_CALLBACK_FAILURE
|
|
||||||
* The callback function failed.
|
|
||||||
*/
|
|
||||||
int nghttp2_session_on_altsvc_received(nghttp2_session *session,
|
|
||||||
nghttp2_frame *frame);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called when DATA is received, assuming |frame| is properly
|
* Called when DATA is received, assuming |frame| is properly
|
||||||
* initialized.
|
* initialized.
|
||||||
|
|
|
@ -342,106 +342,13 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags _U_,
|
int nghttp2_submit_altsvc(nghttp2_session *session _U_, uint8_t flags _U_,
|
||||||
int32_t stream_id, uint32_t max_age, uint16_t port,
|
int32_t stream_id _U_, uint32_t max_age _U_,
|
||||||
const uint8_t *protocol_id, size_t protocol_id_len,
|
uint16_t port _U_, const uint8_t *protocol_id _U_,
|
||||||
const uint8_t *host, size_t host_len,
|
size_t protocol_id_len _U_, const uint8_t *host _U_,
|
||||||
const uint8_t *origin, size_t origin_len) {
|
size_t host_len _U_, const uint8_t *origin _U_,
|
||||||
int rv;
|
size_t origin_len _U_) {
|
||||||
size_t varlen;
|
|
||||||
uint8_t *var, *varp;
|
|
||||||
nghttp2_outbound_item *item;
|
|
||||||
nghttp2_frame *frame;
|
|
||||||
nghttp2_ext_altsvc *altsvc;
|
|
||||||
uint8_t *copy_protocol_id, *copy_host, *copy_origin;
|
|
||||||
|
|
||||||
if (!session->server) {
|
|
||||||
return NGHTTP2_ERR_PROTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
varlen = protocol_id_len + host_len + origin_len;
|
|
||||||
|
|
||||||
/* 9 = fixed part 8 bytes + HOST_LEN 1 byte */
|
|
||||||
if (varlen + 9 > NGHTTP2_MAX_PAYLOADLEN) {
|
|
||||||
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;
|
|
||||||
copy_host = NULL;
|
|
||||||
copy_origin = NULL;
|
|
||||||
} else {
|
|
||||||
var = malloc(varlen);
|
|
||||||
|
|
||||||
if (var == NULL) {
|
|
||||||
rv = NGHTTP2_ERR_NOMEM;
|
|
||||||
|
|
||||||
goto var_alloc_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
varp = var;
|
|
||||||
|
|
||||||
memcpy(varp, protocol_id, protocol_id_len);
|
|
||||||
|
|
||||||
copy_protocol_id = varp;
|
|
||||||
varp += protocol_id_len;
|
|
||||||
|
|
||||||
memcpy(varp, host, host_len);
|
|
||||||
|
|
||||||
copy_host = varp;
|
|
||||||
varp += host_len;
|
|
||||||
|
|
||||||
memcpy(varp, origin, origin_len);
|
|
||||||
|
|
||||||
copy_origin = varp;
|
|
||||||
}
|
|
||||||
|
|
||||||
item = malloc(sizeof(nghttp2_outbound_item));
|
|
||||||
|
|
||||||
if (item == NULL) {
|
|
||||||
rv = NGHTTP2_ERR_NOMEM;
|
|
||||||
|
|
||||||
goto frame_alloc_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
nghttp2_session_outbound_item_init(session, item);
|
|
||||||
|
|
||||||
frame = &item->frame;
|
|
||||||
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_item(session, item);
|
|
||||||
|
|
||||||
if (rv != 0) {
|
|
||||||
nghttp2_frame_altsvc_free(&frame->ext);
|
|
||||||
free(item);
|
|
||||||
free(altsvc);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
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,
|
static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec,
|
||||||
|
|
|
@ -86,8 +86,6 @@ int main(int argc _U_, char *argv[] _U_) {
|
||||||
test_nghttp2_session_recv_headers_with_priority) ||
|
test_nghttp2_session_recv_headers_with_priority) ||
|
||||||
!CU_add_test(pSuite, "session_recv_premature_headers",
|
!CU_add_test(pSuite, "session_recv_premature_headers",
|
||||||
test_nghttp2_session_recv_premature_headers) ||
|
test_nghttp2_session_recv_premature_headers) ||
|
||||||
!CU_add_test(pSuite, "session_recv_altsvc",
|
|
||||||
test_nghttp2_session_recv_altsvc) ||
|
|
||||||
!CU_add_test(pSuite, "session_recv_unknown_frame",
|
!CU_add_test(pSuite, "session_recv_unknown_frame",
|
||||||
test_nghttp2_session_recv_unknown_frame) ||
|
test_nghttp2_session_recv_unknown_frame) ||
|
||||||
!CU_add_test(pSuite, "session_recv_unexpected_continuation",
|
!CU_add_test(pSuite, "session_recv_unexpected_continuation",
|
||||||
|
@ -176,7 +174,6 @@ int main(int argc _U_, char *argv[] _U_) {
|
||||||
test_nghttp2_submit_window_update) ||
|
test_nghttp2_submit_window_update) ||
|
||||||
!CU_add_test(pSuite, "submit_window_update_local_window_size",
|
!CU_add_test(pSuite, "submit_window_update_local_window_size",
|
||||||
test_nghttp2_submit_window_update_local_window_size) ||
|
test_nghttp2_submit_window_update_local_window_size) ||
|
||||||
!CU_add_test(pSuite, "submit_altsvc", test_nghttp2_submit_altsvc) ||
|
|
||||||
!CU_add_test(pSuite, "submit_invalid_nv",
|
!CU_add_test(pSuite, "submit_invalid_nv",
|
||||||
test_nghttp2_submit_invalid_nv) ||
|
test_nghttp2_submit_invalid_nv) ||
|
||||||
!CU_add_test(pSuite, "session_open_stream",
|
!CU_add_test(pSuite, "session_open_stream",
|
||||||
|
@ -273,8 +270,6 @@ int main(int argc _U_, char *argv[] _U_) {
|
||||||
test_nghttp2_frame_pack_goaway) ||
|
test_nghttp2_frame_pack_goaway) ||
|
||||||
!CU_add_test(pSuite, "frame_pack_window_update",
|
!CU_add_test(pSuite, "frame_pack_window_update",
|
||||||
test_nghttp2_frame_pack_window_update) ||
|
test_nghttp2_frame_pack_window_update) ||
|
||||||
!CU_add_test(pSuite, "frame_pack_altsvc",
|
|
||||||
test_nghttp2_frame_pack_altsvc) ||
|
|
||||||
!CU_add_test(pSuite, "nv_array_copy", test_nghttp2_nv_array_copy) ||
|
!CU_add_test(pSuite, "nv_array_copy", test_nghttp2_nv_array_copy) ||
|
||||||
!CU_add_test(pSuite, "iv_check", test_nghttp2_iv_check) ||
|
!CU_add_test(pSuite, "iv_check", test_nghttp2_iv_check) ||
|
||||||
!CU_add_test(pSuite, "hd_deflate", test_nghttp2_hd_deflate) ||
|
!CU_add_test(pSuite, "hd_deflate", test_nghttp2_hd_deflate) ||
|
||||||
|
|
|
@ -442,156 +442,6 @@ void test_nghttp2_frame_pack_window_update(void) {
|
||||||
nghttp2_frame_window_update_free(&frame);
|
nghttp2_frame_window_update_free(&frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_nghttp2_frame_pack_altsvc(void) {
|
|
||||||
nghttp2_extension frame, oframe;
|
|
||||||
nghttp2_ext_altsvc altsvc, oaltsvc;
|
|
||||||
nghttp2_bufs bufs;
|
|
||||||
nghttp2_buf *buf;
|
|
||||||
size_t protocol_id_len, host_len, origin_len;
|
|
||||||
uint8_t *protocol_id, *host, *origin;
|
|
||||||
uint8_t *data;
|
|
||||||
size_t datalen;
|
|
||||||
int rv;
|
|
||||||
size_t payloadlen;
|
|
||||||
|
|
||||||
protocol_id_len = strlen("h2");
|
|
||||||
host_len = strlen("h2.example.org");
|
|
||||||
origin_len = strlen("www.example.org");
|
|
||||||
|
|
||||||
datalen = protocol_id_len + host_len + origin_len;
|
|
||||||
data = malloc(datalen);
|
|
||||||
|
|
||||||
memcpy(data, "h2", protocol_id_len);
|
|
||||||
protocol_id = data;
|
|
||||||
|
|
||||||
memcpy(data + protocol_id_len, "h2.example.org", host_len);
|
|
||||||
host = data + protocol_id_len;
|
|
||||||
|
|
||||||
memcpy(data + protocol_id_len + host_len, "http://www.example.org",
|
|
||||||
origin_len);
|
|
||||||
origin = data + protocol_id_len + host_len;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
rv = nghttp2_frame_pack_altsvc(&bufs, &frame);
|
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
|
||||||
|
|
||||||
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_EXT_ALTSVC,
|
|
||||||
NGHTTP2_FLAG_NONE, 1000000007, &oframe.hd);
|
|
||||||
CU_ASSERT(1u << 31 == oaltsvc.max_age);
|
|
||||||
CU_ASSERT(4000 == oaltsvc.port);
|
|
||||||
|
|
||||||
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 == oaltsvc.host_len);
|
|
||||||
CU_ASSERT(memcmp(host, oaltsvc.host, host_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;
|
|
||||||
|
|
||||||
CU_ASSERT(buf->pos - buf->begin == 1);
|
|
||||||
|
|
||||||
/* Check no origin case */
|
|
||||||
|
|
||||||
payloadlen = NGHTTP2_ALTSVC_MINLEN + protocol_id_len + host_len;
|
|
||||||
nghttp2_put_uint32be(buf->pos, (uint32_t)((payloadlen << 8) + buf->pos[3]));
|
|
||||||
|
|
||||||
oframe.payload = &oaltsvc;
|
|
||||||
|
|
||||||
CU_ASSERT(0 ==
|
|
||||||
nghttp2_frame_unpack_altsvc_payload(
|
|
||||||
&oframe, buf->pos + NGHTTP2_FRAME_HDLEN,
|
|
||||||
NGHTTP2_ALTSVC_FIXED_PARTLEN,
|
|
||||||
buf->pos + NGHTTP2_FRAME_HDLEN + NGHTTP2_ALTSVC_FIXED_PARTLEN,
|
|
||||||
payloadlen - NGHTTP2_ALTSVC_FIXED_PARTLEN));
|
|
||||||
|
|
||||||
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_uint32be(buf->pos, (uint32_t)((payloadlen << 8) + buf->pos[3]));
|
|
||||||
|
|
||||||
oframe.payload = &oaltsvc;
|
|
||||||
|
|
||||||
CU_ASSERT(NGHTTP2_ERR_FRAME_SIZE_ERROR ==
|
|
||||||
nghttp2_frame_unpack_altsvc_payload(
|
|
||||||
&oframe, buf->pos + NGHTTP2_FRAME_HDLEN,
|
|
||||||
NGHTTP2_ALTSVC_FIXED_PARTLEN,
|
|
||||||
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_uint32be(buf->pos, (uint32_t)((payloadlen << 8) + buf->pos[3]));
|
|
||||||
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, buf->pos + NGHTTP2_FRAME_HDLEN,
|
|
||||||
NGHTTP2_ALTSVC_FIXED_PARTLEN,
|
|
||||||
buf->pos + NGHTTP2_FRAME_HDLEN + NGHTTP2_ALTSVC_FIXED_PARTLEN,
|
|
||||||
payloadlen - NGHTTP2_ALTSVC_FIXED_PARTLEN));
|
|
||||||
|
|
||||||
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_uint32be(buf->pos, (uint32_t)((payloadlen << 8) + buf->pos[3]));
|
|
||||||
|
|
||||||
oframe.payload = &oaltsvc;
|
|
||||||
|
|
||||||
CU_ASSERT(NGHTTP2_ERR_FRAME_SIZE_ERROR ==
|
|
||||||
nghttp2_frame_unpack_altsvc_payload(
|
|
||||||
&oframe, buf->pos + NGHTTP2_FRAME_HDLEN,
|
|
||||||
NGHTTP2_ALTSVC_FIXED_PARTLEN,
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_nghttp2_nv_array_copy(void) {
|
void test_nghttp2_nv_array_copy(void) {
|
||||||
nghttp2_nv *nva;
|
nghttp2_nv *nva;
|
||||||
ssize_t rv;
|
ssize_t rv;
|
||||||
|
|
|
@ -34,7 +34,6 @@ void test_nghttp2_frame_pack_push_promise(void);
|
||||||
void test_nghttp2_frame_pack_ping(void);
|
void test_nghttp2_frame_pack_ping(void);
|
||||||
void test_nghttp2_frame_pack_goaway(void);
|
void test_nghttp2_frame_pack_goaway(void);
|
||||||
void test_nghttp2_frame_pack_window_update(void);
|
void test_nghttp2_frame_pack_window_update(void);
|
||||||
void test_nghttp2_frame_pack_altsvc(void);
|
|
||||||
void test_nghttp2_nv_array_copy(void);
|
void test_nghttp2_nv_array_copy(void);
|
||||||
void test_nghttp2_iv_check(void);
|
void test_nghttp2_iv_check(void);
|
||||||
|
|
||||||
|
|
|
@ -1075,102 +1075,6 @@ void test_nghttp2_session_recv_premature_headers(void) {
|
||||||
nghttp2_session_del(session);
|
nghttp2_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
size_t datalen;
|
|
||||||
nghttp2_bufs bufs;
|
|
||||||
nghttp2_buf *buf;
|
|
||||||
ssize_t rv;
|
|
||||||
my_user_data ud;
|
|
||||||
nghttp2_outbound_item *item;
|
|
||||||
|
|
||||||
frame_pack_bufs_init(&bufs);
|
|
||||||
|
|
||||||
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
|
||||||
callbacks.on_frame_recv_callback = on_frame_recv_callback;
|
|
||||||
|
|
||||||
protocol_id_len = strlen("h2");
|
|
||||||
host_len = strlen("h2.example.org");
|
|
||||||
origin_len = strlen("www.example.org");
|
|
||||||
|
|
||||||
datalen = protocol_id_len + host_len + origin_len;
|
|
||||||
data = malloc(datalen);
|
|
||||||
|
|
||||||
memcpy(data, "h2", protocol_id_len);
|
|
||||||
protocol_id = data;
|
|
||||||
|
|
||||||
memcpy(data + protocol_id_len, "h2.example.org", host_len);
|
|
||||||
host = data + protocol_id_len;
|
|
||||||
|
|
||||||
memcpy(data + protocol_id_len + host_len, "http://www.example.org",
|
|
||||||
origin_len);
|
|
||||||
origin = data + protocol_id_len + host_len;
|
|
||||||
|
|
||||||
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.ext);
|
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
|
||||||
CU_ASSERT(nghttp2_bufs_len(&bufs) > 0);
|
|
||||||
|
|
||||||
nghttp2_frame_altsvc_free(&frame.ext);
|
|
||||||
|
|
||||||
buf = &bufs.head->buf;
|
|
||||||
assert(nghttp2_bufs_len(&bufs) == nghttp2_buf_len(buf));
|
|
||||||
|
|
||||||
/* error if server receives ALTSVC */
|
|
||||||
nghttp2_session_server_new(&session, &callbacks, &ud);
|
|
||||||
|
|
||||||
ud.frame_recv_cb_called = 0;
|
|
||||||
|
|
||||||
rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
|
|
||||||
|
|
||||||
CU_ASSERT(rv == nghttp2_buf_len(buf));
|
|
||||||
CU_ASSERT(0 == ud.frame_recv_cb_called);
|
|
||||||
|
|
||||||
item = nghttp2_session_get_next_ob_item(session);
|
|
||||||
CU_ASSERT(NGHTTP2_GOAWAY == item->frame.hd.type);
|
|
||||||
|
|
||||||
nghttp2_session_del(session);
|
|
||||||
|
|
||||||
nghttp2_session_client_new(&session, &callbacks, &ud);
|
|
||||||
|
|
||||||
ud.frame_recv_cb_called = 0;
|
|
||||||
|
|
||||||
rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
|
|
||||||
|
|
||||||
CU_ASSERT(rv == nghttp2_buf_len(buf));
|
|
||||||
CU_ASSERT(1 == ud.frame_recv_cb_called);
|
|
||||||
CU_ASSERT(NGHTTP2_EXT_ALTSVC == ud.recv_frame_type);
|
|
||||||
|
|
||||||
/* premature payload */
|
|
||||||
nghttp2_put_uint32be(buf->pos, (8 << 8) + buf->pos[3]);
|
|
||||||
|
|
||||||
ud.frame_recv_cb_called = 0;
|
|
||||||
|
|
||||||
rv = nghttp2_session_mem_recv(session, buf->pos, NGHTTP2_FRAME_HDLEN + 8);
|
|
||||||
|
|
||||||
CU_ASSERT(rv == NGHTTP2_FRAME_HDLEN + 8);
|
|
||||||
CU_ASSERT(0 == ud.frame_recv_cb_called);
|
|
||||||
|
|
||||||
item = nghttp2_session_get_next_ob_item(session);
|
|
||||||
|
|
||||||
CU_ASSERT(NGHTTP2_GOAWAY == item->frame.hd.type);
|
|
||||||
|
|
||||||
nghttp2_bufs_free(&bufs);
|
|
||||||
nghttp2_session_del(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_nghttp2_session_recv_unknown_frame(void) {
|
void test_nghttp2_session_recv_unknown_frame(void) {
|
||||||
nghttp2_session *session;
|
nghttp2_session *session;
|
||||||
nghttp2_session_callbacks callbacks;
|
nghttp2_session_callbacks callbacks;
|
||||||
|
@ -4052,73 +3956,6 @@ void test_nghttp2_submit_window_update_local_window_size(void) {
|
||||||
nghttp2_session_del(session);
|
nghttp2_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_nghttp2_submit_altsvc(void) {
|
|
||||||
nghttp2_session *session;
|
|
||||||
nghttp2_session_callbacks callbacks;
|
|
||||||
const char protocol_id[] = "h2";
|
|
||||||
const char host[] = "localhost";
|
|
||||||
const char origin[] = "http://localhost/";
|
|
||||||
nghttp2_frame *frame;
|
|
||||||
nghttp2_ext_altsvc *altsvc;
|
|
||||||
nghttp2_outbound_item *item;
|
|
||||||
my_user_data ud;
|
|
||||||
|
|
||||||
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
|
||||||
callbacks.send_callback = null_send_callback;
|
|
||||||
callbacks.on_frame_send_callback = on_frame_send_callback;
|
|
||||||
|
|
||||||
nghttp2_session_client_new(&session, &callbacks, NULL);
|
|
||||||
|
|
||||||
CU_ASSERT(NGHTTP2_ERR_PROTO ==
|
|
||||||
nghttp2_submit_altsvc(session, NGHTTP2_FLAG_NONE, 0, 0, 3000,
|
|
||||||
(const uint8_t *)protocol_id,
|
|
||||||
strlen(protocol_id), (const uint8_t *)host,
|
|
||||||
strlen(host), (const uint8_t *)origin,
|
|
||||||
strlen(origin)));
|
|
||||||
|
|
||||||
nghttp2_session_del(session);
|
|
||||||
|
|
||||||
nghttp2_session_server_new(&session, &callbacks, &ud);
|
|
||||||
|
|
||||||
open_stream(session, 9);
|
|
||||||
|
|
||||||
CU_ASSERT(0 == nghttp2_submit_altsvc(
|
|
||||||
session, NGHTTP2_FLAG_NONE, 9, 12345, 3000,
|
|
||||||
(const uint8_t *)protocol_id, strlen(protocol_id),
|
|
||||||
(const uint8_t *)host, strlen(host),
|
|
||||||
(const uint8_t *)origin, strlen(origin)));
|
|
||||||
|
|
||||||
item = nghttp2_session_get_next_ob_item(session);
|
|
||||||
|
|
||||||
frame = &item->frame;
|
|
||||||
|
|
||||||
CU_ASSERT(NGHTTP2_EXT_ALTSVC == frame->hd.type);
|
|
||||||
CU_ASSERT(9 == frame->hd.stream_id);
|
|
||||||
|
|
||||||
altsvc = frame->ext.payload;
|
|
||||||
|
|
||||||
CU_ASSERT(12345 == altsvc->max_age);
|
|
||||||
CU_ASSERT(3000 == altsvc->port);
|
|
||||||
|
|
||||||
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_EXT_ALTSVC == ud.sent_frame_type);
|
|
||||||
|
|
||||||
nghttp2_session_del(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_nghttp2_submit_invalid_nv(void) {
|
void test_nghttp2_submit_invalid_nv(void) {
|
||||||
nghttp2_session *session;
|
nghttp2_session *session;
|
||||||
nghttp2_session_callbacks callbacks;
|
nghttp2_session_callbacks callbacks;
|
||||||
|
|
|
@ -33,7 +33,6 @@ void test_nghttp2_session_recv_data(void);
|
||||||
void test_nghttp2_session_recv_continuation(void);
|
void test_nghttp2_session_recv_continuation(void);
|
||||||
void test_nghttp2_session_recv_headers_with_priority(void);
|
void test_nghttp2_session_recv_headers_with_priority(void);
|
||||||
void test_nghttp2_session_recv_premature_headers(void);
|
void test_nghttp2_session_recv_premature_headers(void);
|
||||||
void test_nghttp2_session_recv_altsvc(void);
|
|
||||||
void test_nghttp2_session_recv_unknown_frame(void);
|
void test_nghttp2_session_recv_unknown_frame(void);
|
||||||
void test_nghttp2_session_recv_unexpected_continuation(void);
|
void test_nghttp2_session_recv_unexpected_continuation(void);
|
||||||
void test_nghttp2_session_recv_settings_header_table_size(void);
|
void test_nghttp2_session_recv_settings_header_table_size(void);
|
||||||
|
@ -81,7 +80,6 @@ void test_nghttp2_submit_settings_update_local_window_size(void);
|
||||||
void test_nghttp2_submit_push_promise(void);
|
void test_nghttp2_submit_push_promise(void);
|
||||||
void test_nghttp2_submit_window_update(void);
|
void test_nghttp2_submit_window_update(void);
|
||||||
void test_nghttp2_submit_window_update_local_window_size(void);
|
void test_nghttp2_submit_window_update_local_window_size(void);
|
||||||
void test_nghttp2_submit_altsvc(void);
|
|
||||||
void test_nghttp2_submit_invalid_nv(void);
|
void test_nghttp2_submit_invalid_nv(void);
|
||||||
void test_nghttp2_session_open_stream(void);
|
void test_nghttp2_session_open_stream(void);
|
||||||
void test_nghttp2_session_open_stream_with_closed_stream_limit(void);
|
void test_nghttp2_session_open_stream_with_closed_stream_limit(void);
|
||||||
|
|
|
@ -45,8 +45,6 @@ int unpack_frame(nghttp2_frame *frame, const uint8_t *in, size_t len) {
|
||||||
const uint8_t *payload = in + NGHTTP2_FRAME_HDLEN;
|
const uint8_t *payload = in + NGHTTP2_FRAME_HDLEN;
|
||||||
size_t payloadlen = len - NGHTTP2_FRAME_HDLEN;
|
size_t payloadlen = len - NGHTTP2_FRAME_HDLEN;
|
||||||
size_t payloadoff;
|
size_t payloadoff;
|
||||||
uint8_t *gift_payload;
|
|
||||||
size_t gift_payloadlen;
|
|
||||||
|
|
||||||
nghttp2_frame_unpack_frame_hd(&frame->hd, in);
|
nghttp2_frame_unpack_frame_hd(&frame->hd, in);
|
||||||
switch (frame->hd.type) {
|
switch (frame->hd.type) {
|
||||||
|
@ -81,18 +79,6 @@ int unpack_frame(nghttp2_frame *frame, const uint8_t *in, size_t len) {
|
||||||
nghttp2_frame_unpack_window_update_payload(&frame->window_update, payload,
|
nghttp2_frame_unpack_window_update_payload(&frame->window_update, payload,
|
||||||
payloadlen);
|
payloadlen);
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_EXT_ALTSVC:
|
|
||||||
gift_payloadlen = payloadlen - NGHTTP2_ALTSVC_FIXED_PARTLEN;
|
|
||||||
gift_payload = malloc(gift_payloadlen);
|
|
||||||
|
|
||||||
memcpy(gift_payload, payload + NGHTTP2_ALTSVC_FIXED_PARTLEN,
|
|
||||||
gift_payloadlen);
|
|
||||||
|
|
||||||
payloadlen -= NGHTTP2_ALTSVC_FIXED_PARTLEN;
|
|
||||||
|
|
||||||
rv = nghttp2_frame_unpack_altsvc_payload(&frame->ext, payload, payloadlen,
|
|
||||||
gift_payload, gift_payloadlen);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
/* Must not be reachable */
|
/* Must not be reachable */
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
Loading…
Reference in New Issue