Merge branch 'master' into simple-extensions

This commit is contained in:
Tatsuhiro Tsujikawa 2016-01-11 16:39:35 +09:00
commit e14da859b6
14 changed files with 572 additions and 370 deletions

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText. .\" Man page generated from reStructuredText.
. .
.TH "H2LOAD" "1" "December 23, 2015" "1.6.0" "nghttp2" .TH "H2LOAD" "1" "January 11, 2016" "1.6.1-DEV" "nghttp2"
.SH NAME .SH NAME
h2load \- HTTP/2 benchmarking tool h2load \- HTTP/2 benchmarking tool
. .
@ -88,11 +88,12 @@ scheme, host or port values.
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-m, \-\-max\-concurrent\-streams=(auto|<N>) .B \-m, \-\-max\-concurrent\-streams=<N>
Max concurrent streams to issue per session. If "auto" Max concurrent streams to issue per session. When
is given, the number of given URIs is used. http/1.1 is used, this specifies the number of HTTP
pipelining requests in\-flight.
.sp .sp
Default: \fBauto\fP Default: \fB1\fP
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
@ -410,6 +411,6 @@ window size described in HTTP/2 and SPDY protocol specification.
.SH AUTHOR .SH AUTHOR
Tatsuhiro Tsujikawa Tatsuhiro Tsujikawa
.SH COPYRIGHT .SH COPYRIGHT
2012, 2015, Tatsuhiro Tsujikawa 2012, 2015, 2016, Tatsuhiro Tsujikawa
.\" Generated by docutils manpage writer. .\" Generated by docutils manpage writer.
. .

View File

