Remove RFC 7540 priorities

Summary of the behavioral changes in public API functions:

- nghttp2_session_change_stream_priority: This function is noop.  It
  always returns 0.
- nghttp2_session_create_idle_stream: This function is noop.  It
  always returns 0.
- nghttp2_submit_request: pri_spec is ignored.
- nghttp2_submit_request2: pri_spec is ignored.
- nghttp2_submit_headers: pri_spec is ignored.
- nghttp2_submit_priority: This function is noop.  It always returns
  0.
- nghttp2_stream_get_parent: This function always returns NULL.
- nghttp2_stream_get_next_sibling: This function always returns NULL.
- nghttp2_stream_get_previous_sibling: This function always returns
  NULL.
- nghttp2_stream_get_first_child: This function always returns NULL.
- nghttp2_stream_get_weight: This function always returns
  NGHTTP2_DEFAULT_WEIGHT.
- nghttp2_stream_get_sum_dependency_weight: This function always
  returns 0.
This commit is contained in:
Tatsuhiro Tsujikawa
2024-03-25 18:46:03 +09:00
parent 8c83772f6c
commit 3dd61f8ec3
11 changed files with 163 additions and 4747 deletions

View File

@@ -4179,39 +4179,9 @@ NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session,
*
* Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of
* 2024, this function will always return 0 without doing anything.
* prioritization scheme.
*
* 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.
*
* Otherwise, 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.
*
* If
* :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
* of value of 1 is submitted via `nghttp2_submit_settings()`, this
* function does nothing and returns 0.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
* :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* Attempted to depend on itself; or no stream exist for the given
* |stream_id|; or |stream_id| is 0
* This function is noop. It always returns 0.
*/
NGHTTP2_EXTERN int
nghttp2_session_change_stream_priority(nghttp2_session *session,
@@ -4225,51 +4195,9 @@ nghttp2_session_change_stream_priority(nghttp2_session *session,
*
* Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of
* 2024, this function will always return 0 without doing anything.
* prioritization scheme.
*
* Creates idle stream with the given |stream_id|, and priority
* |pri_spec|.
*
* The stream creation is done without sending PRIORITY frame, which
* means that peer does not know about the existence of this idle
* stream in the local endpoint.
*
* RFC 7540 does not disallow the use of creation of idle stream with
* odd or even stream ID regardless of client or server. So this
* function can create odd or even stream ID regardless of client or
* server. But probably it is a bit safer to use the stream ID the
* local endpoint can initiate (in other words, use odd stream ID for
* client, and even stream ID for server), to avoid potential
* collision from peer's instruction. Also we can use
* `nghttp2_session_set_next_stream_id()` to avoid to open created
* idle streams accidentally if we follow this recommendation.
*
* 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.
*
* Otherwise, 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.
*
* If
* :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
* of value of 1 is submitted via `nghttp2_submit_settings()`, this
* function does nothing and returns 0.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
* :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* Attempted to depend on itself; or stream denoted by |stream_id|
* already exists; or |stream_id| cannot be used to create idle
* stream (in other words, local endpoint has already opened
* stream ID greater than or equal to the given stream ID; or
* |stream_id| is 0
* This function is noop. It always returns 0.
*/
NGHTTP2_EXTERN int
nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id,
@@ -4505,23 +4433,7 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
*
* Submits HEADERS frame and optionally one or more DATA frames.
*
* The |pri_spec| is a deprecated priority specification of this
* request. ``NULL`` means the default priority (see
* `nghttp2_priority_spec_default_init()`). To specify the priority,
* use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``,
* this function will copy its data members.
*
* The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
* :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
* is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
* :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
* :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
* :macro:`NGHTTP2_MAX_WEIGHT`.
*
* If
* :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
* of value of 1 is received by a remote endpoint, |pri_spec| is
* ignored, and treated as if ``NULL`` is specified.
* The |pri_spec| is ignored.
*
* The |nva| is an array of name/value pair :type:`nghttp2_nv` with
* |nvlen| elements. The application is responsible to include
@@ -4564,9 +4476,6 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
* :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
* No stream ID is available because maximum stream ID was
* reached.
* :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* Trying to depend on itself (new stream ID equals
* ``pri_spec->stream_id``).
* :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
* The |session| is server session.
*
@@ -4594,25 +4503,7 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request(
*
* Submits HEADERS frame and optionally one or more DATA frames.
*
* The |pri_spec| is a deprecated priority specification of this
* request. ``NULL`` means the default priority (see
* `nghttp2_priority_spec_default_init()`). To specify the priority,
* use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``,
* this function will copy its data members. In the future release
* after the end of 2024, this function will ignore |pri_spec| and
* behave as if ``NULL`` is given.
*
* The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
* :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
* is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
* :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
* :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
* :macro:`NGHTTP2_MAX_WEIGHT`.
*
* If
* :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
* of value of 1 is received by a remote endpoint, |pri_spec| is
* ignored, and treated as if ``NULL`` is specified.
* The |pri_spec| is ignored.
*
* The |nva| is an array of name/value pair :type:`nghttp2_nv` with
* |nvlen| elements. The application is responsible to include
@@ -4655,9 +4546,6 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request(
* :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
* No stream ID is available because maximum stream ID was
* reached.
* :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* Trying to depend on itself (new stream ID equals
* ``pri_spec->stream_id``).
* :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
* The |session| is server session.
*
@@ -4899,24 +4787,7 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
* assigned stream ID will be returned. Otherwise, specify stream ID
* in |stream_id|.
*
* The |pri_spec| is a deprecated priority specification of this
* request. ``NULL`` means the default priority (see
* `nghttp2_priority_spec_default_init()`). To specify the priority,
* use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``,
* this function will copy its data members. In the future release
* after the end of 2024, this function will ignore |pri_spec| and
* behave as if ``NULL`` is given.
*
* The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
* :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
* is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
* :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
* :macro:`NGHTTP2_MAX_WEIGHT`, it becomes :macro:`NGHTTP2_MAX_WEIGHT`.
*
* If
* :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
* of value of 1 is received by a remote endpoint, |pri_spec| is
* ignored, and treated as if ``NULL`` is specified.
* The |pri_spec| is ignored.
*
* The |nva| is an array of name/value pair :type:`nghttp2_nv` with
* |nvlen| elements. The application is responsible to include
@@ -4956,8 +4827,7 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
* No stream ID is available because maximum stream ID was
* reached.
* :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0; or trying to depend on itself (stream ID
* equals ``pri_spec->stream_id``).
* The |stream_id| is 0.
* :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
* DATA or HEADERS has been already submitted and not fully
* processed yet. This happens if stream denoted by |stream_id|
@@ -5083,40 +4953,9 @@ NGHTTP2_EXTERN int nghttp2_submit_data2(nghttp2_session *session, uint8_t flags,
*
* Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of
* 2024, this function will always return 0 without doing anything.
* prioritization scheme.
*
* Submits PRIORITY frame to change the priority of stream |stream_id|
* to the priority specification |pri_spec|.
*
* The |flags| is currently ignored and should be
* :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
*
* The |pri_spec| is a deprecated priority specification of this
* request. ``NULL`` is not allowed for this function. To specify the
* priority, use `nghttp2_priority_spec_init()`. This function will
* copy its data members.
*
* The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
* :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
* is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
* :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
* :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
* :macro:`NGHTTP2_MAX_WEIGHT`.
*
* If
* :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
* of value of 1 is received by a remote endpoint, this function does
* nothing and returns 0.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
* :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0; or the |pri_spec| is NULL; or trying to
* depend on itself.
* This function is noop. It always returns 0.
*/
NGHTTP2_EXTERN int
nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
@@ -6885,11 +6724,9 @@ nghttp2_session_get_root_stream(nghttp2_session *session);
*
* Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of
* 2024, this function will always return NULL.
* prioritization scheme.
*
* Returns the parent stream of |stream| in dependency tree. Returns
* NULL if there is no such stream.
* This function always returns NULL.
*/
NGHTTP2_EXTERN nghttp2_stream *
nghttp2_stream_get_parent(nghttp2_stream *stream);
@@ -6903,11 +6740,9 @@ NGHTTP2_EXTERN int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream);
*
* Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of
* 2024, this function will always return NULL.
* prioritization scheme.
*
* Returns the next sibling stream of |stream| in dependency tree.
* Returns NULL if there is no such stream.
* This function always returns NULL.
*/
NGHTTP2_EXTERN nghttp2_stream *
nghttp2_stream_get_next_sibling(nghttp2_stream *stream);
@@ -6919,11 +6754,9 @@ nghttp2_stream_get_next_sibling(nghttp2_stream *stream);
*
* Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of
* 2024, this function will always return NULL.
* prioritization scheme.
*
* Returns the previous sibling stream of |stream| in dependency tree.
* Returns NULL if there is no such stream.
* This function always returns NULL.
*/
NGHTTP2_EXTERN nghttp2_stream *
nghttp2_stream_get_previous_sibling(nghttp2_stream *stream);
@@ -6935,11 +6768,9 @@ nghttp2_stream_get_previous_sibling(nghttp2_stream *stream);
*
* Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of
* 2024, this function will always return NULL.
* prioritization scheme.
*
* Returns the first child stream of |stream| in dependency tree.
* Returns NULL if there is no such stream.
* This function always returns NULL.
*/
NGHTTP2_EXTERN nghttp2_stream *
nghttp2_stream_get_first_child(nghttp2_stream *stream);
@@ -6951,11 +6782,9 @@ nghttp2_stream_get_first_child(nghttp2_stream *stream);
*
* Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of
* 2024, this function will always return
* :macro:`NGHTTP2_DEFAULT_WEIGHT`.
* prioritization scheme.
*
* Returns dependency weight to the parent stream of |stream|.
* This function always returns :macro:`NGHTTP2_DEFAULT_WEIGHT`.
*/
NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream);
@@ -6966,10 +6795,9 @@ NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream);
*
* Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of
* 2024, this function will always return 0.
* prioritization scheme.
*
* Returns the sum of the weight for |stream|'s children.
* This function always returns 0.
*/
NGHTTP2_EXTERN int32_t
nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream);

View File

@@ -207,7 +207,6 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
if (!trailer &&
/* Do not parse the header field in PUSH_PROMISE. */
(stream->stream_id & 1) &&
(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) &&
!(stream->http_flags & NGHTTP2_HTTP_FLAG_BAD_PRIORITY)) {
nghttp2_extpri_from_uint8(&extpri, stream->http_extpri);
if (nghttp2_http_parse_priority(&extpri, nv->value->base,

File diff suppressed because it is too large Load Diff

View File

@@ -45,6 +45,8 @@
preface handling. */
extern int nghttp2_enable_strict_preface;
extern nghttp2_stream root;
/*
* Option flags.
*/
@@ -89,10 +91,6 @@ typedef struct {
/* The default maximum number of incoming reserved streams */
#define NGHTTP2_MAX_INCOMING_RESERVED_STREAMS 200
/* Even if we have less SETTINGS_MAX_CONCURRENT_STREAMS than this
number, we keep NGHTTP2_MIN_IDLE_STREAMS streams in idle state */
#define NGHTTP2_MIN_IDLE_STREAMS 16
/* The maximum number of items in outbound queue, which is considered
as flooding caused by peer. All frames are not considered here.
We only consider PING + ACK and SETTINGS + ACK. This is because
@@ -205,8 +203,6 @@ typedef struct nghttp2_inflight_settings nghttp2_inflight_settings;
struct nghttp2_session {
nghttp2_map /* <nghttp2_stream*> */ streams;
/* root of dependency tree*/
nghttp2_stream root;
/* Queue for outbound urgent frames (PING and SETTINGS) */
nghttp2_outbound_queue ob_urgent;
/* Queue for non-DATA frames */
@@ -229,20 +225,6 @@ struct nghttp2_session {
/* Memory allocator */
nghttp2_mem mem;
void *user_data;
/* Points to the latest incoming closed stream. NULL if there is no
closed stream. Only used when session is initialized as
server. */
nghttp2_stream *closed_stream_head;
/* Points to the oldest incoming closed stream. NULL if there is no
closed stream. Only used when session is initialized as
server. */
nghttp2_stream *closed_stream_tail;
/* Points to the latest idle stream. NULL if there is no idle
stream. Only used when session is initialized as server .*/
nghttp2_stream *idle_stream_head;
/* Points to the oldest idle stream. NULL if there is no idle
stream. Only used when session is initialized as erver. */
nghttp2_stream *idle_stream_tail;
/* Queue of In-flight SETTINGS values. SETTINGS bearing ACK is not
considered as in-flight. */
nghttp2_inflight_settings *inflight_settings_head;
@@ -276,10 +258,9 @@ struct nghttp2_session {
|closed_stream_head|. The current implementation only keeps
incoming streams and session is initialized as server. */
size_t num_closed_streams;
/* The number of idle streams kept in |streams| hash. The idle
streams can be accessed through doubly linked list
|idle_stream_head|. The current implementation only keeps idle
streams if session is initialized as server. */
/* The number of idle streams kept in |streams| hash. The current
implementation only keeps idle streams if session is initialized
as server. */
size_t num_idle_streams;
/* The number of bytes allocated for nvbuf */
size_t nvbuflen;
@@ -527,15 +508,9 @@ int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags,
*
* This function returns a pointer to created new stream object, or
* NULL.
*
* This function adjusts neither the number of closed streams or idle
* streams. The caller should manually call
* nghttp2_session_adjust_closed_stream() or
* nghttp2_session_adjust_idle_stream() respectively.
*/
nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
int32_t stream_id, uint8_t flags,
nghttp2_priority_spec *pri_spec,
nghttp2_stream_state initial_state,
void *stream_user_data);
@@ -544,11 +519,6 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
* is indicated by the |error_code|. When closing the stream,
* on_stream_close_callback will be called.
*
* If the session is initialized as server and |stream| is incoming
* stream, stream is just marked closed and this function calls
* nghttp2_session_keep_closed_stream() with |stream|. Otherwise,
* |stream| will be deleted from memory.
*
* This function returns 0 if it succeeds, or one the following
* negative error codes:
*
@@ -565,63 +535,9 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
/*
* Deletes |stream| from memory. After this function returns, stream
* cannot be accessed.
*
* This function returns 0 if it succeeds, or one the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_session_destroy_stream(nghttp2_session *session,
nghttp2_stream *stream);
/*
* Tries to keep incoming closed stream |stream|. Due to the
* limitation of maximum number of streams in memory, |stream| is not
* closed and just deleted from memory (see
* nghttp2_session_destroy_stream).
*/
void nghttp2_session_keep_closed_stream(nghttp2_session *session,
nghttp2_stream *stream);
/*
* Appends |stream| to linked list |session->idle_stream_head|. We
* apply fixed limit for list size. To fit into that limit, one or
* more oldest streams are removed from list as necessary.
*/
void nghttp2_session_keep_idle_stream(nghttp2_session *session,
nghttp2_stream *stream);
/*
* Detaches |stream| from idle streams linked list.
*/
void nghttp2_session_detach_idle_stream(nghttp2_session *session,
nghttp2_stream *stream);
/*
* Deletes closed stream to ensure that number of incoming streams
* including active and closed is in the maximum number of allowed
* stream.
*
* This function returns 0 if it succeeds, or one the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_session_adjust_closed_stream(nghttp2_session *session);
/*
* Deletes idle stream to ensure that number of idle streams is in
* certain limit.
*
* This function returns 0 if it succeeds, or one the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_session_adjust_idle_stream(nghttp2_session *session);
void nghttp2_session_destroy_stream(nghttp2_session *session,
nghttp2_stream *stream);
/*
* If further receptions and transmissions over the stream |stream_id|
@@ -915,24 +831,6 @@ int nghttp2_session_update_local_settings(nghttp2_session *session,
nghttp2_settings_entry *iv,
size_t niv);
/*
* Re-prioritize |stream|. The new priority specification is
* |pri_spec|. Caller must ensure that stream->hd.stream_id !=
* pri_spec->stream_id.
*
* This function does not adjust the number of idle streams. The
* caller should call nghttp2_session_adjust_idle_stream() later.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_session_reprioritize_stream(nghttp2_session *session,
nghttp2_stream *stream,
const nghttp2_priority_spec *pri_spec);
/*
* Terminates current |session| with the |error_code|. The |reason|
* is NULL-terminated debug string.

View File

@@ -25,45 +25,17 @@
#include "nghttp2_stream.h"
#include <assert.h>
#include <stdio.h>
#include "nghttp2_session.h"
#include "nghttp2_helper.h"
#include "nghttp2_debug.h"
#include "nghttp2_frame.h"
/* Maximum distance between any two stream's cycle in the same
priority queue. Imagine stream A's cycle is A, and stream B's
cycle is B, and A < B. The cycle is unsigned 32 bit integer, it
may get overflow. Because of how we calculate the next cycle
value, if B - A is less than or equals to
NGHTTP2_MAX_CYCLE_DISTANCE, A and B are in the same scale, in other
words, B is really greater than or equal to A. Otherwise, A is a
result of overflow, and it is actually A > B if we consider that
fact. */
#define NGHTTP2_MAX_CYCLE_DISTANCE \
((uint64_t)NGHTTP2_MAX_FRAME_SIZE_MAX * 256 + 255)
static int stream_less(const void *lhsx, const void *rhsx) {
const nghttp2_stream *lhs, *rhs;
lhs = nghttp2_struct_of(lhsx, nghttp2_stream, pq_entry);
rhs = nghttp2_struct_of(rhsx, nghttp2_stream, pq_entry);
if (lhs->cycle == rhs->cycle) {
return lhs->seq < rhs->seq;
}
return rhs->cycle - lhs->cycle <= NGHTTP2_MAX_CYCLE_DISTANCE;
}
void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
uint8_t flags, nghttp2_stream_state initial_state,
int32_t weight, int32_t remote_initial_window_size,
int32_t remote_initial_window_size,
int32_t local_initial_window_size,
void *stream_user_data, nghttp2_mem *mem) {
nghttp2_pq_init(&stream->obq, stream_less, mem);
void *stream_user_data) {
stream->stream_id = stream_id;
stream->flags = flags;
stream->state = initial_state;
@@ -77,428 +49,36 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
stream->recv_reduction = 0;
stream->window_update_queued = 0;
stream->dep_prev = NULL;
stream->dep_next = NULL;
stream->sib_prev = NULL;
stream->sib_next = NULL;
stream->closed_prev = NULL;
stream->closed_next = NULL;
stream->weight = weight;
stream->sum_dep_weight = 0;
stream->http_flags = NGHTTP2_HTTP_FLAG_NONE;
stream->content_length = -1;
stream->recv_content_length = 0;
stream->status_code = -1;
stream->queued = 0;
stream->descendant_last_cycle = 0;
stream->cycle = 0;
stream->pending_penalty = 0;
stream->descendant_next_seq = 0;
stream->seq = 0;
stream->last_writelen = 0;
stream->extpri = stream->http_extpri = NGHTTP2_EXTPRI_DEFAULT_URGENCY;
}
void nghttp2_stream_free(nghttp2_stream *stream) {
nghttp2_pq_free(&stream->obq);
/* We don't free stream->item. If it is assigned to aob, then
active_outbound_item_reset() will delete it. Otherwise,
nghttp2_stream_close() or session_del() will delete it. */
}
void nghttp2_stream_free(nghttp2_stream *stream) { (void)stream; }
void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag) {
stream->shut_flags = (uint8_t)(stream->shut_flags | flag);
}
/*
* Returns nonzero if |stream| is active. This function does not take
* into account its descendants.
*/
static int stream_active(nghttp2_stream *stream) {
return stream->item &&
(stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0;
}
/*
* Returns nonzero if |stream| or one of its descendants is active
*/
static int stream_subtree_active(nghttp2_stream *stream) {
return stream_active(stream) || !nghttp2_pq_empty(&stream->obq);
}
/*
* Returns next cycle for |stream|.
*/
static void stream_next_cycle(nghttp2_stream *stream, uint64_t last_cycle) {
uint64_t penalty;
penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT +
stream->pending_penalty;
stream->cycle = last_cycle + penalty / (uint32_t)stream->weight;
stream->pending_penalty = (uint32_t)(penalty % (uint32_t)stream->weight);
}
static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
int rv;
for (; dep_stream && !stream->queued;
stream = dep_stream, dep_stream = dep_stream->dep_prev) {
stream_next_cycle(stream, dep_stream->descendant_last_cycle);
stream->seq = dep_stream->descendant_next_seq++;
DEBUGF("stream: stream=%d obq push cycle=%lu\n", stream->stream_id,
stream->cycle);
DEBUGF("stream: push stream %d to stream %d\n", stream->stream_id,
dep_stream->stream_id);
rv = nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
if (rv != 0) {
return rv;
}
stream->queued = 1;
}
return 0;
}
/*
* Removes |stream| from parent's obq. If removal of |stream| makes
* parent's obq empty, and parent is not active, then parent is also
* removed. This process is repeated recursively.
*/
static void stream_obq_remove(nghttp2_stream *stream) {
nghttp2_stream *dep_stream;
dep_stream = stream->dep_prev;
if (!stream->queued) {
return;
}
for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) {
DEBUGF("stream: remove stream %d from stream %d\n", stream->stream_id,
dep_stream->stream_id);
nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
assert(stream->queued);
stream->queued = 0;
stream->cycle = 0;
stream->pending_penalty = 0;
stream->descendant_last_cycle = 0;
stream->last_writelen = 0;
if (stream_subtree_active(dep_stream)) {
return;
}
}
}
/*
* Moves |stream| from |src|'s obq to |dest|'s obq. Removal from
* |src|'s obq is just done calling nghttp2_pq_remove(), so it does
* not recursively remove |src| and ancestors, like
* stream_obq_remove().
*/
static int stream_obq_move(nghttp2_stream *dest, nghttp2_stream *src,
nghttp2_stream *stream) {
if (!stream->queued) {
return 0;
}
DEBUGF("stream: remove stream %d from stream %d (move)\n", stream->stream_id,
src->stream_id);
nghttp2_pq_remove(&src->obq, &stream->pq_entry);
stream->queued = 0;
return stream_obq_push(dest, stream);
}
void nghttp2_stream_reschedule(nghttp2_stream *stream) {
nghttp2_stream *dep_stream;
assert(stream->queued);
dep_stream = stream->dep_prev;
for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) {
nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
stream_next_cycle(stream, dep_stream->descendant_last_cycle);
stream->seq = dep_stream->descendant_next_seq++;
nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id,
stream->cycle);
dep_stream->last_writelen = stream->last_writelen;
}
}
void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
nghttp2_stream *dep_stream;
uint64_t last_cycle;
int32_t old_weight;
uint64_t wlen_penalty;
if (stream->weight == weight) {
return;
}
old_weight = stream->weight;
stream->weight = weight;
dep_stream = stream->dep_prev;
if (!dep_stream) {
return;
}
dep_stream->sum_dep_weight += weight - old_weight;
if (!stream->queued) {
return;
}
nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
wlen_penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT;
/* Compute old stream->pending_penalty we used to calculate
stream->cycle */
stream->pending_penalty =
(uint32_t)((stream->pending_penalty + (uint32_t)old_weight -
(wlen_penalty % (uint32_t)old_weight)) %
(uint32_t)old_weight);
last_cycle = stream->cycle -
(wlen_penalty + stream->pending_penalty) / (uint32_t)old_weight;
/* Now we have old stream->pending_penalty and new stream->weight in
place */
stream_next_cycle(stream, last_cycle);
if (dep_stream->descendant_last_cycle - stream->cycle <=
NGHTTP2_MAX_CYCLE_DISTANCE) {
stream->cycle = dep_stream->descendant_last_cycle;
}
/* Continue to use same stream->seq */
nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id,
stream->cycle);
}
static nghttp2_stream *stream_last_sib(nghttp2_stream *stream) {
for (; stream->sib_next; stream = stream->sib_next)
;
return stream;
}
int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream,
int32_t weight) {
weight = stream->weight * weight / stream->sum_dep_weight;
return nghttp2_max_int32(1, weight);
}
#ifdef STREAM_DEP_DEBUG
static void ensure_inactive(nghttp2_stream *stream) {
nghttp2_stream *si;
if (stream->queued) {
fprintf(stderr, "stream(%p)=%d, stream->queued = 1; want 0\n", stream,
stream->stream_id);
assert(0);
}
if (stream_active(stream)) {
fprintf(stderr, "stream(%p)=%d, stream_active(stream) = 1; want 0\n",
stream, stream->stream_id);
assert(0);
}
if (!nghttp2_pq_empty(&stream->obq)) {
fprintf(stderr, "stream(%p)=%d, nghttp2_pq_size() = %zu; want 0\n", stream,
stream->stream_id, nghttp2_pq_size(&stream->obq));
assert(0);
}
for (si = stream->dep_next; si; si = si->sib_next) {
ensure_inactive(si);
}
}
static void check_queued(nghttp2_stream *stream) {
nghttp2_stream *si;
int queued;
if (stream->queued) {
if (!stream_subtree_active(stream)) {
fprintf(stderr,
"stream(%p)=%d, stream->queued == 1, but "
"stream_active() == %d and nghttp2_pq_size(&stream->obq) = %zu\n",
stream, stream->stream_id, stream_active(stream),
nghttp2_pq_size(&stream->obq));
assert(0);
}
if (!stream_active(stream)) {
queued = 0;
for (si = stream->dep_next; si; si = si->sib_next) {
if (si->queued) {
++queued;
}
}
if (queued == 0) {
fprintf(stderr,
"stream(%p)=%d, stream->queued == 1, and "
"!stream_active(), but no descendants is queued\n",
stream, stream->stream_id);
assert(0);
}
}
for (si = stream->dep_next; si; si = si->sib_next) {
check_queued(si);
}
} else {
if (stream_active(stream) || !nghttp2_pq_empty(&stream->obq)) {
fprintf(stderr,
"stream(%p) = %d, stream->queued == 0, but "
"stream_active(stream) == %d and "
"nghttp2_pq_size(&stream->obq) = %zu\n",
stream, stream->stream_id, stream_active(stream),
nghttp2_pq_size(&stream->obq));
assert(0);
}
for (si = stream->dep_next; si; si = si->sib_next) {
ensure_inactive(si);
}
}
}
static void check_sum_dep(nghttp2_stream *stream) {
nghttp2_stream *si;
int32_t n = 0;
for (si = stream->dep_next; si; si = si->sib_next) {
n += si->weight;
}
if (n != stream->sum_dep_weight) {
fprintf(stderr, "stream(%p)=%d, sum_dep_weight = %d; want %d\n", stream,
stream->stream_id, n, stream->sum_dep_weight);
assert(0);
}
for (si = stream->dep_next; si; si = si->sib_next) {
check_sum_dep(si);
}
}
static void check_dep_prev(nghttp2_stream *stream) {
nghttp2_stream *si;
for (si = stream->dep_next; si; si = si->sib_next) {
if (si->dep_prev != stream) {
fprintf(stderr, "si->dep_prev = %p; want %p\n", si->dep_prev, stream);
assert(0);
}
check_dep_prev(si);
}
}
#endif /* STREAM_DEP_DEBUG */
#ifdef STREAM_DEP_DEBUG
static void validate_tree(nghttp2_stream *stream) {
nghttp2_stream *si;
if (!stream) {
return;
}
for (; stream->dep_prev; stream = stream->dep_prev)
;
assert(stream->stream_id == 0);
assert(!stream->queued);
fprintf(stderr, "checking...\n");
if (nghttp2_pq_empty(&stream->obq)) {
fprintf(stderr, "root obq empty\n");
for (si = stream->dep_next; si; si = si->sib_next) {
ensure_inactive(si);
}
} else {
for (si = stream->dep_next; si; si = si->sib_next) {
check_queued(si);
}
}
check_sum_dep(stream);
check_dep_prev(stream);
}
#else /* !STREAM_DEP_DEBUG */
static void validate_tree(nghttp2_stream *stream) { (void)stream; }
#endif /* !STREAM_DEP_DEBUG*/
static int stream_update_dep_on_attach_item(nghttp2_stream *stream) {
int rv;
rv = stream_obq_push(stream->dep_prev, stream);
if (rv != 0) {
return rv;
}
validate_tree(stream);
return 0;
}
static void stream_update_dep_on_detach_item(nghttp2_stream *stream) {
if (nghttp2_pq_empty(&stream->obq)) {
stream_obq_remove(stream);
}
validate_tree(stream);
}
int nghttp2_stream_attach_item(nghttp2_stream *stream,
nghttp2_outbound_item *item) {
int rv;
void nghttp2_stream_attach_item(nghttp2_stream *stream,
nghttp2_outbound_item *item) {
assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0);
assert(stream->item == NULL);
DEBUGF("stream: stream=%d attach item=%p\n", stream->stream_id, item);
stream->item = item;
if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
return 0;
}
rv = stream_update_dep_on_attach_item(stream);
if (rv != 0) {
/* This may relave stream->queued == 1, but stream->item == NULL.
But only consequence of this error is fatal one, and session
destruction. In that execution path, these inconsistency does
not matter. */
stream->item = NULL;
return rv;
}
return 0;
}
void nghttp2_stream_detach_item(nghttp2_stream *stream) {
@@ -506,12 +86,6 @@ void nghttp2_stream_detach_item(nghttp2_stream *stream) {
stream->item = NULL;
stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL);
if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
return;
}
stream_update_dep_on_detach_item(stream);
}
void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
@@ -521,31 +95,16 @@ void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
stream->item, flags);
stream->flags |= flags;
if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
return;
}
stream_update_dep_on_detach_item(stream);
}
int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags) {
void nghttp2_stream_resume_deferred_item(nghttp2_stream *stream,
uint8_t flags) {
assert(stream->item);
DEBUGF("stream: stream=%d resume item=%p flags=%02x\n", stream->stream_id,
stream->item, flags);
stream->flags = (uint8_t)(stream->flags & ~flags);
if (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) {
return 0;
}
if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
return 0;
}
return stream_update_dep_on_attach_item(stream);
}
int nghttp2_stream_check_deferred_item(nghttp2_stream *stream) {
@@ -591,373 +150,11 @@ void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream) {
stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_PUSH);
}
int nghttp2_stream_dep_find_ancestor(nghttp2_stream *stream,
nghttp2_stream *target) {
for (; stream; stream = stream->dep_prev) {
if (stream == target) {
return 1;
}
}
return 0;
}
int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
nghttp2_stream *stream) {
nghttp2_stream *si;
int rv;
DEBUGF("stream: dep_insert dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
dep_stream->stream_id, stream, stream->stream_id);
stream->sum_dep_weight = dep_stream->sum_dep_weight;
dep_stream->sum_dep_weight = stream->weight;
if (dep_stream->dep_next) {
for (si = dep_stream->dep_next; si; si = si->sib_next) {
si->dep_prev = stream;
if (si->queued) {
rv = stream_obq_move(stream, dep_stream, si);
if (rv != 0) {
return rv;
}
}
}
if (stream_subtree_active(stream)) {
rv = stream_obq_push(dep_stream, stream);
if (rv != 0) {
return rv;
}
}
stream->dep_next = dep_stream->dep_next;
}
dep_stream->dep_next = stream;
stream->dep_prev = dep_stream;
validate_tree(stream);
return 0;
}
static void set_dep_prev(nghttp2_stream *stream, nghttp2_stream *dep) {
for (; stream; stream = stream->sib_next) {
stream->dep_prev = dep;
}
}
static void link_dep(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
dep_stream->dep_next = stream;
if (stream) {
stream->dep_prev = dep_stream;
}
}
static void link_sib(nghttp2_stream *a, nghttp2_stream *b) {
a->sib_next = b;
if (b) {
b->sib_prev = a;
}
}
static void insert_link_dep(nghttp2_stream *dep_stream,
nghttp2_stream *stream) {
nghttp2_stream *sib_next;
assert(stream->sib_prev == NULL);
sib_next = dep_stream->dep_next;
link_sib(stream, sib_next);
link_dep(dep_stream, stream);
}
static void unlink_sib(nghttp2_stream *stream) {
nghttp2_stream *prev, *next, *dep_next;
prev = stream->sib_prev;
dep_next = stream->dep_next;
assert(prev);
if (dep_next) {
/*
* prev--stream(--sib_next--...)
* |
* dep_next
*/
link_sib(prev, dep_next);
set_dep_prev(dep_next, stream->dep_prev);
if (stream->sib_next) {
link_sib(stream_last_sib(dep_next), stream->sib_next);
}
} else {
/*
* prev--stream(--sib_next--...)
*/
next = stream->sib_next;
prev->sib_next = next;
if (next) {
next->sib_prev = prev;
}
}
}
static void unlink_dep(nghttp2_stream *stream) {
nghttp2_stream *prev, *next, *dep_next;
prev = stream->dep_prev;
dep_next = stream->dep_next;
assert(prev);
if (dep_next) {
/*
* prev
* |
* stream(--sib_next--...)
* |
* dep_next
*/
link_dep(prev, dep_next);
set_dep_prev(dep_next, stream->dep_prev);
if (stream->sib_next) {
link_sib(stream_last_sib(dep_next), stream->sib_next);
}
} else if (stream->sib_next) {
/*
* prev
* |
* stream--sib_next
*/
next = stream->sib_next;
next->sib_prev = NULL;
link_dep(prev, next);
} else {
prev->dep_next = NULL;
}
}
void nghttp2_stream_dep_add(nghttp2_stream *dep_stream,
nghttp2_stream *stream) {
DEBUGF("stream: dep_add dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
dep_stream->stream_id, stream, stream->stream_id);
dep_stream->sum_dep_weight += stream->weight;
if (dep_stream->dep_next == NULL) {
link_dep(dep_stream, stream);
} else {
insert_link_dep(dep_stream, stream);
}
validate_tree(stream);
}
int nghttp2_stream_dep_remove(nghttp2_stream *stream) {
nghttp2_stream *dep_prev, *si;
int32_t sum_dep_weight_delta;
int rv;
DEBUGF("stream: dep_remove stream(%p)=%d\n", stream, stream->stream_id);
/* Distribute weight of |stream| to direct descendants */
sum_dep_weight_delta = -stream->weight;
for (si = stream->dep_next; si; si = si->sib_next) {
si->weight = nghttp2_stream_dep_distributed_weight(stream, si->weight);
sum_dep_weight_delta += si->weight;
if (si->queued) {
rv = stream_obq_move(stream->dep_prev, stream, si);
if (rv != 0) {
return rv;
}
}
}
assert(stream->dep_prev);
dep_prev = stream->dep_prev;
dep_prev->sum_dep_weight += sum_dep_weight_delta;
if (stream->queued) {
stream_obq_remove(stream);
}
if (stream->sib_prev) {
unlink_sib(stream);
} else {
unlink_dep(stream);
}
stream->sum_dep_weight = 0;
stream->dep_prev = NULL;
stream->dep_next = NULL;
stream->sib_prev = NULL;
stream->sib_next = NULL;
validate_tree(dep_prev);
return 0;
}
int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
nghttp2_stream *stream) {
nghttp2_stream *last_sib;
nghttp2_stream *dep_next;
nghttp2_stream *si;
int rv;
DEBUGF("stream: dep_insert_subtree dep_stream(%p)=%d stream(%p)=%d\n",
dep_stream, dep_stream->stream_id, stream, stream->stream_id);
stream->sum_dep_weight += dep_stream->sum_dep_weight;
dep_stream->sum_dep_weight = stream->weight;
if (dep_stream->dep_next) {
dep_next = dep_stream->dep_next;
link_dep(dep_stream, stream);
if (stream->dep_next) {
last_sib = stream_last_sib(stream->dep_next);
link_sib(last_sib, dep_next);
} else {
link_dep(stream, dep_next);
}
for (si = dep_next; si; si = si->sib_next) {
si->dep_prev = stream;
if (si->queued) {
rv = stream_obq_move(stream, dep_stream, si);
if (rv != 0) {
return rv;
}
}
}
} else {
link_dep(dep_stream, stream);
}
if (stream_subtree_active(stream)) {
rv = stream_obq_push(dep_stream, stream);
if (rv != 0) {
return rv;
}
}
validate_tree(dep_stream);
return 0;
}
int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
nghttp2_stream *stream) {
int rv;
DEBUGF("stream: dep_add_subtree dep_stream(%p)=%d stream(%p)=%d\n",
dep_stream, dep_stream->stream_id, stream, stream->stream_id);
dep_stream->sum_dep_weight += stream->weight;
if (dep_stream->dep_next) {
insert_link_dep(dep_stream, stream);
} else {
link_dep(dep_stream, stream);
}
if (stream_subtree_active(stream)) {
rv = stream_obq_push(dep_stream, stream);
if (rv != 0) {
return rv;
}
}
validate_tree(dep_stream);
return 0;
}
void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream) {
nghttp2_stream *next, *dep_prev;
DEBUGF("stream: dep_remove_subtree stream(%p)=%d\n", stream,
stream->stream_id);
assert(stream->dep_prev);
dep_prev = stream->dep_prev;
if (stream->sib_prev) {
link_sib(stream->sib_prev, stream->sib_next);
} else {
next = stream->sib_next;
link_dep(dep_prev, next);
if (next) {
next->sib_prev = NULL;
}
}
dep_prev->sum_dep_weight -= stream->weight;
if (stream->queued) {
stream_obq_remove(stream);
}
validate_tree(dep_prev);
stream->sib_prev = NULL;
stream->sib_next = NULL;
stream->dep_prev = NULL;
}
int nghttp2_stream_in_dep_tree(nghttp2_stream *stream) {
return stream->dep_prev || stream->dep_next || stream->sib_prev ||
stream->sib_next;
}
nghttp2_outbound_item *
nghttp2_stream_next_outbound_item(nghttp2_stream *stream) {
nghttp2_pq_entry *ent;
nghttp2_stream *si;
for (;;) {
if (stream_active(stream)) {
/* Update ascendant's descendant_last_cycle here, so that we can
assure that new stream is scheduled based on it. */
for (si = stream; si->dep_prev; si = si->dep_prev) {
si->dep_prev->descendant_last_cycle = si->cycle;
}
return stream->item;
}
ent = nghttp2_pq_top(&stream->obq);
if (!ent) {
return NULL;
}
stream = nghttp2_struct_of(ent, nghttp2_stream, pq_entry);
}
}
nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) {
if (stream == &root) {
return NGHTTP2_STREAM_STATE_IDLE;
}
if (stream->flags & NGHTTP2_STREAM_FLAG_CLOSED) {
return NGHTTP2_STREAM_STATE_CLOSED;
}
@@ -988,27 +185,39 @@ nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) {
}
nghttp2_stream *nghttp2_stream_get_parent(nghttp2_stream *stream) {
return stream->dep_prev;
(void)stream;
return NULL;
}
nghttp2_stream *nghttp2_stream_get_next_sibling(nghttp2_stream *stream) {
return stream->sib_next;
(void)stream;
return NULL;
}
nghttp2_stream *nghttp2_stream_get_previous_sibling(nghttp2_stream *stream) {
return stream->sib_prev;
(void)stream;
return NULL;
}
nghttp2_stream *nghttp2_stream_get_first_child(nghttp2_stream *stream) {
return stream->dep_next;
(void)stream;
return NULL;
}
int32_t nghttp2_stream_get_weight(nghttp2_stream *stream) {
return stream->weight;
(void)stream;
return NGHTTP2_DEFAULT_WEIGHT;
}
int32_t nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream) {
return stream->sum_dep_weight;
(void)stream;
return 0;
}
int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream) {

View File

@@ -91,9 +91,6 @@ typedef enum {
/* bitwise OR of NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and
NGHTTP2_STREAM_FLAG_DEFERRED_USER. */
NGHTTP2_STREAM_FLAG_DEFERRED_ALL = 0x0c,
/* Indicates that this stream is not subject to RFC7540
priorities scheme. */
NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES = 0x10,
/* Ignore client RFC 9218 priority signal. */
NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES = 0x20,
/* Indicates that RFC 9113 leading and trailing white spaces
@@ -146,39 +143,18 @@ typedef enum {
} nghttp2_http_flag;
struct nghttp2_stream {
/* Entry for dep_prev->obq */
nghttp2_stream_state state;
nghttp2_pq_entry pq_entry;
/* Priority Queue storing direct descendant (nghttp2_stream). Only
streams which itself has some data to send, or has a descendant
which has some data to sent. */
nghttp2_pq obq;
/* Content-Length of request/response body. -1 if unknown. */
int64_t content_length;
/* Received body so far */
int64_t recv_content_length;
/* Base last_cycle for direct descendent streams. */
uint64_t descendant_last_cycle;
/* Next scheduled time to sent item */
uint64_t cycle;
/* Next seq used for direct descendant streams */
uint64_t descendant_next_seq;
/* Secondary key for prioritization to break a tie for cycle. This
value is monotonically increased for single parent stream. */
uint64_t seq;
/* pointers to form dependency tree. If multiple streams depend on
a stream, only one stream (left most) has non-NULL dep_prev which
points to the stream it depends on. The remaining streams are
linked using sib_prev and sib_next. The stream which has
non-NULL dep_prev always NULL sib_prev. The right most stream
has NULL sib_next. If this stream is a root of dependency tree,
dep_prev and sib_prev are NULL. */
nghttp2_stream *dep_prev, *dep_next;
nghttp2_stream *sib_prev, *sib_next;
/* When stream is kept after closure, it may be kept in doubly
linked list pointed by nghttp2_session closed_stream_head.
closed_next points to the next stream object if it is the element
of the list. */
nghttp2_stream *closed_prev, *closed_next;
nghttp2_stream *closed_next;
/* The arbitrary data provided by user for this stream. */
void *stream_user_data;
/* Item to send */
@@ -205,13 +181,8 @@ struct nghttp2_stream {
NGHTTP2_INITIAL_WINDOW_SIZE and could be increased/decreased by
submitting WINDOW_UPDATE. See nghttp2_submit_window_update(). */
int32_t local_window_size;
/* weight of this stream */
int32_t weight;
/* This is unpaid penalty (offset) when calculating cycle. */
uint32_t pending_penalty;
/* sum of weight of direct descendants */
int32_t sum_dep_weight;
nghttp2_stream_state state;
/* status code from remote server */
int16_t status_code;
/* Bitwise OR of zero or more nghttp2_http_flag values */
@@ -239,9 +210,9 @@ struct nghttp2_stream {
void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
uint8_t flags, nghttp2_stream_state initial_state,
int32_t weight, int32_t remote_initial_window_size,
int32_t remote_initial_window_size,
int32_t local_initial_window_size,
void *stream_user_data, nghttp2_mem *mem);
void *stream_user_data);
void nghttp2_stream_free(nghttp2_stream *stream);
@@ -267,14 +238,8 @@ void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags);
* NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and given masks are
* cleared if they are set. So even if this function is called, if
* one of flag is still set, data does not become active.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags);
void nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags);
/*
* Returns nonzero if item is deferred by whatever reason.
@@ -317,57 +282,11 @@ int nghttp2_stream_update_local_initial_window_size(
*/
void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream);
/*
* Returns nonzero if |target| is an ancestor of |stream|.
*/
int nghttp2_stream_dep_find_ancestor(nghttp2_stream *stream,
nghttp2_stream *target);
/*
* Computes distributed weight of a stream of the |weight| under the
* |stream| if |stream| is removed from a dependency tree.
*/
int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream,
int32_t weight);
/*
* Makes the |stream| depend on the |dep_stream|. This dependency is
* exclusive. All existing direct descendants of |dep_stream| become
* the descendants of the |stream|. This function assumes
* |stream->item| is NULL.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
nghttp2_stream *stream);
/*
* Makes the |stream| depend on the |dep_stream|. This dependency is
* not exclusive. This function assumes |stream->item| is NULL.
*/
void nghttp2_stream_dep_add(nghttp2_stream *dep_stream, nghttp2_stream *stream);
/*
* Removes the |stream| from the current dependency tree. This
* function assumes |stream->item| is NULL.
*/
int nghttp2_stream_dep_remove(nghttp2_stream *stream);
/*
* Attaches |item| to |stream|.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_stream_attach_item(nghttp2_stream *stream,
nghttp2_outbound_item *item);
void nghttp2_stream_attach_item(nghttp2_stream *stream,
nghttp2_outbound_item *item);
/*
* Detaches |stream->item|. This function does not free
@@ -375,66 +294,4 @@ int nghttp2_stream_attach_item(nghttp2_stream *stream,
*/
void nghttp2_stream_detach_item(nghttp2_stream *stream);
/*
* Makes the |stream| depend on the |dep_stream|. This dependency is
* exclusive.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
nghttp2_stream *stream);
/*
* Makes the |stream| depend on the |dep_stream|. This dependency is
* not exclusive.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
nghttp2_stream *stream);
/*
* Removes subtree whose root stream is |stream|. The
* effective_weight of streams in removed subtree is not updated.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream);
/*
* Returns nonzero if |stream| is in any dependency tree.
*/
int nghttp2_stream_in_dep_tree(nghttp2_stream *stream);
/*
* Schedules transmission of |stream|'s item, assuming stream->item is
* attached, and stream->last_writelen was updated.
*/
void nghttp2_stream_reschedule(nghttp2_stream *stream);
/*
* Changes |stream|'s weight to |weight|. If |stream| is queued, it
* will be rescheduled based on new weight.
*/
void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight);
/*
* Returns a stream which has highest priority, updating
* descendant_last_cycle of selected stream's ancestors.
*/
nghttp2_outbound_item *
nghttp2_stream_next_outbound_item(nghttp2_stream *stream);
#endif /* NGHTTP2_STREAM */

