Merge branch 'change-stream-priority'
This commit is contained in:
commit
2fee05242e
|
@ -105,6 +105,7 @@ APIDOCS= \
|
||||||
nghttp2_session_mem_recv.rst \
|
nghttp2_session_mem_recv.rst \
|
||||||
nghttp2_session_mem_send.rst \
|
nghttp2_session_mem_send.rst \
|
||||||
nghttp2_session_recv.rst \
|
nghttp2_session_recv.rst \
|
||||||
|
nghttp2_session_change_stream_priority.rst \
|
||||||
nghttp2_session_check_request_allowed.rst \
|
nghttp2_session_check_request_allowed.rst \
|
||||||
nghttp2_session_check_server_session.rst \
|
nghttp2_session_check_server_session.rst \
|
||||||
nghttp2_session_resume_data.rst \
|
nghttp2_session_resume_data.rst \
|
||||||
|
|
|
@ -2853,6 +2853,40 @@ NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session,
|
||||||
int32_t stream_id,
|
int32_t stream_id,
|
||||||
size_t size);
|
size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
*
|
||||||
|
* Changes priority of existing stream denoted by |stream_id|. The
|
||||||
|
* new priority specification is |pri_spec|.
|
||||||
|
*
|
||||||
|
* The priority is changed silently and instantly, and no PRIORITY
|
||||||
|
* frame will be sent to notify the peer of this change. This
|
||||||
|
* function may be useful for server to change the priority of pushed
|
||||||
|
* stream.
|
||||||
|
*
|
||||||
|
* If |session| is initialized as server, and ``pri_spec->stream_id``
|
||||||
|
* points to the idle stream, the idle stream is created if it does
|
||||||
|
* not exist. The created idle stream will depend on root stream
|
||||||
|
* (stream 0) with weight 16.
|
||||||
|
*
|
||||||
|
* If stream denoted by ``pri_spec->stream_id`` is not found, we use
|
||||||
|
* default priority instead of given |pri_spec|. That is make stream
|
||||||
|
* depend on root stream with weight 16.
|
||||||
|
*
|
||||||
|
* 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_ARGUMENT`
|
||||||
|
* Attempted to depend on itself; no stream exist for the given
|
||||||
|
* |stream_id|.
|
||||||
|
*/
|
||||||
|
NGHTTP2_EXTERN int
|
||||||
|
nghttp2_session_change_stream_priority(nghttp2_session *session,
|
||||||
|
int32_t stream_id,
|
||||||
|
const nghttp2_priority_spec *pri_spec);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
|
|
|
@ -42,3 +42,11 @@ int nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec) {
|
||||||
return pri_spec->stream_id == 0 &&
|
return pri_spec->stream_id == 0 &&
|
||||||
pri_spec->weight == NGHTTP2_DEFAULT_WEIGHT && pri_spec->exclusive == 0;
|
pri_spec->weight == NGHTTP2_DEFAULT_WEIGHT && pri_spec->exclusive == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec) {
|
||||||
|
if (pri_spec->weight < NGHTTP2_MIN_WEIGHT) {
|
||||||
|
pri_spec->weight = NGHTTP2_MIN_WEIGHT;
|
||||||
|
} else if (pri_spec->weight > NGHTTP2_MAX_WEIGHT) {
|
||||||
|
pri_spec->weight = NGHTTP2_MAX_WEIGHT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -31,4 +31,12 @@
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function normalizes pri_spec->weight if it is out of range.
|
||||||
|
* If pri_spec->weight is less than NGHTTP2_MIN_WEIGHT, it is set to
|
||||||
|
* NGHTTP2_MIN_WEIGHT. If pri_spec->weight is larger than
|
||||||
|
* NGHTTP2_MAX_WEIGHT, it is set to NGHTTP2_MAX_WEIGHT.
|
||||||
|
*/
|
||||||
|
void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec);
|
||||||
|
|
||||||
#endif /* NGHTTP2_PRIORITY_SPEC_H */
|
#endif /* NGHTTP2_PRIORITY_SPEC_H */
|
||||||
|
|
|
@ -6771,3 +6771,24 @@ nghttp2_stream *nghttp2_session_get_root_stream(nghttp2_session *session) {
|
||||||
int nghttp2_session_check_server_session(nghttp2_session *session) {
|
int nghttp2_session_check_server_session(nghttp2_session *session) {
|
||||||
return session->server;
|
return session->server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nghttp2_session_change_stream_priority(
|
||||||
|
nghttp2_session *session, int32_t stream_id,
|
||||||
|
const nghttp2_priority_spec *pri_spec) {
|
||||||
|
nghttp2_stream *stream;
|
||||||
|
nghttp2_priority_spec pri_spec_copy;
|
||||||
|
|
||||||
|
if (stream_id == pri_spec->stream_id) {
|
||||||
|
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream = nghttp2_session_get_stream_raw(session, stream_id);
|
||||||
|
if (!stream) {
|
||||||
|
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
pri_spec_copy = *pri_spec;
|
||||||
|
nghttp2_priority_spec_normalize_weight(&pri_spec_copy);
|
||||||
|
|
||||||
|
return nghttp2_session_reprioritize_stream(session, stream, &pri_spec_copy);
|
||||||
|
}
|
||||||
|
|
|
@ -117,14 +117,6 @@ fail2:
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjust_priority_spec_weight(nghttp2_priority_spec *pri_spec) {
|
|
||||||
if (pri_spec->weight < NGHTTP2_MIN_WEIGHT) {
|
|
||||||
pri_spec->weight = NGHTTP2_MIN_WEIGHT;
|
|
||||||
} else if (pri_spec->weight > NGHTTP2_MAX_WEIGHT) {
|
|
||||||
pri_spec->weight = NGHTTP2_MAX_WEIGHT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t submit_headers_shared_nva(nghttp2_session *session,
|
static int32_t submit_headers_shared_nva(nghttp2_session *session,
|
||||||
uint8_t flags, int32_t stream_id,
|
uint8_t flags, int32_t stream_id,
|
||||||
const nghttp2_priority_spec *pri_spec,
|
const nghttp2_priority_spec *pri_spec,
|
||||||
|
@ -141,7 +133,7 @@ static int32_t submit_headers_shared_nva(nghttp2_session *session,
|
||||||
|
|
||||||
if (pri_spec) {
|
if (pri_spec) {
|
||||||
copy_pri_spec = *pri_spec;
|
copy_pri_spec = *pri_spec;
|
||||||
adjust_priority_spec_weight(©_pri_spec);
|
nghttp2_priority_spec_normalize_weight(©_pri_spec);
|
||||||
} else {
|
} else {
|
||||||
nghttp2_priority_spec_default_init(©_pri_spec);
|
nghttp2_priority_spec_default_init(©_pri_spec);
|
||||||
}
|
}
|
||||||
|
@ -206,7 +198,7 @@ int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags _U_,
|
||||||
|
|
||||||
copy_pri_spec = *pri_spec;
|
copy_pri_spec = *pri_spec;
|
||||||
|
|
||||||
adjust_priority_spec_weight(©_pri_spec);
|
nghttp2_priority_spec_normalize_weight(©_pri_spec);
|
||||||
|
|
||||||
item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
|
item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
|
||||||
|
|
||||||
|
|
|
@ -282,6 +282,8 @@ int main(int argc _U_, char *argv[] _U_) {
|
||||||
!CU_add_test(pSuite, "session_detach_item_from_closed_stream",
|
!CU_add_test(pSuite, "session_detach_item_from_closed_stream",
|
||||||
test_nghttp2_session_detach_item_from_closed_stream) ||
|
test_nghttp2_session_detach_item_from_closed_stream) ||
|
||||||
!CU_add_test(pSuite, "session_flooding", test_nghttp2_session_flooding) ||
|
!CU_add_test(pSuite, "session_flooding", test_nghttp2_session_flooding) ||
|
||||||
|
!CU_add_test(pSuite, "session_change_stream_priority",
|
||||||
|
test_nghttp2_session_change_stream_priority) ||
|
||||||
!CU_add_test(pSuite, "http_mandatory_headers",
|
!CU_add_test(pSuite, "http_mandatory_headers",
|
||||||
test_nghttp2_http_mandatory_headers) ||
|
test_nghttp2_http_mandatory_headers) ||
|
||||||
!CU_add_test(pSuite, "http_content_length",
|
!CU_add_test(pSuite, "http_content_length",
|
||||||
|
|
|
@ -8319,6 +8319,41 @@ void test_nghttp2_session_flooding(void) {
|
||||||
nghttp2_bufs_free(&bufs);
|
nghttp2_bufs_free(&bufs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_nghttp2_session_change_stream_priority(void) {
|
||||||
|
nghttp2_session *session;
|
||||||
|
nghttp2_session_callbacks callbacks;
|
||||||
|
nghttp2_stream *stream1, *stream2, *stream3;
|
||||||
|
nghttp2_priority_spec pri_spec;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
memset(&callbacks, 0, sizeof(callbacks));
|
||||||
|
|
||||||
|
nghttp2_session_server_new(&session, &callbacks, NULL);
|
||||||
|
|
||||||
|
stream1 = open_stream(session, 1);
|
||||||
|
stream3 = open_stream_with_dep_weight(session, 3, 199, stream1);
|
||||||
|
stream2 = open_stream_with_dep_weight(session, 2, 101, stream3);
|
||||||
|
|
||||||
|
nghttp2_priority_spec_init(&pri_spec, 1, 256, 0);
|
||||||
|
|
||||||
|
rv = nghttp2_session_change_stream_priority(session, 2, &pri_spec);
|
||||||
|
|
||||||
|
CU_ASSERT(0 == rv);
|
||||||
|
|
||||||
|
CU_ASSERT(stream1 == stream2->dep_prev);
|
||||||
|
CU_ASSERT(256 == stream2->weight);
|
||||||
|
|
||||||
|
/* Cannot change stream which does not exist */
|
||||||
|
rv = nghttp2_session_change_stream_priority(session, 5, &pri_spec);
|
||||||
|
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT == rv);
|
||||||
|
|
||||||
|
/* It is an error to depend on itself */
|
||||||
|
rv = nghttp2_session_change_stream_priority(session, 1, &pri_spec);
|
||||||
|
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT == rv);
|
||||||
|
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
}
|
||||||
|
|
||||||
static void check_nghttp2_http_recv_headers_fail(
|
static void check_nghttp2_http_recv_headers_fail(
|
||||||
nghttp2_session *session, nghttp2_hd_deflater *deflater, int32_t stream_id,
|
nghttp2_session *session, nghttp2_hd_deflater *deflater, int32_t stream_id,
|
||||||
int stream_state, const nghttp2_nv *nva, size_t nvlen) {
|
int stream_state, const nghttp2_nv *nva, size_t nvlen) {
|
||||||
|
|
|
@ -133,6 +133,7 @@ void test_nghttp2_session_on_begin_headers_temporal_failure(void);
|
||||||
void test_nghttp2_session_defer_then_close(void);
|
void test_nghttp2_session_defer_then_close(void);
|
||||||
void test_nghttp2_session_detach_item_from_closed_stream(void);
|
void test_nghttp2_session_detach_item_from_closed_stream(void);
|
||||||
void test_nghttp2_session_flooding(void);
|
void test_nghttp2_session_flooding(void);
|
||||||
|
void test_nghttp2_session_change_stream_priority(void);
|
||||||
void test_nghttp2_http_mandatory_headers(void);
|
void test_nghttp2_http_mandatory_headers(void);
|
||||||
void test_nghttp2_http_content_length(void);
|
void test_nghttp2_http_content_length(void);
|
||||||
void test_nghttp2_http_content_length_mismatch(void);
|
void test_nghttp2_http_content_length_mismatch(void);
|
||||||
|
|
Loading…
Reference in New Issue