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_send.rst \
|
||||
nghttp2_session_recv.rst \
|
||||
nghttp2_session_change_stream_priority.rst \
|
||||
nghttp2_session_check_request_allowed.rst \
|
||||
nghttp2_session_check_server_session.rst \
|
||||
nghttp2_session_resume_data.rst \
|
||||
|
|
|
@ -2853,6 +2853,40 @@ NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session,
|
|||
int32_t stream_id,
|
||||
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
|
||||
*
|
||||
|
|
|
@ -42,3 +42,11 @@ int nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec) {
|
|||
return pri_spec->stream_id == 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>
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
|
|
@ -6771,3 +6771,24 @@ nghttp2_stream *nghttp2_session_get_root_stream(nghttp2_session *session) {
|
|||
int nghttp2_session_check_server_session(nghttp2_session *session) {
|
||||
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;
|
||||
}
|
||||
|
||||
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,
|
||||
uint8_t flags, int32_t stream_id,
|
||||
const nghttp2_priority_spec *pri_spec,
|
||||
|
@ -141,7 +133,7 @@ static int32_t submit_headers_shared_nva(nghttp2_session *session,
|
|||
|
||||
if (pri_spec) {
|
||||
copy_pri_spec = *pri_spec;
|
||||
adjust_priority_spec_weight(©_pri_spec);
|
||||
nghttp2_priority_spec_normalize_weight(©_pri_spec);
|
||||
} else {
|
||||
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;
|
||||
|
||||
adjust_priority_spec_weight(©_pri_spec);
|
||||
nghttp2_priority_spec_normalize_weight(©_pri_spec);
|
||||
|
||||
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",
|
||||
test_nghttp2_session_detach_item_from_closed_stream) ||
|
||||
!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",
|
||||
test_nghttp2_http_mandatory_headers) ||
|
||||
!CU_add_test(pSuite, "http_content_length",
|
||||
|
|
|
@ -8319,6 +8319,41 @@ void test_nghttp2_session_flooding(void) {
|
|||
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(
|
||||
nghttp2_session *session, nghttp2_hd_deflater *deflater, int32_t stream_id,
|
||||
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_detach_item_from_closed_stream(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_content_length(void);
|
||||
void test_nghttp2_http_content_length_mismatch(void);
|
||||
|
|
Loading…
Reference in New Issue