@ -63,12 +63,13 @@ OPTIONS
are used solely. Definition of a base URI overrides all are used solely. Definition of a base URI overrides all
scheme, host or port values. scheme, host or port values.
.. option:: -m, --max-concurrent-streams=(auto|<N>) .. option:: -m, --max-concurrent-streams=<N>
Max concurrent streams to issue per session. If "auto" Max concurrent streams to issue per session. When
is given, the number of given URIs is used. http/1.1 is used, this specifies the number of HTTP
pipelining requests in-flight.
Default: ``auto`` Default: ``1``
.. option:: -w, --window-bits=<N> .. option:: -w, --window-bits=<N>

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText. .\" Man page generated from reStructuredText.
. .
.TH "NGHTTP" "1" "December 23, 2015" "1.6.0" "nghttp2" .TH "NGHTTP" "1" "January 11, 2016" "1.6.1-DEV" "nghttp2"
.SH NAME .SH NAME
nghttp \- HTTP/2 client nghttp \- HTTP/2 client
. .
@ -296,6 +296,6 @@ on stream 11 with the weight 2.
.SH AUTHOR .SH AUTHOR
Tatsuhiro Tsujikawa Tatsuhiro Tsujikawa
.SH COPYRIGHT .SH COPYRIGHT
2012, 2015, Tatsuhiro Tsujikawa 2012, 2015, 2016, Tatsuhiro Tsujikawa
.\" Generated by docutils manpage writer. .\" Generated by docutils manpage writer.
. .

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText. .\" Man page generated from reStructuredText.
. .
.TH "NGHTTPD" "1" "December 23, 2015" "1.6.0" "nghttp2" .TH "NGHTTPD" "1" "January 11, 2016" "1.6.1-DEV" "nghttp2"
.SH NAME .SH NAME
nghttpd \- HTTP/2 server nghttpd \- HTTP/2 server
. .
@ -180,6 +180,11 @@ Default: \fB/etc/mime.types\fP
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-no\-content\-length
Don\(aqt send content\-length header field.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-version .B \-\-version
Display version information and exit. Display version information and exit.
.UNINDENT .UNINDENT
@ -197,6 +202,6 @@ The <SIZE> argument is an integer and an optional unit (e.g., 10K is
.SH AUTHOR .SH AUTHOR
Tatsuhiro Tsujikawa Tatsuhiro Tsujikawa
.SH COPYRIGHT .SH COPYRIGHT
2012, 2015, Tatsuhiro Tsujikawa 2012, 2015, 2016, Tatsuhiro Tsujikawa
.\" Generated by docutils manpage writer. .\" Generated by docutils manpage writer.
. .

View File

@ -139,6 +139,10 @@ OPTIONS
Default: ``/etc/mime.types`` Default: ``/etc/mime.types``
.. option:: --no-content-length
Don't send content-length header field.
.. option:: --version .. option:: --version
Display version information and exit. Display version information and exit.

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText. .\" Man page generated from reStructuredText.
. .
.TH "NGHTTPX" "1" "December 23, 2015" "1.6.0" "nghttp2" .TH "NGHTTPX" "1" "January 11, 2016" "1.6.1-DEV" "nghttp2"
.SH NAME .SH NAME
nghttpx \- HTTP/2 proxy nghttpx \- HTTP/2 proxy
. .
@ -896,8 +896,8 @@ Example: \fI\%\-\-add\-response\-header\fP="foo: bar"
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-header\-field\-buffer=<SIZE> .B \-\-header\-field\-buffer=<SIZE>
Set maximum buffer size for incoming HTTP header field Set maximum buffer size for incoming HTTP request header
list. This is the sum of header name and value in field list. This is the sum of header name and value in
bytes. bytes.
.sp .sp
Default: \fB64K\fP Default: \fB64K\fP
@ -905,8 +905,9 @@ Default: \fB64K\fP
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-max\-header\-fields=<N> .B \-\-max\-header\-fields=<N>
Set maximum number of incoming HTTP header fields, which Set maximum number of incoming HTTP request header
appear in one request or response header field list. fields, which appear in one request or response header
field list.
.sp .sp
Default: \fB100\fP Default: \fB100\fP
.UNINDENT .UNINDENT
@ -1458,6 +1459,6 @@ App.new
.SH AUTHOR .SH AUTHOR
Tatsuhiro Tsujikawa Tatsuhiro Tsujikawa
.SH COPYRIGHT .SH COPYRIGHT
2012, 2015, Tatsuhiro Tsujikawa 2012, 2015, 2016, Tatsuhiro Tsujikawa
.\" Generated by docutils manpage writer. .\" Generated by docutils manpage writer.
. .

View File

@ -797,16 +797,17 @@ HTTP
.. option:: --header-field-buffer=<SIZE> .. option:: --header-field-buffer=<SIZE>
Set maximum buffer size for incoming HTTP header field Set maximum buffer size for incoming HTTP request header
list. This is the sum of header name and value in field list. This is the sum of header name and value in
bytes. bytes.
Default: ``64K`` Default: ``64K``
.. option:: --max-header-fields=<N> .. option:: --max-header-fields=<N>
Set maximum number of incoming HTTP header fields, which Set maximum number of incoming HTTP request header
appear in one request or response header field list. fields, which appear in one request or response header
field list.
Default: ``100`` Default: ``100``

View File

@ -3299,6 +3299,8 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
* Trying to depend on itself (new stream ID equals * Trying to depend on itself (new stream ID equals
* ``pri_spec->stream_id``). * ``pri_spec->stream_id``).
* :enum:`NGHTTP2_ERR_PROTO`
* The |session| is server session.
* *
* .. warning:: * .. warning::
* *
@ -3371,6 +3373,8 @@ nghttp2_submit_request(nghttp2_session *session,
* processed yet. Normally, this does not happen, but when * processed yet. Normally, this does not happen, but when
* application wrongly calls `nghttp2_submit_response()` twice, * application wrongly calls `nghttp2_submit_response()` twice,
* this may happen. * this may happen.
* :enum:`NGHTTP2_ERR_PROTO`
* The |session| is client session.
* *
* .. warning:: * .. warning::
* *
@ -3515,6 +3519,8 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
* 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|
* is in reserved state. * is in reserved state.
* :enum:`NGHTTP2_ERR_PROTO`
* The |stream_id| is -1, and |session| is server session.
* *
* .. warning:: * .. warning::
* *

View File

@ -130,7 +130,7 @@ static int session_detect_idle_stream(nghttp2_session *session,
int32_t stream_id) { int32_t stream_id) {
/* Assume that stream object with stream_id does not exist */ /* Assume that stream object with stream_id does not exist */
if (nghttp2_session_is_my_stream_id(session, stream_id)) { if (nghttp2_session_is_my_stream_id(session, stream_id)) {
if (session->next_stream_id <= (uint32_t)stream_id) { if (session->sent_stream_id < stream_id) {
return 1; return 1;
} }
return 0; return 0;
@ -1379,7 +1379,9 @@ static int session_predicate_request_headers_send(nghttp2_session *session,
* NGHTTP2_ERR_INVALID_STREAM_STATE * NGHTTP2_ERR_INVALID_STREAM_STATE
* The state of the stream is not valid. * The state of the stream is not valid.
* NGHTTP2_ERR_SESSION_CLOSING * NGHTTP2_ERR_SESSION_CLOSING
* This session is closing. * This session is closing.
* NGHTTP2_ERR_PROTO
* Client side attempted to send response.
*/ */
static int session_predicate_response_headers_send(nghttp2_session *session, static int session_predicate_response_headers_send(nghttp2_session *session,
nghttp2_stream *stream) { nghttp2_stream *stream) {
@ -1389,6 +1391,9 @@ static int session_predicate_response_headers_send(nghttp2_session *session,
return rv; return rv;
} }
assert(stream); assert(stream);
if (!session->server) {
return NGHTTP2_ERR_PROTO;
}
if (nghttp2_session_is_my_stream_id(session, stream->stream_id)) { if (nghttp2_session_is_my_stream_id(session, stream->stream_id)) {
return NGHTTP2_ERR_INVALID_STREAM_ID; return NGHTTP2_ERR_INVALID_STREAM_ID;
} }
@ -1422,6 +1427,8 @@ static int session_predicate_response_headers_send(nghttp2_session *session,
* NGHTTP2_ERR_START_STREAM_NOT_ALLOWED * NGHTTP2_ERR_START_STREAM_NOT_ALLOWED
* New stream cannot be created because GOAWAY is already sent or * New stream cannot be created because GOAWAY is already sent or
* received. * received.
* NGHTTP2_ERR_PROTO
* Client side attempted to send push response.
*/ */
static int static int
session_predicate_push_response_headers_send(nghttp2_session *session, session_predicate_push_response_headers_send(nghttp2_session *session,
@ -1433,6 +1440,9 @@ session_predicate_push_response_headers_send(nghttp2_session *session,
return rv; return rv;
} }
assert(stream); assert(stream);
if (!session->server) {
return NGHTTP2_ERR_PROTO;
}
if (stream->state != NGHTTP2_STREAM_RESERVED) { if (stream->state != NGHTTP2_STREAM_RESERVED) {
return NGHTTP2_ERR_PROTO; return NGHTTP2_ERR_PROTO;
} }
@ -1901,6 +1911,11 @@ static int session_prep_frame(nghttp2_session *session,
DEBUGF(fprintf(stderr, "send: HEADERS finally serialized in %zd bytes\n", DEBUGF(fprintf(stderr, "send: HEADERS finally serialized in %zd bytes\n",
nghttp2_bufs_len(&session->aob.framebufs))); nghttp2_bufs_len(&session->aob.framebufs)));
if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
assert(session->sent_stream_id < frame->hd.stream_id);
session->sent_stream_id = frame->hd.stream_id;
}
break; break;
} }
case NGHTTP2_PRIORITY: { case NGHTTP2_PRIORITY: {
@ -1970,6 +1985,10 @@ static int session_prep_frame(nghttp2_session *session,
return rv; return rv;
} }
assert(session->sent_stream_id + 2 <=
frame->push_promise.promised_stream_id);
session->sent_stream_id = frame->push_promise.promised_stream_id;
break; break;
} }
case NGHTTP2_PING: case NGHTTP2_PING:
@ -3805,13 +3824,14 @@ int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO, return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
"RST_STREAM: stream_id == 0"); "RST_STREAM: stream_id == 0");
} }
if (session_detect_idle_stream(session, frame->hd.stream_id)) {
return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
"RST_STREAM: stream in idle");
}
stream = nghttp2_session_get_stream(session, frame->hd.stream_id); stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
if (!stream) { if (stream) {
if (session_detect_idle_stream(session, frame->hd.stream_id)) {
return session_handle_invalid_connection(
session, frame, NGHTTP2_ERR_PROTO, "RST_STREAM: stream in idle");
}
} else {
/* We may use stream->shut_flags for strict error checking. */ /* We may use stream->shut_flags for strict error checking. */
nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
} }
@ -4249,21 +4269,20 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session,
session, frame, NGHTTP2_ERR_PROTO, session, frame, NGHTTP2_ERR_PROTO,
"PUSH_PROMISE: invalid promised_stream_id"); "PUSH_PROMISE: invalid promised_stream_id");
} }
if (session_detect_idle_stream(session, frame->hd.stream_id)) {
return session_inflate_handle_invalid_connection(
session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream in idle");
}
session->last_recv_stream_id = frame->push_promise.promised_stream_id; session->last_recv_stream_id = frame->push_promise.promised_stream_id;
stream = nghttp2_session_get_stream(session, frame->hd.stream_id); stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
if (!stream || stream->state == NGHTTP2_STREAM_CLOSING || if (!stream || stream->state == NGHTTP2_STREAM_CLOSING ||
!session->pending_enable_push || !session->pending_enable_push ||
session->num_incoming_reserved_streams >= session->num_incoming_reserved_streams >=
session->max_incoming_reserved_streams) { session->max_incoming_reserved_streams) {
if (!stream) { /* Currently, client does not retain closed stream, so we don't
if (session_detect_idle_stream(session, frame->hd.stream_id)) { check NGHTTP2_SHUT_RD condition here. */
return session_inflate_handle_invalid_connection(
session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream in idle");
}
/* Currently, client does not retain closed stream, so we don't
check NGHTTP2_SHUT_RD condition here. */
}
rv = nghttp2_session_add_rst_stream( rv = nghttp2_session_add_rst_stream(
session, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL); session, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL);
@ -4415,12 +4434,14 @@ static int session_on_stream_window_update_received(nghttp2_session *session,
nghttp2_frame *frame) { nghttp2_frame *frame) {
int rv; int rv;
nghttp2_stream *stream; nghttp2_stream *stream;
if (session_detect_idle_stream(session, frame->hd.stream_id)) {
return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
"WINDOW_UPDATE to idle stream");
}
stream = nghttp2_session_get_stream(session, frame->hd.stream_id); stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
if (!stream) { if (!stream) {
if (session_detect_idle_stream(session, frame->hd.stream_id)) {
return session_handle_invalid_connection(
session, frame, NGHTTP2_ERR_PROTO, "WINDOW_UPDATE to idle stream");
}
return 0; return 0;
} }
if (state_reserved_remote(session, stream)) { if (state_reserved_remote(session, stream)) {
@ -4736,14 +4757,15 @@ static int session_on_data_received_fail_fast(nghttp2_session *session) {
failure_reason = "DATA: stream_id == 0"; failure_reason = "DATA: stream_id == 0";
goto fail; goto fail;
} }
if (session_detect_idle_stream(session, stream_id)) {
failure_reason = "DATA: stream in idle";
error_code = NGHTTP2_PROTOCOL_ERROR;
goto fail;
}
stream = nghttp2_session_get_stream(session, stream_id); stream = nghttp2_session_get_stream(session, stream_id);
if (!stream) { if (!stream) {
if (session_detect_idle_stream(session, stream_id)) {
failure_reason = "DATA: stream in idle";
error_code = NGHTTP2_PROTOCOL_ERROR;
goto fail;
}
stream = nghttp2_session_get_stream_raw(session, stream_id); stream = nghttp2_session_get_stream_raw(session, stream_id);
if (stream && (stream->shut_flags & NGHTTP2_SHUT_RD)) { if (stream && (stream->shut_flags & NGHTTP2_SHUT_RD)) {
failure_reason = "DATA: stream closed"; failure_reason = "DATA: stream closed";

View File

@ -247,6 +247,10 @@ struct nghttp2_session {
size_t obq_flood_counter_; size_t obq_flood_counter_;
/* Next Stream ID. Made unsigned int to detect >= (1 << 31). */ /* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
uint32_t next_stream_id; uint32_t next_stream_id;
/* The last stream ID this session initiated. For client session,
this is the last stream ID it has sent. For server session, it
is the last promised stream ID sent in PUSH_PROMISE. */
int32_t sent_stream_id;
/* The largest stream ID received so far */ /* The largest stream ID received so far */
int32_t last_recv_stream_id; int32_t last_recv_stream_id;
/* The largest stream ID which has been processed in some way. This /* The largest stream ID which has been processed in some way. This

View File

@ -32,6 +32,35 @@
#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. */
@ -50,21 +79,6 @@ static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags,
mem = &session->mem; mem = &session->mem;
if (stream_id == 0) {
rv = NGHTTP2_ERR_INVALID_ARGUMENT;
goto fail;
}
if (stream_id == -1) {
if ((int32_t)session->next_stream_id == pri_spec->stream_id) {
rv = NGHTTP2_ERR_INVALID_ARGUMENT;
goto fail;
}
} else if (stream_id == pri_spec->stream_id) {
rv = NGHTTP2_ERR_INVALID_ARGUMENT;
goto fail;
}
item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
if (item == NULL) { if (item == NULL) {
rv = NGHTTP2_ERR_NOMEM; rv = NGHTTP2_ERR_NOMEM;
@ -156,6 +170,10 @@ static int32_t submit_headers_shared_nva(nghttp2_session *session,
int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id, int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id,
const nghttp2_nv *nva, size_t nvlen) { const nghttp2_nv *nva, size_t nvlen) {
if (stream_id <= 0) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
return (int)submit_headers_shared_nva(session, NGHTTP2_FLAG_END_STREAM, return (int)submit_headers_shared_nva(session, NGHTTP2_FLAG_END_STREAM,
stream_id, NULL, nva, nvlen, NULL, stream_id, NULL, nva, nvlen, NULL,
NULL); NULL);
@ -166,9 +184,24 @@ 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;
if (stream_id == -1) {
if (session->server) {
return NGHTTP2_ERR_PROTO;
}
} else if (stream_id <= 0) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
flags &= NGHTTP2_FLAG_END_STREAM; flags &= NGHTTP2_FLAG_END_STREAM;
if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec)) { if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec)) {
rv = detect_self_dependency(session, stream_id, pri_spec);
if (rv != 0) {
return rv;
}
flags |= NGHTTP2_FLAG_PRIORITY; flags |= NGHTTP2_FLAG_PRIORITY;
} else { } else {
pri_spec = NULL; pri_spec = NULL;
@ -281,7 +314,7 @@ int32_t nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags _U_,
mem = &session->mem; mem = &session->mem;
if (stream_id == 0 || nghttp2_session_is_my_stream_id(session, stream_id)) { if (stream_id <= 0 || nghttp2_session_is_my_stream_id(session, stream_id)) {
return NGHTTP2_ERR_INVALID_ARGUMENT; return NGHTTP2_ERR_INVALID_ARGUMENT;
} }
@ -396,8 +429,18 @@ 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) {
uint8_t flags; uint8_t flags;
int rv;
if (pri_spec && nghttp2_priority_spec_check_default(pri_spec)) { if (session->server) {
return NGHTTP2_ERR_PROTO;
}
if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec)) {
rv = detect_self_dependency(session, -1, pri_spec);
if (rv != 0) {
return rv;
}
} else {
pri_spec = NULL; pri_spec = NULL;
} }
@ -418,7 +461,17 @@ static uint8_t set_response_flags(const nghttp2_data_provider *data_prd) {
int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id, int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
const nghttp2_nv *nva, size_t nvlen, const nghttp2_nv *nva, size_t nvlen,
const nghttp2_data_provider *data_prd) { const nghttp2_data_provider *data_prd) {
uint8_t flags = set_response_flags(data_prd); uint8_t flags;
if (stream_id <= 0) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
if (!session->server) {
return NGHTTP2_ERR_PROTO;
}
flags = set_response_flags(data_prd);
return submit_headers_shared_nva(session, flags, stream_id, NULL, nva, nvlen, return submit_headers_shared_nva(session, flags, stream_id, NULL, nva, nvlen,
data_prd, NULL); data_prd, NULL);
} }

File diff suppressed because it is too large Load Diff

View File

@ -306,3 +306,119 @@ nghttp2_outbound_item *create_data_ob_item(nghttp2_mem *mem) {
return item; return item;
} }
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,
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);
}
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->sent_stream_id = nghttp2_max(session->sent_stream_id, stream_id);
session->next_stream_id =
nghttp2_max(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->sent_stream_id = nghttp2_max(session->sent_stream_id, stream_id);
session->next_stream_id =
nghttp2_max(session->next_stream_id, (uint32_t)stream_id + 2);
return stream;
}
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,
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);
}
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(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 =
nghttp2_max(session->last_recv_stream_id, stream_id);
return stream;
}

View File

@ -110,4 +110,49 @@ nghttp2_stream *open_stream_with_dep_excl(nghttp2_session *session,
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|,
and session->sent_stream_id and session->next_stream_id will be
adjusted accordingly. */
nghttp2_stream *open_sent_stream(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 *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);
nghttp2_stream *open_recv_stream2(nghttp2_session *session, int32_t stream_id,
nghttp2_stream_state initial_state);
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 */ #endif /* NGHTTP2_TEST_HELPER_H */