View File

@@ -32,42 +32,12 @@
#include "nghttp2_helper.h"
#include "nghttp2_priority_spec.h"
/*
* Detects the dependency error, that is stream attempted to depend on
* itself. If |stream_id| is -1, we use session->next_stream_id as
* stream ID.
*
* This function returns 0 if it succeeds, or one of the following
* error codes:
*
* NGHTTP2_ERR_INVALID_ARGUMENT
* Stream attempted to depend on itself.
*/
static int detect_self_dependency(nghttp2_session *session, int32_t stream_id,
const nghttp2_priority_spec *pri_spec) {
assert(pri_spec);
if (stream_id == -1) {
if ((int32_t)session->next_stream_id == pri_spec->stream_id) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
return 0;
}
if (stream_id == pri_spec->stream_id) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
return 0;
}
/* This function takes ownership of |nva_copy|. Regardless of the
return value, the caller must not free |nva_copy| after this
function returns. */
static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags,
int32_t stream_id,
const nghttp2_priority_spec *pri_spec,
nghttp2_nv *nva_copy, size_t nvlen,
int32_t stream_id, nghttp2_nv *nva_copy,
size_t nvlen,
const nghttp2_data_provider_wrap *dpw,
void *stream_user_data) {
int rv;
@@ -114,8 +84,8 @@ static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags,
frame = &item->frame;
nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat,
pri_spec, nva_copy, nvlen);
nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat, NULL,
nva_copy, nvlen);
rv = nghttp2_session_add_item(session, item);
@@ -141,31 +111,22 @@ fail2:
static int32_t submit_headers_shared_nva(nghttp2_session *session,
uint8_t flags, int32_t stream_id,
const nghttp2_priority_spec *pri_spec,
const nghttp2_nv *nva, size_t nvlen,
const nghttp2_data_provider_wrap *dpw,
void *stream_user_data) {
int rv;
nghttp2_nv *nva_copy;
nghttp2_priority_spec copy_pri_spec;
nghttp2_mem *mem;
mem = &session->mem;
if (pri_spec) {
copy_pri_spec = *pri_spec;
nghttp2_priority_spec_normalize_weight(&copy_pri_spec);
} else {
nghttp2_priority_spec_default_init(&copy_pri_spec);
}
rv = nghttp2_nv_array_copy(&nva_copy, nva, nvlen, mem);
if (rv < 0) {
return rv;
}
return submit_headers_shared(session, flags, stream_id, &copy_pri_spec,
nva_copy, nvlen, dpw, stream_user_data);
return submit_headers_shared(session, flags, stream_id, nva_copy, nvlen, dpw,
stream_user_data);
}
int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id,
@@ -174,8 +135,8 @@ int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id,
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
return (int)submit_headers_shared_nva(
session, NGHTTP2_FLAG_END_STREAM, stream_id, NULL, nva, nvlen, NULL, NULL);
return (int)submit_headers_shared_nva(session, NGHTTP2_FLAG_END_STREAM,
stream_id, nva, nvlen, NULL, NULL);
}
int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
@@ -183,7 +144,7 @@ int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
const nghttp2_priority_spec *pri_spec,
const nghttp2_nv *nva, size_t nvlen,
void *stream_user_data) {
int rv;
(void)pri_spec;
if (stream_id == -1) {
if (session->server) {
@@ -195,20 +156,8 @@ int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
flags &= NGHTTP2_FLAG_END_STREAM;
if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) &&
session->remote_settings.no_rfc7540_priorities != 1) {
rv = detect_self_dependency(session, stream_id, pri_spec);
if (rv != 0) {
return rv;
}
flags |= NGHTTP2_FLAG_PRIORITY;
} else {
pri_spec = NULL;
}
return submit_headers_shared_nva(session, flags, stream_id, pri_spec, nva,
nvlen, NULL, stream_user_data);
return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, NULL,
stream_user_data);
}
int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
@@ -220,51 +169,10 @@ int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
int32_t stream_id,
const nghttp2_priority_spec *pri_spec) {
int rv;
nghttp2_outbound_item *item;
nghttp2_frame *frame;
nghttp2_priority_spec copy_pri_spec;
nghttp2_mem *mem;
(void)session;
(void)flags;
mem = &session->mem;
if (session->remote_settings.no_rfc7540_priorities == 1) {
return 0;
}
if (stream_id == 0 || pri_spec == NULL) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
if (stream_id == pri_spec->stream_id) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
copy_pri_spec = *pri_spec;
nghttp2_priority_spec_normalize_weight(&copy_pri_spec);
item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
if (item == NULL) {
return NGHTTP2_ERR_NOMEM;
}
nghttp2_outbound_item_init(item);
frame = &item->frame;
nghttp2_frame_priority_init(&frame->priority, stream_id, &copy_pri_spec);
rv = nghttp2_session_add_item(session, item);
if (rv != 0) {
nghttp2_frame_priority_free(&frame->priority);
nghttp2_mem_free(mem, item);
return rv;
}
(void)stream_id;
(void)pri_spec;
return 0;
}
@@ -738,46 +646,29 @@ fail_item_malloc:
return rv;
}
static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec,
const nghttp2_data_provider_wrap *dpw) {
static uint8_t set_request_flags(const nghttp2_data_provider_wrap *dpw) {
uint8_t flags = NGHTTP2_FLAG_NONE;
if (dpw == NULL || dpw->data_prd.read_callback == NULL) {
flags |= NGHTTP2_FLAG_END_STREAM;
}
if (pri_spec) {
flags |= NGHTTP2_FLAG_PRIORITY;
}
return flags;
}
static int32_t submit_request_shared(nghttp2_session *session,
const nghttp2_priority_spec *pri_spec,
const nghttp2_nv *nva, size_t nvlen,
const nghttp2_data_provider_wrap *dpw,
void *stream_user_data) {
uint8_t flags;
int rv;
if (session->server) {
return NGHTTP2_ERR_PROTO;
}
if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) &&
session->remote_settings.no_rfc7540_priorities != 1) {
rv = detect_self_dependency(session, -1, pri_spec);
if (rv != 0) {
return rv;
}
} else {
pri_spec = NULL;
}
flags = set_request_flags(dpw);
flags = set_request_flags(pri_spec, dpw);
return submit_headers_shared_nva(session, flags, -1, pri_spec, nva, nvlen,
dpw, stream_user_data);
return submit_headers_shared_nva(session, flags, -1, nva, nvlen, dpw,
stream_user_data);
}
int32_t nghttp2_submit_request(nghttp2_session *session,
@@ -786,8 +677,9 @@ int32_t nghttp2_submit_request(nghttp2_session *session,
const nghttp2_data_provider *data_prd,
void *stream_user_data) {
nghttp2_data_provider_wrap dpw;
(void)pri_spec;
return submit_request_shared(session, pri_spec, nva, nvlen,
return submit_request_shared(session, nva, nvlen,
nghttp2_data_provider_wrap_v1(&dpw, data_prd),
stream_user_data);
}
@@ -798,8 +690,9 @@ int32_t nghttp2_submit_request2(nghttp2_session *session,
const nghttp2_data_provider2 *data_prd,
void *stream_user_data) {
nghttp2_data_provider_wrap dpw;
(void)pri_spec;
return submit_request_shared(session, pri_spec, nva, nvlen,
return submit_request_shared(session, nva, nvlen,
nghttp2_data_provider_wrap_v2(&dpw, data_prd),
stream_user_data);
}
@@ -826,8 +719,8 @@ static int submit_response_shared(nghttp2_session *session, int32_t stream_id,
}
flags = set_response_flags(dpw);
return submit_headers_shared_nva(session, flags, stream_id, NULL, nva, nvlen,
dpw, NULL);
return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, dpw,
NULL);
}
int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,

File diff suppressed because it is too large Load Diff

View File

@@ -63,7 +63,6 @@ munit_void_test_decl(test_nghttp2_session_on_request_headers_received)
munit_void_test_decl(test_nghttp2_session_on_response_headers_received)
munit_void_test_decl(test_nghttp2_session_on_headers_received)
munit_void_test_decl(test_nghttp2_session_on_push_response_headers_received)
munit_void_test_decl(test_nghttp2_session_on_priority_received)
munit_void_test_decl(test_nghttp2_session_on_rst_stream_received)
munit_void_test_decl(test_nghttp2_session_on_settings_received)
munit_void_test_decl(test_nghttp2_session_on_push_promise_received)
@@ -81,9 +80,6 @@ munit_void_test_decl(test_nghttp2_session_send_rst_stream)
munit_void_test_decl(test_nghttp2_session_send_push_promise)
munit_void_test_decl(test_nghttp2_session_is_my_stream_id)
munit_void_test_decl(test_nghttp2_session_upgrade2)
munit_void_test_decl(test_nghttp2_session_reprioritize_stream)
munit_void_test_decl(
test_nghttp2_session_reprioritize_stream_with_idle_stream_dep)
munit_void_test_decl(test_nghttp2_submit_data)
munit_void_test_decl(test_nghttp2_submit_data_read_length_too_large)
munit_void_test_decl(test_nghttp2_submit_data_read_length_smallest)
@@ -100,7 +96,6 @@ munit_void_test_decl(test_nghttp2_submit_headers_push_reply)
munit_void_test_decl(test_nghttp2_submit_headers)
munit_void_test_decl(test_nghttp2_submit_headers_continuation)
munit_void_test_decl(test_nghttp2_submit_headers_continuation_extra_large)
munit_void_test_decl(test_nghttp2_submit_priority)
munit_void_test_decl(test_nghttp2_submit_settings)
munit_void_test_decl(test_nghttp2_submit_settings_update_local_window_size)
munit_void_test_decl(test_nghttp2_submit_settings_multiple_times)
@@ -115,7 +110,6 @@ munit_void_test_decl(test_nghttp2_submit_origin)
munit_void_test_decl(test_nghttp2_submit_priority_update)
munit_void_test_decl(test_nghttp2_submit_rst_stream)
munit_void_test_decl(test_nghttp2_session_open_stream)
munit_void_test_decl(test_nghttp2_session_open_stream_with_idle_stream_dep)
munit_void_test_decl(test_nghttp2_session_get_next_ob_item)
munit_void_test_decl(test_nghttp2_session_pop_next_ob_item)
munit_void_test_decl(test_nghttp2_session_reply_fail)
@@ -135,21 +129,8 @@ munit_void_test_decl(test_nghttp2_session_data_backoff_by_high_pri_frame)
munit_void_test_decl(test_nghttp2_session_pack_data_with_padding)
munit_void_test_decl(test_nghttp2_session_pack_headers_with_padding)
munit_void_test_decl(test_nghttp2_pack_settings_payload)
munit_void_test_decl(test_nghttp2_session_stream_dep_add)
munit_void_test_decl(test_nghttp2_session_stream_dep_remove)
munit_void_test_decl(test_nghttp2_session_stream_dep_add_subtree)
munit_void_test_decl(test_nghttp2_session_stream_dep_remove_subtree)
munit_void_test_decl(
test_nghttp2_session_stream_dep_all_your_stream_are_belong_to_us)
munit_void_test_decl(test_nghttp2_session_stream_attach_item)
munit_void_test_decl(test_nghttp2_session_stream_attach_item_subtree)
munit_void_test_decl(test_nghttp2_session_stream_get_state)
munit_void_test_decl(test_nghttp2_session_stream_get_something)
munit_void_test_decl(test_nghttp2_session_find_stream)
munit_void_test_decl(test_nghttp2_session_keep_closed_stream)
munit_void_test_decl(test_nghttp2_session_keep_idle_stream)
munit_void_test_decl(test_nghttp2_session_detach_idle_stream)
munit_void_test_decl(test_nghttp2_session_large_dep_tree)
munit_void_test_decl(test_nghttp2_session_graceful_shutdown)
munit_void_test_decl(test_nghttp2_session_on_header_temporal_failure)
munit_void_test_decl(test_nghttp2_session_recv_client_magic)
@@ -162,11 +143,7 @@ munit_void_test_decl(test_nghttp2_session_on_begin_headers_temporal_failure)
munit_void_test_decl(test_nghttp2_session_defer_then_close)
munit_void_test_decl(test_nghttp2_session_detach_item_from_closed_stream)
munit_void_test_decl(test_nghttp2_session_flooding)
munit_void_test_decl(test_nghttp2_session_change_stream_priority)
munit_void_test_decl(test_nghttp2_session_change_extpri_stream_priority)
munit_void_test_decl(test_nghttp2_session_create_idle_stream)
munit_void_test_decl(test_nghttp2_session_repeated_priority_change)
munit_void_test_decl(test_nghttp2_session_repeated_priority_submission)
munit_void_test_decl(test_nghttp2_session_set_local_window_size)
munit_void_test_decl(test_nghttp2_session_cancel_from_before_frame_send)
munit_void_test_decl(test_nghttp2_session_too_many_settings)
@@ -175,7 +152,6 @@ munit_void_test_decl(test_nghttp2_session_pause_data)
munit_void_test_decl(test_nghttp2_session_no_closed_streams)
munit_void_test_decl(test_nghttp2_session_set_stream_user_data)
munit_void_test_decl(test_nghttp2_session_no_rfc7540_priorities)
munit_void_test_decl(test_nghttp2_session_server_fallback_rfc7540_priorities)
munit_void_test_decl(test_nghttp2_session_stream_reset_ratelim)
munit_void_test_decl(test_nghttp2_http_mandatory_headers)
munit_void_test_decl(test_nghttp2_http_content_length)

View File

@@ -260,49 +260,9 @@ void bufs_large_init(nghttp2_bufs *bufs, size_t chunk_size) {
nghttp2_mem_default());
}
static nghttp2_stream *open_stream_with_all(nghttp2_session *session,
int32_t stream_id, int32_t weight,
uint8_t exclusive,
nghttp2_stream *dep_stream) {
nghttp2_priority_spec pri_spec;
int32_t dep_stream_id;
if (dep_stream) {
dep_stream_id = dep_stream->stream_id;
} else {
dep_stream_id = 0;
}
nghttp2_priority_spec_init(&pri_spec, dep_stream_id, weight, exclusive);
return nghttp2_session_open_stream(session, stream_id,
NGHTTP2_STREAM_FLAG_NONE, &pri_spec,
NGHTTP2_STREAM_OPENED, NULL);
}
nghttp2_stream *open_stream(nghttp2_session *session, int32_t stream_id) {
return open_stream_with_all(session, stream_id, NGHTTP2_DEFAULT_WEIGHT, 0,
NULL);
}
nghttp2_stream *open_stream_with_dep(nghttp2_session *session,
int32_t stream_id,
nghttp2_stream *dep_stream) {
return open_stream_with_all(session, stream_id, NGHTTP2_DEFAULT_WEIGHT, 0,
dep_stream);
}
nghttp2_stream *open_stream_with_dep_weight(nghttp2_session *session,
int32_t stream_id, int32_t weight,
nghttp2_stream *dep_stream) {
return open_stream_with_all(session, stream_id, weight, 0, dep_stream);
}
nghttp2_stream *open_stream_with_dep_excl(nghttp2_session *session,
int32_t stream_id,
nghttp2_stream *dep_stream) {
return open_stream_with_all(session, stream_id, NGHTTP2_DEFAULT_WEIGHT, 1,
dep_stream);
return nghttp2_session_open_stream(
session, stream_id, NGHTTP2_STREAM_FLAG_NONE, NGHTTP2_STREAM_OPENED, NULL);
}
nghttp2_outbound_item *create_data_ob_item(nghttp2_mem *mem) {
@@ -315,58 +275,26 @@ nghttp2_outbound_item *create_data_ob_item(nghttp2_mem *mem) {
}
nghttp2_stream *open_sent_stream(nghttp2_session *session, int32_t stream_id) {
nghttp2_priority_spec pri_spec;
nghttp2_priority_spec_init(&pri_spec, 0, NGHTTP2_DEFAULT_WEIGHT, 0);
return open_sent_stream3(session, stream_id, NGHTTP2_FLAG_NONE, &pri_spec,
return open_sent_stream3(session, stream_id, NGHTTP2_FLAG_NONE,
NGHTTP2_STREAM_OPENED, NULL);
}
nghttp2_stream *open_sent_stream2(nghttp2_session *session, int32_t stream_id,
nghttp2_stream_state initial_state) {
nghttp2_priority_spec pri_spec;
nghttp2_priority_spec_init(&pri_spec, 0, NGHTTP2_DEFAULT_WEIGHT, 0);
return open_sent_stream3(session, stream_id, NGHTTP2_FLAG_NONE, &pri_spec,
initial_state, NULL);
return open_sent_stream3(session, stream_id, NGHTTP2_FLAG_NONE, initial_state,
NULL);
}
nghttp2_stream *open_sent_stream3(nghttp2_session *session, int32_t stream_id,
uint8_t flags,
nghttp2_priority_spec *pri_spec_in,
nghttp2_stream_state initial_state,
void *stream_user_data) {
nghttp2_stream *stream;
assert(nghttp2_session_is_my_stream_id(session, stream_id));
stream = nghttp2_session_open_stream(session, stream_id, flags, pri_spec_in,
initial_state, stream_user_data);
session->last_sent_stream_id =
nghttp2_max_int32(session->last_sent_stream_id, stream_id);
session->next_stream_id =
nghttp2_max_uint32(session->next_stream_id, (uint32_t)stream_id + 2);
return stream;
}
nghttp2_stream *open_sent_stream_with_dep(nghttp2_session *session,
int32_t stream_id,
nghttp2_stream *dep_stream) {
return open_sent_stream_with_dep_weight(session, stream_id,
NGHTTP2_DEFAULT_WEIGHT, dep_stream);
}
nghttp2_stream *open_sent_stream_with_dep_weight(nghttp2_session *session,
int32_t stream_id,
int32_t weight,
nghttp2_stream *dep_stream) {
nghttp2_stream *stream;
assert(nghttp2_session_is_my_stream_id(session, stream_id));
stream = open_stream_with_all(session, stream_id, weight, 0, dep_stream);
stream = nghttp2_session_open_stream(session, stream_id, flags, initial_state,
stream_user_data);
session->last_sent_stream_id =
nghttp2_max_int32(session->last_sent_stream_id, stream_id);
session->next_stream_id =
@@ -376,56 +304,26 @@ nghttp2_stream *open_sent_stream_with_dep_weight(nghttp2_session *session,
}
nghttp2_stream *open_recv_stream(nghttp2_session *session, int32_t stream_id) {
nghttp2_priority_spec pri_spec;
nghttp2_priority_spec_init(&pri_spec, 0, NGHTTP2_DEFAULT_WEIGHT, 0);
return open_recv_stream3(session, stream_id, NGHTTP2_FLAG_NONE, &pri_spec,
return open_recv_stream3(session, stream_id, NGHTTP2_FLAG_NONE,
NGHTTP2_STREAM_OPENED, NULL);
}
nghttp2_stream *open_recv_stream2(nghttp2_session *session, int32_t stream_id,
nghttp2_stream_state initial_state) {
nghttp2_priority_spec pri_spec;
nghttp2_priority_spec_init(&pri_spec, 0, NGHTTP2_DEFAULT_WEIGHT, 0);
return open_recv_stream3(session, stream_id, NGHTTP2_FLAG_NONE, &pri_spec,
initial_state, NULL);
return open_recv_stream3(session, stream_id, NGHTTP2_FLAG_NONE, initial_state,
NULL);
}
nghttp2_stream *open_recv_stream3(nghttp2_session *session, int32_t stream_id,
uint8_t flags,
nghttp2_priority_spec *pri_spec_in,
nghttp2_stream_state initial_state,
void *stream_user_data) {
nghttp2_stream *stream;
assert(!nghttp2_session_is_my_stream_id(session, stream_id));
stream = nghttp2_session_open_stream(session, stream_id, flags, pri_spec_in,
initial_state, stream_user_data);
session->last_recv_stream_id =
nghttp2_max_int32(session->last_recv_stream_id, stream_id);
return stream;
}
nghttp2_stream *open_recv_stream_with_dep(nghttp2_session *session,
int32_t stream_id,
nghttp2_stream *dep_stream) {
return open_recv_stream_with_dep_weight(session, stream_id,
NGHTTP2_DEFAULT_WEIGHT, dep_stream);
}
nghttp2_stream *open_recv_stream_with_dep_weight(nghttp2_session *session,
int32_t stream_id,
int32_t weight,
nghttp2_stream *dep_stream) {
nghttp2_stream *stream;
assert(!nghttp2_session_is_my_stream_id(session, stream_id));
stream = open_stream_with_all(session, stream_id, weight, 0, dep_stream);
stream = nghttp2_session_open_stream(session, stream_id, flags, initial_state,
stream_user_data);
session->last_recv_stream_id =
nghttp2_max_int32(session->last_recv_stream_id, stream_id);

View File

@@ -78,18 +78,6 @@ void bufs_large_init(nghttp2_bufs *bufs, size_t chunk_size);
nghttp2_stream *open_stream(nghttp2_session *session, int32_t stream_id);
nghttp2_stream *open_stream_with_dep(nghttp2_session *session,
int32_t stream_id,
nghttp2_stream *dep_stream);
nghttp2_stream *open_stream_with_dep_weight(nghttp2_session *session,
int32_t stream_id, int32_t weight,
nghttp2_stream *dep_stream);
nghttp2_stream *open_stream_with_dep_excl(nghttp2_session *session,
int32_t stream_id,
nghttp2_stream *dep_stream);
nghttp2_outbound_item *create_data_ob_item(nghttp2_mem *mem);
/* Opens stream. This stream is assumed to be sent from |session|,
@@ -102,19 +90,9 @@ nghttp2_stream *open_sent_stream2(nghttp2_session *session, int32_t stream_id,
nghttp2_stream *open_sent_stream3(nghttp2_session *session, int32_t stream_id,
uint8_t flags,
nghttp2_priority_spec *pri_spec_in,
nghttp2_stream_state initial_state,
void *stream_user_data);
nghttp2_stream *open_sent_stream_with_dep(nghttp2_session *session,
int32_t stream_id,
nghttp2_stream *dep_stream);
nghttp2_stream *open_sent_stream_with_dep_weight(nghttp2_session *session,
int32_t stream_id,
int32_t weight,
nghttp2_stream *dep_stream);
/* Opens stream. This stream is assumed to be received by |session|,
and session->last_recv_stream_id will be adjusted accordingly. */
nghttp2_stream *open_recv_stream(nghttp2_session *session, int32_t stream_id);
@@ -124,17 +102,7 @@ nghttp2_stream *open_recv_stream2(nghttp2_session *session, int32_t stream_id,
nghttp2_stream *open_recv_stream3(nghttp2_session *session, int32_t stream_id,
uint8_t flags,
nghttp2_priority_spec *pri_spec_in,
nghttp2_stream_state initial_state,
void *stream_user_data);
nghttp2_stream *open_recv_stream_with_dep(nghttp2_session *session,
int32_t stream_id,
nghttp2_stream *dep_stream);
nghttp2_stream *open_recv_stream_with_dep_weight(nghttp2_session *session,
int32_t stream_id,
int32_t weight,
nghttp2_stream *dep_stream);
#endif /* NGHTTP2_TEST_HELPER_H */