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 * Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of * prioritization scheme.
* 2024, this function will always return 0 without doing anything.
* *
* Changes priority of existing stream denoted by |stream_id|. The * This function is noop. It always returns 0.
* 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
*/ */
NGHTTP2_EXTERN int NGHTTP2_EXTERN int
nghttp2_session_change_stream_priority(nghttp2_session *session, 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 * Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of * prioritization scheme.
* 2024, this function will always return 0 without doing anything.
* *
* Creates idle stream with the given |stream_id|, and priority * This function is noop. It always returns 0.
* |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
*/ */
NGHTTP2_EXTERN int NGHTTP2_EXTERN int
nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id, 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. * Submits HEADERS frame and optionally one or more DATA frames.
* *
* The |pri_spec| is a deprecated priority specification of this * The |pri_spec| is ignored.
* 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 |nva| is an array of name/value pair :type:`nghttp2_nv` with * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
* |nvlen| elements. The application is responsible to include * |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` * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
* No stream ID is available because maximum stream ID was * No stream ID is available because maximum stream ID was
* reached. * 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` * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
* The |session| is server session. * 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. * Submits HEADERS frame and optionally one or more DATA frames.
* *
* The |pri_spec| is a deprecated priority specification of this * The |pri_spec| is ignored.
* 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 |nva| is an array of name/value pair :type:`nghttp2_nv` with * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
* |nvlen| elements. The application is responsible to include * |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` * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
* No stream ID is available because maximum stream ID was * No stream ID is available because maximum stream ID was
* reached. * 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` * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
* The |session| is server session. * 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 * assigned stream ID will be returned. Otherwise, specify stream ID
* in |stream_id|. * in |stream_id|.
* *
* The |pri_spec| is a deprecated priority specification of this * The |pri_spec| is ignored.
* 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 |nva| is an array of name/value pair :type:`nghttp2_nv` with * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
* |nvlen| elements. The application is responsible to include * |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 * No stream ID is available because maximum stream ID was
* reached. * reached.
* :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0; or trying to depend on itself (stream ID * The |stream_id| is 0.
* equals ``pri_spec->stream_id``).
* :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
* DATA or HEADERS has been already submitted and not fully * DATA or HEADERS has been already submitted and not fully
* processed yet. This happens if stream denoted by |stream_id| * 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 * Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of * prioritization scheme.
* 2024, this function will always return 0 without doing anything.
* *
* Submits PRIORITY frame to change the priority of stream |stream_id| * This function is noop. It always returns 0.
* 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.
*/ */
NGHTTP2_EXTERN int NGHTTP2_EXTERN int
nghttp2_submit_priority(nghttp2_session *session, uint8_t flags, 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 * Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of * prioritization scheme.
* 2024, this function will always return NULL.
* *
* Returns the parent stream of |stream| in dependency tree. Returns * This function always returns NULL.
* NULL if there is no such stream.
*/ */
NGHTTP2_EXTERN nghttp2_stream * NGHTTP2_EXTERN nghttp2_stream *
nghttp2_stream_get_parent(nghttp2_stream *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 * Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of * prioritization scheme.
* 2024, this function will always return NULL.
* *
* Returns the next sibling stream of |stream| in dependency tree. * This function always returns NULL.
* Returns NULL if there is no such stream.
*/ */
NGHTTP2_EXTERN nghttp2_stream * NGHTTP2_EXTERN nghttp2_stream *
nghttp2_stream_get_next_sibling(nghttp2_stream *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 * Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of * prioritization scheme.
* 2024, this function will always return NULL.
* *
* Returns the previous sibling stream of |stream| in dependency tree. * This function always returns NULL.
* Returns NULL if there is no such stream.
*/ */
NGHTTP2_EXTERN nghttp2_stream * NGHTTP2_EXTERN nghttp2_stream *
nghttp2_stream_get_previous_sibling(nghttp2_stream *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 * Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of * prioritization scheme.
* 2024, this function will always return NULL.
* *
* Returns the first child stream of |stream| in dependency tree. * This function always returns NULL.
* Returns NULL if there is no such stream.
*/ */
NGHTTP2_EXTERN nghttp2_stream * NGHTTP2_EXTERN nghttp2_stream *
nghttp2_stream_get_first_child(nghttp2_stream *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 * Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of * prioritization scheme.
* 2024, this function will always return
* :macro:`NGHTTP2_DEFAULT_WEIGHT`.
* *
* 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); 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 * Deprecated. :rfc:`7540` priorities are deprecated by
* :rfc:`9113`. Consider migrating to :rfc:`9218` extensible * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
* prioritization scheme. In the future release after the end of * prioritization scheme.
* 2024, this function will always return 0.
* *
* Returns the sum of the weight for |stream|'s children. * This function always returns 0.
*/ */
NGHTTP2_EXTERN int32_t NGHTTP2_EXTERN int32_t
nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream); 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 && if (!trailer &&
/* Do not parse the header field in PUSH_PROMISE. */ /* Do not parse the header field in PUSH_PROMISE. */
(stream->stream_id & 1) && (stream->stream_id & 1) &&
(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) &&
!(stream->http_flags & NGHTTP2_HTTP_FLAG_BAD_PRIORITY)) { !(stream->http_flags & NGHTTP2_HTTP_FLAG_BAD_PRIORITY)) {
nghttp2_extpri_from_uint8(&extpri, stream->http_extpri); nghttp2_extpri_from_uint8(&extpri, stream->http_extpri);
if (nghttp2_http_parse_priority(&extpri, nv->value->base, 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. */ preface handling. */
extern int nghttp2_enable_strict_preface; extern int nghttp2_enable_strict_preface;
extern nghttp2_stream root;
/* /*
* Option flags. * Option flags.
*/ */
@@ -89,10 +91,6 @@ typedef struct {
/* The default maximum number of incoming reserved streams */ /* The default maximum number of incoming reserved streams */
#define NGHTTP2_MAX_INCOMING_RESERVED_STREAMS 200 #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 /* The maximum number of items in outbound queue, which is considered
as flooding caused by peer. All frames are not considered here. as flooding caused by peer. All frames are not considered here.
We only consider PING + ACK and SETTINGS + ACK. This is because 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 { struct nghttp2_session {
nghttp2_map /* <nghttp2_stream*> */ streams; nghttp2_map /* <nghttp2_stream*> */ streams;
/* root of dependency tree*/
nghttp2_stream root;
/* Queue for outbound urgent frames (PING and SETTINGS) */ /* Queue for outbound urgent frames (PING and SETTINGS) */
nghttp2_outbound_queue ob_urgent; nghttp2_outbound_queue ob_urgent;
/* Queue for non-DATA frames */ /* Queue for non-DATA frames */
@@ -229,20 +225,6 @@ struct nghttp2_session {
/* Memory allocator */ /* Memory allocator */
nghttp2_mem mem; nghttp2_mem mem;
void *user_data; 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 /* Queue of In-flight SETTINGS values. SETTINGS bearing ACK is not
considered as in-flight. */ considered as in-flight. */
nghttp2_inflight_settings *inflight_settings_head; nghttp2_inflight_settings *inflight_settings_head;
@@ -276,10 +258,9 @@ struct nghttp2_session {
|closed_stream_head|. The current implementation only keeps |closed_stream_head|. The current implementation only keeps
incoming streams and session is initialized as server. */ incoming streams and session is initialized as server. */
size_t num_closed_streams; size_t num_closed_streams;
/* The number of idle streams kept in |streams| hash. The idle /* The number of idle streams kept in |streams| hash. The current
streams can be accessed through doubly linked list implementation only keeps idle streams if session is initialized
|idle_stream_head|. The current implementation only keeps idle as server. */
streams if session is initialized as server. */
size_t num_idle_streams; size_t num_idle_streams;
/* The number of bytes allocated for nvbuf */ /* The number of bytes allocated for nvbuf */
size_t nvbuflen; 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 * This function returns a pointer to created new stream object, or
* NULL. * 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, nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
int32_t stream_id, uint8_t flags, int32_t stream_id, uint8_t flags,
nghttp2_priority_spec *pri_spec,
nghttp2_stream_state initial_state, nghttp2_stream_state initial_state,
void *stream_user_data); 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, * is indicated by the |error_code|. When closing the stream,
* on_stream_close_callback will be called. * 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 * This function returns 0 if it succeeds, or one the following
* negative error codes: * negative error codes:
* *
@@ -565,64 +535,10 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
/* /*
* Deletes |stream| from memory. After this function returns, stream * Deletes |stream| from memory. After this function returns, stream
* cannot be accessed. * 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, void nghttp2_session_destroy_stream(nghttp2_session *session,
nghttp2_stream *stream); 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);
/* /*
* If further receptions and transmissions over the stream |stream_id| * If further receptions and transmissions over the stream |stream_id|
* are disallowed, close the stream with error code NGHTTP2_NO_ERROR. * are disallowed, close the stream with error code NGHTTP2_NO_ERROR.
@@ -915,24 +831,6 @@ int nghttp2_session_update_local_settings(nghttp2_session *session,
nghttp2_settings_entry *iv, nghttp2_settings_entry *iv,
size_t niv); 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| * Terminates current |session| with the |error_code|. The |reason|
* is NULL-terminated debug string. * is NULL-terminated debug string.

View File

@@ -25,45 +25,17 @@
#include "nghttp2_stream.h" #include "nghttp2_stream.h"
#include <assert.h> #include <assert.h>
#include <stdio.h>
#include "nghttp2_session.h" #include "nghttp2_session.h"
#include "nghttp2_helper.h" #include "nghttp2_helper.h"
#include "nghttp2_debug.h" #include "nghttp2_debug.h"
#include "nghttp2_frame.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, void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
uint8_t flags, nghttp2_stream_state initial_state, 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, int32_t local_initial_window_size,
void *stream_user_data, nghttp2_mem *mem) { void *stream_user_data) {
nghttp2_pq_init(&stream->obq, stream_less, mem);
stream->stream_id = stream_id; stream->stream_id = stream_id;
stream->flags = flags; stream->flags = flags;
stream->state = initial_state; stream->state = initial_state;
@@ -77,428 +49,36 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
stream->recv_reduction = 0; stream->recv_reduction = 0;
stream->window_update_queued = 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->closed_next = NULL;
stream->weight = weight;
stream->sum_dep_weight = 0;
stream->http_flags = NGHTTP2_HTTP_FLAG_NONE; stream->http_flags = NGHTTP2_HTTP_FLAG_NONE;
stream->content_length = -1; stream->content_length = -1;
stream->recv_content_length = 0; stream->recv_content_length = 0;
stream->status_code = -1; stream->status_code = -1;
stream->queued = 0; stream->queued = 0;
stream->descendant_last_cycle = 0;
stream->cycle = 0; stream->cycle = 0;
stream->pending_penalty = 0; stream->pending_penalty = 0;
stream->descendant_next_seq = 0;
stream->seq = 0; stream->seq = 0;
stream->last_writelen = 0; stream->last_writelen = 0;
stream->extpri = stream->http_extpri = NGHTTP2_EXTPRI_DEFAULT_URGENCY; stream->extpri = stream->http_extpri = NGHTTP2_EXTPRI_DEFAULT_URGENCY;
} }
void nghttp2_stream_free(nghttp2_stream *stream) { void nghttp2_stream_free(nghttp2_stream *stream) { (void)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_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag) { void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag) {
stream->shut_flags = (uint8_t)(stream->shut_flags | flag); stream->shut_flags = (uint8_t)(stream->shut_flags | flag);
} }
/* void nghttp2_stream_attach_item(nghttp2_stream *stream,
* 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) { nghttp2_outbound_item *item) {
int rv;
assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0); assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0);
assert(stream->item == NULL); assert(stream->item == NULL);
DEBUGF("stream: stream=%d attach item=%p\n", stream->stream_id, item); DEBUGF("stream: stream=%d attach item=%p\n", stream->stream_id, item);
stream->item = 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) { void nghttp2_stream_detach_item(nghttp2_stream *stream) {
@@ -506,12 +86,6 @@ void nghttp2_stream_detach_item(nghttp2_stream *stream) {
stream->item = NULL; stream->item = NULL;
stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL); 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) { 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->item, flags);
stream->flags |= flags; stream->flags |= flags;
if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
return;
} }
stream_update_dep_on_detach_item(stream); void nghttp2_stream_resume_deferred_item(nghttp2_stream *stream,
} uint8_t flags) {
int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags) {
assert(stream->item); assert(stream->item);
DEBUGF("stream: stream=%d resume item=%p flags=%02x\n", stream->stream_id, DEBUGF("stream: stream=%d resume item=%p flags=%02x\n", stream->stream_id,
stream->item, flags); stream->item, flags);
stream->flags = (uint8_t)(stream->flags & ~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) { 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); 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) { 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) { if (stream->flags & NGHTTP2_STREAM_FLAG_CLOSED) {
return NGHTTP2_STREAM_STATE_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) { 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) { 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) { 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) { 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) { 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) { 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) { 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 /* bitwise OR of NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and
NGHTTP2_STREAM_FLAG_DEFERRED_USER. */ NGHTTP2_STREAM_FLAG_DEFERRED_USER. */
NGHTTP2_STREAM_FLAG_DEFERRED_ALL = 0x0c, 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. */ /* Ignore client RFC 9218 priority signal. */
NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES = 0x20, NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES = 0x20,
/* Indicates that RFC 9113 leading and trailing white spaces /* Indicates that RFC 9113 leading and trailing white spaces
@@ -146,39 +143,18 @@ typedef enum {
} nghttp2_http_flag; } nghttp2_http_flag;
struct nghttp2_stream { struct nghttp2_stream {
/* Entry for dep_prev->obq */ nghttp2_stream_state state;
nghttp2_pq_entry pq_entry; 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. */ /* Content-Length of request/response body. -1 if unknown. */
int64_t content_length; int64_t content_length;
/* Received body so far */ /* Received body so far */
int64_t recv_content_length; int64_t recv_content_length;
/* Base last_cycle for direct descendent streams. */
uint64_t descendant_last_cycle;
/* Next scheduled time to sent item */ /* Next scheduled time to sent item */
uint64_t cycle; 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 /* Secondary key for prioritization to break a tie for cycle. This
value is monotonically increased for single parent stream. */ value is monotonically increased for single parent stream. */
uint64_t seq; uint64_t seq;
/* pointers to form dependency tree. If multiple streams depend on nghttp2_stream *closed_next;
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;
/* The arbitrary data provided by user for this stream. */ /* The arbitrary data provided by user for this stream. */
void *stream_user_data; void *stream_user_data;
/* Item to send */ /* Item to send */
@@ -205,13 +181,8 @@ struct nghttp2_stream {
NGHTTP2_INITIAL_WINDOW_SIZE and could be increased/decreased by NGHTTP2_INITIAL_WINDOW_SIZE and could be increased/decreased by
submitting WINDOW_UPDATE. See nghttp2_submit_window_update(). */ submitting WINDOW_UPDATE. See nghttp2_submit_window_update(). */
int32_t local_window_size; int32_t local_window_size;
/* weight of this stream */
int32_t weight;
/* This is unpaid penalty (offset) when calculating cycle. */ /* This is unpaid penalty (offset) when calculating cycle. */
uint32_t pending_penalty; uint32_t pending_penalty;
/* sum of weight of direct descendants */
int32_t sum_dep_weight;
nghttp2_stream_state state;
/* status code from remote server */ /* status code from remote server */
int16_t status_code; int16_t status_code;
/* Bitwise OR of zero or more nghttp2_http_flag values */ /* 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, void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
uint8_t flags, nghttp2_stream_state initial_state, 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, int32_t local_initial_window_size,
void *stream_user_data, nghttp2_mem *mem); void *stream_user_data);
void nghttp2_stream_free(nghttp2_stream *stream); 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 * NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and given masks are
* cleared if they are set. So even if this function is called, if * cleared if they are set. So even if this function is called, if
* one of flag is still set, data does not become active. * 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. * Returns nonzero if item is deferred by whatever reason.
@@ -317,56 +282,10 @@ int nghttp2_stream_update_local_initial_window_size(
*/ */
void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream); 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|. * 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, void nghttp2_stream_attach_item(nghttp2_stream *stream,
nghttp2_outbound_item *item); nghttp2_outbound_item *item);
/* /*
@@ -375,66 +294,4 @@ int nghttp2_stream_attach_item(nghttp2_stream *stream,
*/ */
void nghttp2_stream_detach_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 */ #endif /* NGHTTP2_STREAM */

View File

@@ -32,42 +32,12 @@
#include "nghttp2_helper.h" #include "nghttp2_helper.h"
#include "nghttp2_priority_spec.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 /* This function takes ownership of |nva_copy|. Regardless of the
return value, the caller must not free |nva_copy| after this return value, the caller must not free |nva_copy| after this
function returns. */ function returns. */
static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags, static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags,
int32_t stream_id, int32_t stream_id, nghttp2_nv *nva_copy,
const nghttp2_priority_spec *pri_spec, size_t nvlen,
nghttp2_nv *nva_copy, size_t nvlen,
const nghttp2_data_provider_wrap *dpw, const nghttp2_data_provider_wrap *dpw,
void *stream_user_data) { void *stream_user_data) {
int rv; int rv;
@@ -114,8 +84,8 @@ static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags,
frame = &item->frame; frame = &item->frame;
nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat, nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat, NULL,
pri_spec, nva_copy, nvlen); nva_copy, nvlen);
rv = nghttp2_session_add_item(session, item); rv = nghttp2_session_add_item(session, item);
@@ -141,31 +111,22 @@ fail2:
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_nv *nva, size_t nvlen, const nghttp2_nv *nva, size_t nvlen,
const nghttp2_data_provider_wrap *dpw, const nghttp2_data_provider_wrap *dpw,
void *stream_user_data) { void *stream_user_data) {
int rv; int rv;
nghttp2_nv *nva_copy; nghttp2_nv *nva_copy;
nghttp2_priority_spec copy_pri_spec;
nghttp2_mem *mem; nghttp2_mem *mem;
mem = &session->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); rv = nghttp2_nv_array_copy(&nva_copy, nva, nvlen, mem);
if (rv < 0) { if (rv < 0) {
return rv; return rv;
} }
return submit_headers_shared(session, flags, stream_id, &copy_pri_spec, return submit_headers_shared(session, flags, stream_id, nva_copy, nvlen, dpw,
nva_copy, nvlen, dpw, stream_user_data); stream_user_data);
} }
int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id, 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 NGHTTP2_ERR_INVALID_ARGUMENT;
} }
return (int)submit_headers_shared_nva( return (int)submit_headers_shared_nva(session, NGHTTP2_FLAG_END_STREAM,
session, NGHTTP2_FLAG_END_STREAM, stream_id, NULL, nva, nvlen, NULL, NULL); stream_id, nva, nvlen, NULL, NULL);
} }
int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags, 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_priority_spec *pri_spec,
const nghttp2_nv *nva, size_t nvlen, const nghttp2_nv *nva, size_t nvlen,
void *stream_user_data) { void *stream_user_data) {
int rv; (void)pri_spec;
if (stream_id == -1) { if (stream_id == -1) {
if (session->server) { if (session->server) {
@@ -195,20 +156,8 @@ int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
flags &= NGHTTP2_FLAG_END_STREAM; flags &= NGHTTP2_FLAG_END_STREAM;
if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) && return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, NULL,
session->remote_settings.no_rfc7540_priorities != 1) { stream_user_data);
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);
} }
int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags, 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, int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
int32_t stream_id, int32_t stream_id,
const nghttp2_priority_spec *pri_spec) { const nghttp2_priority_spec *pri_spec) {
int rv; (void)session;
nghttp2_outbound_item *item;
nghttp2_frame *frame;
nghttp2_priority_spec copy_pri_spec;
nghttp2_mem *mem;
(void)flags; (void)flags;
(void)stream_id;
mem = &session->mem; (void)pri_spec;
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;
}
return 0; return 0;
} }
@@ -738,46 +646,29 @@ fail_item_malloc:
return rv; return rv;
} }
static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec, static uint8_t set_request_flags(const nghttp2_data_provider_wrap *dpw) {
const nghttp2_data_provider_wrap *dpw) {
uint8_t flags = NGHTTP2_FLAG_NONE; uint8_t flags = NGHTTP2_FLAG_NONE;
if (dpw == NULL || dpw->data_prd.read_callback == NULL) { if (dpw == NULL || dpw->data_prd.read_callback == NULL) {
flags |= NGHTTP2_FLAG_END_STREAM; flags |= NGHTTP2_FLAG_END_STREAM;
} }
if (pri_spec) {
flags |= NGHTTP2_FLAG_PRIORITY;
}
return flags; return flags;
} }
static int32_t submit_request_shared(nghttp2_session *session, static int32_t submit_request_shared(nghttp2_session *session,
const nghttp2_priority_spec *pri_spec,
const nghttp2_nv *nva, size_t nvlen, const nghttp2_nv *nva, size_t nvlen,
const nghttp2_data_provider_wrap *dpw, const nghttp2_data_provider_wrap *dpw,
void *stream_user_data) { void *stream_user_data) {
uint8_t flags; uint8_t flags;
int rv;
if (session->server) { if (session->server) {
return NGHTTP2_ERR_PROTO; return NGHTTP2_ERR_PROTO;
} }
if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) && flags = set_request_flags(dpw);
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(pri_spec, dpw); return submit_headers_shared_nva(session, flags, -1, nva, nvlen, dpw,
stream_user_data);
return submit_headers_shared_nva(session, flags, -1, pri_spec, nva, nvlen,
dpw, stream_user_data);
} }
int32_t nghttp2_submit_request(nghttp2_session *session, 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, const nghttp2_data_provider *data_prd,
void *stream_user_data) { void *stream_user_data) {
nghttp2_data_provider_wrap dpw; 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), nghttp2_data_provider_wrap_v1(&dpw, data_prd),
stream_user_data); stream_user_data);
} }
@@ -798,8 +690,9 @@ int32_t nghttp2_submit_request2(nghttp2_session *session,
const nghttp2_data_provider2 *data_prd, const nghttp2_data_provider2 *data_prd,
void *stream_user_data) { void *stream_user_data) {
nghttp2_data_provider_wrap dpw; 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), nghttp2_data_provider_wrap_v2(&dpw, data_prd),
stream_user_data); stream_user_data);
} }
@@ -826,8 +719,8 @@ static int submit_response_shared(nghttp2_session *session, int32_t stream_id,
} }
flags = set_response_flags(dpw); flags = set_response_flags(dpw);
return submit_headers_shared_nva(session, flags, stream_id, NULL, nva, nvlen, return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, dpw,
dpw, NULL); NULL);
} }
int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id, 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_response_headers_received)
munit_void_test_decl(test_nghttp2_session_on_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_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_rst_stream_received)
munit_void_test_decl(test_nghttp2_session_on_settings_received) munit_void_test_decl(test_nghttp2_session_on_settings_received)
munit_void_test_decl(test_nghttp2_session_on_push_promise_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_send_push_promise)
munit_void_test_decl(test_nghttp2_session_is_my_stream_id) 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_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)
munit_void_test_decl(test_nghttp2_submit_data_read_length_too_large) munit_void_test_decl(test_nghttp2_submit_data_read_length_too_large)
munit_void_test_decl(test_nghttp2_submit_data_read_length_smallest) 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)
munit_void_test_decl(test_nghttp2_submit_headers_continuation) 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_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)
munit_void_test_decl(test_nghttp2_submit_settings_update_local_window_size) munit_void_test_decl(test_nghttp2_submit_settings_update_local_window_size)
munit_void_test_decl(test_nghttp2_submit_settings_multiple_times) 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_priority_update)
munit_void_test_decl(test_nghttp2_submit_rst_stream) 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)
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_get_next_ob_item)
munit_void_test_decl(test_nghttp2_session_pop_next_ob_item) munit_void_test_decl(test_nghttp2_session_pop_next_ob_item)
munit_void_test_decl(test_nghttp2_session_reply_fail) 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_data_with_padding)
munit_void_test_decl(test_nghttp2_session_pack_headers_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_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_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_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_graceful_shutdown)
munit_void_test_decl(test_nghttp2_session_on_header_temporal_failure) munit_void_test_decl(test_nghttp2_session_on_header_temporal_failure)
munit_void_test_decl(test_nghttp2_session_recv_client_magic) 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_defer_then_close)
munit_void_test_decl(test_nghttp2_session_detach_item_from_closed_stream) 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_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_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_set_local_window_size)
munit_void_test_decl(test_nghttp2_session_cancel_from_before_frame_send) munit_void_test_decl(test_nghttp2_session_cancel_from_before_frame_send)
munit_void_test_decl(test_nghttp2_session_too_many_settings) 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_no_closed_streams)
munit_void_test_decl(test_nghttp2_session_set_stream_user_data) 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_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_session_stream_reset_ratelim)
munit_void_test_decl(test_nghttp2_http_mandatory_headers) munit_void_test_decl(test_nghttp2_http_mandatory_headers)
munit_void_test_decl(test_nghttp2_http_content_length) 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()); 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) { nghttp2_stream *open_stream(nghttp2_session *session, int32_t stream_id) {
return open_stream_with_all(session, stream_id, NGHTTP2_DEFAULT_WEIGHT, 0, return nghttp2_session_open_stream(
NULL); session, stream_id, NGHTTP2_STREAM_FLAG_NONE, NGHTTP2_STREAM_OPENED, 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);
} }
nghttp2_outbound_item *create_data_ob_item(nghttp2_mem *mem) { 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_stream *open_sent_stream(nghttp2_session *session, int32_t stream_id) {
nghttp2_priority_spec pri_spec; return open_sent_stream3(session, stream_id, NGHTTP2_FLAG_NONE,
nghttp2_priority_spec_init(&pri_spec, 0, NGHTTP2_DEFAULT_WEIGHT, 0);
return open_sent_stream3(session, stream_id, NGHTTP2_FLAG_NONE, &pri_spec,
NGHTTP2_STREAM_OPENED, NULL); NGHTTP2_STREAM_OPENED, NULL);
} }
nghttp2_stream *open_sent_stream2(nghttp2_session *session, int32_t stream_id, nghttp2_stream *open_sent_stream2(nghttp2_session *session, int32_t stream_id,
nghttp2_stream_state initial_state) { nghttp2_stream_state initial_state) {
nghttp2_priority_spec pri_spec; return open_sent_stream3(session, stream_id, NGHTTP2_FLAG_NONE, initial_state,
NULL);
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);
} }
nghttp2_stream *open_sent_stream3(nghttp2_session *session, int32_t stream_id, nghttp2_stream *open_sent_stream3(nghttp2_session *session, int32_t stream_id,
uint8_t flags, uint8_t flags,
nghttp2_priority_spec *pri_spec_in,
nghttp2_stream_state initial_state, nghttp2_stream_state initial_state,
void *stream_user_data) { void *stream_user_data) {
nghttp2_stream *stream; nghttp2_stream *stream;
assert(nghttp2_session_is_my_stream_id(session, stream_id)); assert(nghttp2_session_is_my_stream_id(session, stream_id));
stream = nghttp2_session_open_stream(session, stream_id, flags, pri_spec_in, stream = nghttp2_session_open_stream(session, stream_id, flags, initial_state,
initial_state, stream_user_data); 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);
session->last_sent_stream_id = session->last_sent_stream_id =
nghttp2_max_int32(session->last_sent_stream_id, stream_id); nghttp2_max_int32(session->last_sent_stream_id, stream_id);
session->next_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_stream *open_recv_stream(nghttp2_session *session, int32_t stream_id) {
nghttp2_priority_spec pri_spec; return open_recv_stream3(session, stream_id, NGHTTP2_FLAG_NONE,
nghttp2_priority_spec_init(&pri_spec, 0, NGHTTP2_DEFAULT_WEIGHT, 0);
return open_recv_stream3(session, stream_id, NGHTTP2_FLAG_NONE, &pri_spec,
NGHTTP2_STREAM_OPENED, NULL); NGHTTP2_STREAM_OPENED, NULL);
} }
nghttp2_stream *open_recv_stream2(nghttp2_session *session, int32_t stream_id, nghttp2_stream *open_recv_stream2(nghttp2_session *session, int32_t stream_id,
nghttp2_stream_state initial_state) { nghttp2_stream_state initial_state) {
nghttp2_priority_spec pri_spec; return open_recv_stream3(session, stream_id, NGHTTP2_FLAG_NONE, initial_state,
NULL);
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);
} }
nghttp2_stream *open_recv_stream3(nghttp2_session *session, int32_t stream_id, nghttp2_stream *open_recv_stream3(nghttp2_session *session, int32_t stream_id,
uint8_t flags, uint8_t flags,
nghttp2_priority_spec *pri_spec_in,
nghttp2_stream_state initial_state, nghttp2_stream_state initial_state,
void *stream_user_data) { void *stream_user_data) {
nghttp2_stream *stream; nghttp2_stream *stream;
assert(!nghttp2_session_is_my_stream_id(session, stream_id)); assert(!nghttp2_session_is_my_stream_id(session, stream_id));
stream = nghttp2_session_open_stream(session, stream_id, flags, pri_spec_in, stream = nghttp2_session_open_stream(session, stream_id, flags, initial_state,
initial_state, stream_user_data); 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);
session->last_recv_stream_id = session->last_recv_stream_id =
nghttp2_max_int32(session->last_recv_stream_id, 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(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); nghttp2_outbound_item *create_data_ob_item(nghttp2_mem *mem);
/* Opens stream. This stream is assumed to be sent from |session|, /* 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, nghttp2_stream *open_sent_stream3(nghttp2_session *session, int32_t stream_id,
uint8_t flags, uint8_t flags,
nghttp2_priority_spec *pri_spec_in,
nghttp2_stream_state initial_state, nghttp2_stream_state initial_state,
void *stream_user_data); 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|, /* Opens stream. This stream is assumed to be received by |session|,
and session->last_recv_stream_id will be adjusted accordingly. */ and session->last_recv_stream_id will be adjusted accordingly. */
nghttp2_stream *open_recv_stream(nghttp2_session *session, int32_t stream_id); 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, nghttp2_stream *open_recv_stream3(nghttp2_session *session, int32_t stream_id,
uint8_t flags, uint8_t flags,
nghttp2_priority_spec *pri_spec_in,
nghttp2_stream_state initial_state, nghttp2_stream_state initial_state,
void *stream_user_data); 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 */ #endif /* NGHTTP2_TEST_HELPER_H */