altsvc: Add error handling about origin and stream_id

This commit is contained in:
Tatsuhiro Tsujikawa 2016-03-31 23:58:26 +09:00
parent ecabef2dc7
commit 8b5a85ae1d
2 changed files with 50 additions and 2 deletions

View File

@ -4136,6 +4136,36 @@ typedef struct {
size_t field_value_len; size_t field_value_len;
} nghttp2_ext_altsvc; } nghttp2_ext_altsvc;
/**
* @function
*
* Submits ALTSVC frame.
*
* The |flags| is currently ignored and should be
* :enum:`NGHTTP2_FLAG_NONE`.
*
* The |origin| points to the origin this alternative service is
* associated with. The |origin_len| is the length of the origin. If
* |stream_id| is 0, the origin must be specified. If |stream_id| is
* not zero, the origin must be empty (in other words, |origin_len|
* must be 0).
*
* The ALTSVC frame is only usable from server side. If this function
* is invoked with client side session, this function returns
* :enum:`NGHTTP2_ERR_INVALID_STATE`.
*
* 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_INVALID_STATE`
* The function is called from client side session
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
* The sum of |origin_len| and |field_value_len| is larger than
* 16382; or |origin_len| is 0 while |stream_id| is 0; or
* |origin_len| is not 0 while |stream_id| is not 0.
*/
NGHTTP2_EXTERN int nghttp2_submit_altsvc(nghttp2_session *session, NGHTTP2_EXTERN int nghttp2_submit_altsvc(nghttp2_session *session,
uint8_t flags, int32_t stream_id, uint8_t flags, int32_t stream_id,
const uint8_t *origin, const uint8_t *origin,

View File

@ -425,10 +425,22 @@ int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags _U_,
mem = &session->mem; mem = &session->mem;
if (!session->server) {
return NGHTTP2_ERR_INVALID_STATE;
}
if (2 + origin_len + field_value_len > NGHTTP2_MAX_PAYLOADLEN) { if (2 + origin_len + field_value_len > NGHTTP2_MAX_PAYLOADLEN) {
return NGHTTP2_ERR_INVALID_ARGUMENT; return NGHTTP2_ERR_INVALID_ARGUMENT;
} }
if (stream_id == 0) {
if (origin_len == 0) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
} else if (origin_len != 0) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
buf = nghttp2_mem_malloc(mem, origin_len + field_value_len + 2); buf = nghttp2_mem_malloc(mem, origin_len + field_value_len + 2);
if (buf == NULL) { if (buf == NULL) {
return NGHTTP2_ERR_NOMEM; return NGHTTP2_ERR_NOMEM;
@ -437,11 +449,15 @@ int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags _U_,
p = buf; p = buf;
origin_copy = p; origin_copy = p;
p = nghttp2_cpymem(p, origin, origin_len); if (origin_len) {
p = nghttp2_cpymem(p, origin, origin_len);
}
*p++ = '\0'; *p++ = '\0';
field_value_copy = p; field_value_copy = p;
p = nghttp2_cpymem(p, field_value, field_value_len); if (field_value_len) {
p = nghttp2_cpymem(p, field_value, field_value_len);
}
*p++ = '\0'; *p++ = '\0';
item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
@ -470,6 +486,8 @@ int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags _U_,
if (rv != 0) { if (rv != 0) {
nghttp2_frame_altsvc_free(&frame->ext, mem); nghttp2_frame_altsvc_free(&frame->ext, mem);
nghttp2_mem_free(mem, item); nghttp2_mem_free(mem, item);
return rv;
} }
return 0; return 0;