Add API to change stream priority without sending PRIORITY frame

The added API is nghttp2_session_change_stream_priority().  This
provides the same functionality to re-prioritize stream when PRIORITY
frame.  is received, but we do it without PRIORITY frame.  This could
be useful for server to change pushed stream's priority silently.
This commit is contained in:
Tatsuhiro Tsujikawa 2015-11-21 18:22:28 +09:00
parent 72f2c4b272
commit aa317c89ea
6 changed files with 74 additions and 10 deletions

View File

@ -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 \

View File

@ -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
*

View File

@ -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;
}
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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(&copy_pri_spec);
nghttp2_priority_spec_normalize_weight(&copy_pri_spec);
} else {
nghttp2_priority_spec_default_init(&copy_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(&copy_pri_spec);
nghttp2_priority_spec_normalize_weight(&copy_pri_spec);
item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));