Commit Graph

658 Commits

Author SHA1 Message Date
Tatsuhiro Tsujikawa 2288ee8060 Create stream object for pushed resource during nghttp2_submit_push_promise()
Previously, stream object for pushed resource was not created during
nghttp2_submit_push_promise().  It was created just before
nghttp2_before_frame_send_callback was called for that PUSH_PROMISE
frame.  This means that application could not call
nghttp2_submit_response for the pushed resource before
nghttp2_before_frame_send_callback was called.  This could be solved
by callback chaining, but for web server with back pressure from
backend stream, it is a bit unnecessarily hard to use.

This commit changes nghttp2_submit_push_promise() behaviour so that
stream object is created during that call.  It makes application call
nghttp2_submit_response right after successful
nghttp2_submit_push_promise call.
2015-12-02 21:16:30 +09:00
Tatsuhiro Tsujikawa 12b2e0a2b3 Add nghttp2_session_create_idle_stream() API
See GH-436
2015-11-28 15:23:44 +09:00
Tatsuhiro Tsujikawa a70445e122 Retain stream in reserved state on client side
Application may use it using nghttp2_stream_* functions, and traverse
its dependency.
2015-11-27 22:54:55 +09:00
Tatsuhiro Tsujikawa f23e34fa3c Handle response in nghttp2_on_begin_frame_callback
Previously, nghttp2_session_end_request_headers_received assumes
stream is still writable (in other words, local endpoint has not sent
END_STREAM).  But this assumption is false, because application can
send response in nghttp2_on_begin_frame_callback.  Probably, this
assumption was made before the callback was introduced.  This commit
addresses this issue.  Since all
nghttp2_session_end_*_headers_received functions are identical, we
refactored them into one function.
2015-11-27 22:50:13 +09:00
Tatsuhiro Tsujikawa 3048bb9d90 Fix test: stream_id is not incremented 2015-11-25 22:18:54 +09:00
Tatsuhiro Tsujikawa b08d5b1975 Explicitly treat stream_id 0 as error in nghttp2_session_change_stream_priority 2015-11-24 22:34:36 +09:00
Tatsuhiro Tsujikawa b53b1381b7 Fix bug that nghttp2_session_find_stream(session, 0) returned NULL
Previously, nghttp2_session_find_stream(session, 0) returned NULL
despite the fact that documentation said that it should return root
stream.  Now it is corrected, and it returns root stream as
documented.
2015-11-24 22:30:12 +09:00
Tatsuhiro Tsujikawa d62bc26b62 Add test for nghttp2_session_change_stream_priority() 2015-11-23 19:48:51 +09:00
Tatsuhiro Tsujikawa d7b0768ab8 Fix bug that dep_stream->sum_dep_weight was not updated 2015-11-20 21:24:54 +09:00
Tatsuhiro Tsujikawa 83cc2511e3 Remove flags parameter from nghttp2_pack_extension_callback
It has no usecase at the moment.  It is most likely that applications
know the flags when it submitted extension frame, no need to modify it
later.  Possibly feature bloat.
2015-11-17 21:29:21 +09:00
Tatsuhiro Tsujikawa b918f9650a Don't send push response if GOAWAY has been received 2015-11-16 22:47:12 +09:00
Tatsuhiro Tsujikawa 7463493259 Use error code CANCEL to reset pushed reserved stream from remote 2015-11-16 22:20:27 +09:00
Tatsuhiro Tsujikawa eb4e402aae Merge branch 'master' into simple-extensions 2015-11-14 22:31:52 +09:00
Tatsuhiro Tsujikawa c6ef1c02b9 Switch to clang-format-3.6 2015-11-13 00:53:29 +09:00
Tatsuhiro Tsujikawa 269a100081 Add nghttp2_session_upgrade2(), deprecate nghttp2_session_upgrade()
To validate actual response body length against the value declared in
content-length response header field, we first check request method.
If request method is HEAD, respose body must be 0 regardless of the
value in content-length.  nghttp2_session_upgrade() has no parameter
to indicate the request method is HEAD, so we failed to validate
response body if HEAD is used with HTTP Upgrade.  New
nghttp2_session_upgrade2() accepts new parameter to indicate that
request method is HEAD or not to fix this issue.  Although, this issue
affects client side only, we deprecate nghttp2_session_upgrade() in
favor of nghttp2_session_upgrade2() for both client and server side.
2015-11-07 16:13:06 +09:00
Tatsuhiro Tsujikawa af4c3cb2cf Fix travis gcc build 2015-11-07 11:34:05 +09:00
Tatsuhiro Tsujikawa 5e7e479c6c Workaround HTTP upgrade with HEAD request
By default, we check the length of response body matches
content-length.  For HEAD request, this is not necessarily true, so we
sniff request method, and if it is HEAD, make sure that response body
length is 0.  But this does not work for HTTP Upgrade, since
nghttp2_session_upgrade() has no parameter to tell the request method
was HEAD.  This commit disables this response body length validation
for the stream upgraded by HTTP Upgrade.  We will add new version of
nghttp2_session_upgrade with the parameter to pass the request method
information so that we can handle this situation properly.
2015-11-07 10:56:40 +09:00
Tatsuhiro Tsujikawa 5d611d2e24 Merge branch 'master' into simple-extensions 2015-10-29 23:24:34 +09:00
Kamil Dudka 4825009e42 tests: fix broken linkage with --disable-static 2015-10-26 20:33:36 +01:00
Tatsuhiro Tsujikawa 25bf567cd7 Don't always expect dynamic table size update
The encoder is not required to send dynamic table size update if the
table size is not changed from the previous value after accepting new
maximum value.
2015-10-24 17:49:51 +09:00
Tatsuhiro Tsujikawa ce74a30990 Use -fvisibility=hidden for internal functions
This will improve performance since we can avoid indirect call of
internal functions.  The downside is we now require libnghttp2 static
library to run unit tests.
2015-10-23 00:08:15 +09:00
Tatsuhiro Tsujikawa 061a557839 Add nghttp2_option_set_user_recv_extension_type to opt-in incoming extension type 2015-10-15 00:17:07 +09:00
Tatsuhiro Tsujikawa d9893d014c Add tests 2015-10-11 17:46:23 +09:00
Tatsuhiro Tsujikawa a0e884836e Fix wrong test name 2015-10-11 17:28:40 +09:00
Tatsuhiro Tsujikawa ba08948307 Merge branch 'master' of https://github.com/alagoutte/nghttp2 into alagoutte-master 2015-10-04 22:02:47 +09:00
Alexis La Goutte 81addc77b4 Add (and fix) -Wredundant-decls 2015-10-04 14:48:32 +02:00
Tatsuhiro Tsujikawa cea76226b1 Avoid excessive WINDOW_UPDATE queuing 2015-10-01 01:19:57 +09:00
Tatsuhiro Tsujikawa d22ced77c0 Return fatal error if flooding is detected to close session immediately
This change adds new return error code from nghttp2_session_mem_recv
and nghttp2_session_recv functions, namely NGHTTP2_ERR_FLOODED.  It is
fatal error, and is returned when flooding was detected.
2015-09-30 22:19:03 +09:00
Tatsuhiro Tsujikawa 0cb8c82125 Detect flooding and tear down session 2015-09-30 00:44:08 +09:00
Tatsuhiro Tsujikawa 93ba75b602 Fix bug that headers in CONTINUATION were ignored after HEADERS with padding 2015-09-25 22:28:03 +09:00
Tatsuhiro Tsujikawa 50ec17c4af Add more tests for handling padding in DATA frame 2015-09-23 18:26:18 +09:00
Tatsuhiro Tsujikawa 170f2a144a Fix warning with gcc 2015-09-23 18:26:02 +09:00
Tatsuhiro Tsujikawa 28fe3e7e89 More warning flags for --enable-werror 2015-09-23 16:49:45 +09:00
Tatsuhiro Tsujikawa 928a81885c Limit the number of incoming reserved (remote) streams
RFC 7540 does not enforce any limit on the number of incoming reserved
streams (in RFC 7540 terms, streams in reserved (remote) state).  This
only affects client side, since only server can push streams.
Malicious server can push arbitrary number of streams, and make
client's memory exhausted.  The new option,
nghttp2_set_max_reserved_remote_streams, can set the maximum number of
such incoming streams to avoid possible memory exhaustion.  If this
option is set, and pushed streams are automatically closed on
reception, without calling user provided callback, if they exceed the
given limit.  The default value is 200.  If session is configured as
server side, this option has no effect.  Server can control the number
of streams to push.
2015-08-23 21:43:41 +09:00
Tatsuhiro Tsujikawa 647e30619f Remove nghttp2_pq_increase_key 2015-08-21 23:35:17 +09:00
Tatsuhiro Tsujikawa 059280d1a5 Add stream public API
The intention of this stream API is give server application about
stream dependency information, so that it can utilize it for better
scheduling of stream processing.  We have no plan to add object
oriented API based on stream object.
2015-08-19 23:04:06 +09:00
Tatsuhiro Tsujikawa 5b59e46e2b Rewrite priority handling
We now use priority queue per stream, which contains the stream which
has ready to send a frame, or one of its descendants have a frame to
send.  We maintain invariant that if a stream is queued, then its
ancestors are also queued (except for root).  When we re-schedule
stream after transmission, we re-schedule all ancestors, so that
streams on the other path can get a chance to send.  This is basically
the same mechanism h2o project uses, but there are differences in the
details.
2015-08-17 22:35:50 +09:00
Tatsuhiro Tsujikawa d1e49a196d Remove restriction in regard to number of stream in dependency tree
Previously, the number of stream in one dependency tree (not including
root) is limited to 120.  This is due to the fact that we use
recursive calls to traverse trees.  Now we replaced recursive calls
with loop, we can remove this limitation.  Also now all streams are
descendant of root stream, rather than linked list of individual
subtree root.
2015-08-15 00:53:09 +09:00
Tatsuhiro Tsujikawa c941bff929 Fix compile error with gcc 2015-07-31 21:27:36 +09:00
Tatsuhiro Tsujikawa e66bd490a4 Fix crash if response or data is submitted to closing stream 2015-07-31 21:11:16 +09:00
Tatsuhiro Tsujikawa 8c701bb139 Header table size UINT32_MAX must be accepted 2015-07-30 21:19:46 +09:00
Tatsuhiro Tsujikawa f6a8c8d078 Remove unused variable 2015-07-23 00:44:54 +09:00
Tatsuhiro Tsujikawa 7f71fed963 Allow multiple in-flight SETTINGS 2015-07-23 00:36:00 +09:00
Tatsuhiro Tsujikawa f3288092e8 Strictly check occurrence of dynamic table size update
RFC 7541 requires that dynamic table size update must occur at the
beginning of the first header block, and is signaled as SETTINGS
acknowledgement.  This commit checks these conditions.  If dynamic
table size update appears other than the beginning of the first header
block, it is treated as error.  If SETTINGS ACK is received, and next
HEADERS header block does not have dynamic table size update, it is
treated as error.
2015-07-22 00:11:23 +09:00
Tatsuhiro Tsujikawa 764cd17316 Add test when nghttp2_http_on_data_chunk failed without auto flow control 2015-07-08 22:56:40 +09:00
Tatsuhiro Tsujikawa d6ca95a0c9 Fix sibling's item is not queued when ancestor's item is detached 2015-06-24 22:18:07 +09:00
Tatsuhiro Tsujikawa 1945d0f02a Fix assertion failure in nghttp2_stream.c
This is regression introduced in
46b70c1db8.
2015-06-23 23:04:53 +09:00
Tatsuhiro Tsujikawa a7031da364 Fix bug that idle self-depending PRIORITY is not handled gracefully
Previously, we did not handle PRIORITY frame which depends on itself
and for idle stream.  As a result, nghttp2_session_mem_recv (or
nghttp2_session_recv) returne NGHTTP2_ERR_NOMEM.  The error code was
still misleading.  It was not out of memory, and we failed to insert
hash map because of duplicated key, which was treated as out of
memory.  This commit fixes this issue, by explicitly checking
dependency for incoming PRIORITY for all cases.
2015-06-21 16:02:32 +09:00
Tatsuhiro Tsujikawa 46b70c1db8 Optimize dependency based priority code to Firefox style tree
While this commit optimizes dependency routine to Firefox style tree,
the other use cases (e.g., linear chain) are also improved
dramatically as well.
2015-06-20 22:11:24 +09:00
Tatsuhiro Tsujikawa b5717cd288 Fix bug that data are not consumed for connection in race condition
When we know that stream is closed at time we read DATA frame header,
we use NGHTTP2_IB_IGN_DATA, and consume data for connection if
nghttp2_option_set_no_auto_window_update() is used.  However, if
stream is closed while we are in NGHTTP2_IB_READ_DATA, those bytes are
not consumed for connection, nor notified to application via callback,
so it eventually fills up connection window and connection will
freeze.  This commit fixes this issue by consuming these data for
connection when stream is closed or does not exist.
2015-06-11 23:34:30 +09:00
Tatsuhiro Tsujikawa a0a5f4f93e tests: Break if all compressed header input processed in nghttp2_buf 2015-05-27 00:33:24 +09:00
Tatsuhiro Tsujikawa f0379aa428 Fix invalid memory free 2015-05-22 23:36:34 +09:00
Alexis La Goutte ddee5d3896 fix Value stored to 'rv' is never read found by Clang Analyzer 2015-05-15 18:11:59 +02:00
Tatsuhiro Tsujikawa 0b27f005e0 Merge branch 'master' into v1.0.0
Conflicts:
	src/HttpServer.cc
2015-05-15 23:24:19 +09:00
Tatsuhiro Tsujikawa 252aeb43e1 Add test for GH-232 2015-05-15 01:00:09 +09:00
Tatsuhiro Tsujikawa 1ad1fe6005 Merge branch 'master' into v1.0.0 2015-04-28 22:48:34 +09:00
Tatsuhiro Tsujikawa 9e1b068a4b Fix bug that promised stream was not reset on decompression error 2015-04-28 21:38:52 +09:00
Tatsuhiro Tsujikawa c41f413978 Fix compile error with --enable-werror 2015-04-25 02:23:01 +09:00
Tatsuhiro Tsujikawa f2cf2b625c Replace priority queue with linear queue where possible
After reviewing codebase, only queue for DATA frames requires
priorities.  Other frames can be replaced multiple linear queues.
Replacing priority queue with linear queue allows us to simplify
codebase a bit; for example, now nghttp2_session.next_seq is gone.
2015-04-25 00:56:46 +09:00
Tatsuhiro Tsujikawa db4a68454a Merge branch 'master' into v1.0.0
Conflicts:
	lib/includes/nghttp2/nghttp2.h
2015-04-24 00:13:15 +09:00
Tatsuhiro Tsujikawa c925c32233 Fix bug that promised stream is not reset on temporal failure from on_header_callback 2015-04-23 23:57:39 +09:00
Tatsuhiro Tsujikawa 514558afc0 Allow NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE from nghttp2_on_begin_headers_callback
Since application most likely allocates the stream object in
nghttp2_on_begin_headers_callback, it is desirable to handle its
failure as stream error.  But previously it only signals success or
fatal error.  Submitting RST_STREAM does not prevent
nghttp2_on_header_callback from being invoked.  This commit improves
this situation by allowing NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE from
nghttp2_on_begin_headers_callback.  If that value is returned, library
submits RST_STREAM with error code INTERNAL_ERROR, and
nghttp2_on_header_callback and nghttp2_on_frame_recv_callback for that
frame are not invoked.  Note that for PUSH_PROMISE frame, the stream
to be reset is promised stream.
2015-04-23 23:43:30 +09:00
Tatsuhiro Tsujikawa 5937b4b6f7 Merge branch 'master' into v1.0.0 2015-04-19 23:13:38 +09:00
Tatsuhiro Tsujikawa 57644e0256 Effectively revert 03c4092862
This is not mandated by spec.  Also it may work badly with Firefox
style dependency tree usage.
2015-04-17 21:04:17 +09:00
Tatsuhiro Tsujikawa 82e2c5bd22 Never index authorization and small cookie header field
nghttp2 library now use Literal Header Field never Indexed for
"authorization" header field and small "cookie" header field,
regardless of nghttp2_nv.flags.
2015-04-15 23:58:56 +09:00
Tatsuhiro Tsujikawa 3e50ef439d Announce h2, final HTTP/2 ALPN identifier 2015-04-05 23:15:20 +09:00
Tatsuhiro Tsujikawa d0c27d5229 Send 24 bytes client magic byte string by library
Previously nghttp2_session_send() and nghttp2_session_mem_send() did
not send 24 bytes client magic byte string (MAGIC).  We made
nghttp2_session_recv() and nghttp2_session_mem_recv() process MAGIC by
default, so it is natural to make library send MAGIC as well.  This
commit makes nghttp2_session_send() and nghttp2_session_mem_send()
send MAGIC.  This commit also replace "connection preface" with
"client magic", since we call MAGIC as "connection preface" but it is
just a part of connection preface.  NGHTTP2_CLIENT_CONNECTION_PREFACE
macro was replaced with NGHTTP2_CLIENT_MAGIC.  The already deprecated
NGHTTP2_CLIENT_CONNECTION_HEADER macro was removed permanently.
nghttp2_option_set_no_recv_client_preface() was renamed as
nghttp2_option_set_no_recv_client_magic().  NGHTTP2_ERR_BAD_PREFACE
was renamed as NGHTTP2_ERR_BAD_CLIENT_MAGIC.
2015-04-05 23:15:20 +09:00
Tatsuhiro Tsujikawa ebf214c8fc nghttp2_on_invalid_frame_recv_callback should have lib_error_code as param
nghttp2_error_code is HTTP/2 standard error code and is too coarse to
know what's going on.
2015-04-05 23:15:20 +09:00
Tatsuhiro Tsujikawa 250ea53e4b Deal with 24 bytes client connection preface by default
Since HTTP/2 spec requires for client to send connection preface, it
is reasonable to make this option enabled by default.  It is still a
use case to disable this, so replace this option with
nghttp2_option_set_no_recv_client_preface().
2015-04-05 23:15:20 +09:00
Tatsuhiro Tsujikawa 9eff511c5e Add nghttp2_send_data_callback to send DATA payload without copying
To avoid buffer copy in nghttp2_data_source_read_callback, this commit
introduces NGHTTP2_DATA_FLAG_NO_COPY and nghttp2_send_data_callback.
By using NGHTTP2_DATA_FLAG_NO_COPY in
nghttp2_data_source_read_callback, application can avoid to copy
application data to given buffer.  Instead, application has to
implement nghttp2_send_data_callback to send complete DATA frame by
itself.  We see noticeable performance increase in nghttpd and
tiny-nghttpd using this new feature.  On the other hand, nghttpx does
not show such difference, probably because buffer copy is not
bottleneck.  Using nghttp2_send_data_callback adds complexity, so it
is recommended to measure the performance to see whether this extra
complexity worth it.
2015-04-04 21:23:50 +09:00
Alexis La Goutte 5f05135d1b Fix some "Value stored to 'stream' is never read" found by Clang Analyzer 2015-04-01 13:03:22 +02:00
Tatsuhiro Tsujikawa ccea4d42b5 Refactor .gitignore files 2015-03-29 18:40:37 +09:00
Tatsuhiro Tsujikawa d3d6c5e314 Fix bug that inflater->nvbufs is not reset 2015-03-24 21:54:05 +09:00
Tatsuhiro Tsujikawa 661fb2eb0e NULL-terminate name and value in nghttp2_nv
Guaranteeing NULL-termination is very useful when name or value are
used with C functions which requires NULL-terminated string.
2015-03-23 23:25:57 +09:00
Tatsuhiro Tsujikawa ef913bc929 Validate :path header field
For "http" or "https" URIs, :path header field must start with "/".
The only exception is OPTIONS method, which can contain "*" to
represent system-wide OPTIONS request.
2015-03-21 23:03:37 +09:00
Tatsuhiro Tsujikawa 2f2a535113 Add a way to send trailer with nghttp2_submit_request/nghttp2_submit_response
nghttp2_submit_request and nghttp2_submit_response will set
NGHTTP2_FLAG_END_STREAM after all given data is sent (data could be
0).  This means we have no way to send trailers.  In this commit, we
added NGHTTP2_DATA_FLAG_NO_END_STREAM flag.  The application can set
this flag in *data_flags inside nghttp2_data_source_read_callback.  If
NGHTTP2_DATA_FLAG_EOF is set, library automatically set
NGHTTP2_FLAG_END_STREAM.  But if both NGHTTP2_DATA_FLAG_EOF and
NGHTTP2_DATA_FLAG_NO_END_STREAM are set, NGHTTP2_FLAG_END_STREAM will
not set by library.  Then application can use new
nghttp2_submit_trailer() to send trailers.  nghttp2_submit_trailer()
will set NGHTTP2_FLAG_END_STREAM and it is actually thing wrapper of
nghttp2_submit_headers().
2015-03-07 17:09:29 +09:00
Tatsuhiro Tsujikawa 505a300d93 Refuse PUSH_PROMISE while unacked local ENABLE_PUSH is 0
After we sent SETTINGS including ENABLE_PUSH = 0, peer may already
issue PUSH_PROMISE before receiving our SETTINGS and react it to
SETTINGS ACK.  Previously we accept this PUSH_PROMISE.  In this
commit, we check the pending ENABLE_PUSH value and if it means
disabling push, we refuse PUSH_PROMISE with RST_STREAM of error
REFUSED_STREAM.
2015-03-07 16:17:40 +09:00
Tatsuhiro Tsujikawa a2a9f15307 tests: Use nghttp2_mem instead of raw malloc()/free()
Fixes GH-170
2015-03-03 23:23:43 +09:00
Tatsuhiro Tsujikawa 05b8901d69 Call on_invalid_frame_recv_callback on bad HTTP messaging 2015-02-26 22:59:07 +09:00
Tatsuhiro Tsujikawa 814c7e68e0 Ignore regular headers if it includes illegal characters.
This commit only affects the library behaviour unless
nghttp2_option_set_no_http_messaging() is used.

We like strict validation against header field name and value against
RFC 7230, but we have already so much web sites and libraries in
public internet which do not obey these rules.  Simply just
terminating stream because of this may break web sites and it is too
disruptive.  So we decided that we should be conservative here so
those header fields containing illegal characters are just ignored.
But we are conservative only for regular headers.  We are strict for
pseudo headers since it is new to HTTP/2 and new implementations
should know the rules better.
2015-02-22 23:13:27 +09:00
Tatsuhiro Tsujikawa 6051ff63e0 tests: Fix compile error with gcc-4.7 2015-02-22 17:43:00 +09:00
Tatsuhiro Tsujikawa b3846d6c27 Rename NGHTTP2_OPTMASK_NO_HTTP_SEMANTICS with NGHTTP2_OPTMASK_NO_HTTP_MESSAGING 2015-02-20 23:07:48 +09:00
Tatsuhiro Tsujikawa b157d4ebb2 Validate HTTP semantics by default
Previously we did not check HTTP semantics and it is left out for
application.  Although checking is relatively easy, but they are
scattered and error prone.  We have implemented these checks in our
applications and also feel they are tedious.  To make application
development a bit easier, this commit adds basic HTTP semantics
validation to library code.  We do following checks:

server:

* HEADERS is either request header or trailer header.  Other type of
header is disallowed.

client:

* HEADERS is either zero or more non-final response header or final
  response header or trailer header.  Other type of header is
  disallowed.

For both:

* Check mandatory pseudo header fields.
* Make sure that content-length matches the amount of DATA we
  received.

If validation fails, RST_STREAM of type PROTOCOL_ERROR is issued.
2015-02-20 01:01:10 +09:00
Tatsuhiro Tsujikawa 9c30211da9 Ignore all incoming bytes when first SETTINGS is not received 2015-02-15 01:20:10 +09:00
Tatsuhiro Tsujikawa 442572c1f4 Handle situation where request HEADERS in queue is reset by RST_STREAM
Previously we did not handle the situation where RST_STREAM is
submitted against a stream while requet HEADERS which opens that
stream is still in queue.  Due to max concurrent streams limit,
RST_STREAM is sent first, and then request HEADERS, which effectively
voids RST_STREAM.

In this commit, we checks RST_STREAM against currently pending request
HEADERS in queue and if stream ID matches, we mark that HEADERS as
canceled and RST_STREAM is not sent in this case.  The library will
call on_frame_not_sent_callback for the canceled HEADERS with error
code from RST_STREAM.
2015-02-13 23:48:16 +09:00
Tatsuhiro Tsujikawa 0d2bbead9d Add test to submit PUSH_PROMISE without associated stream open 2015-02-12 23:09:01 +09:00
Tatsuhiro Tsujikawa 7d4a6aa179 Add test for submission ordering of HEADERS and its RST_STREAM 2015-02-12 21:28:20 +09:00
Tatsuhiro Tsujikawa 354de30874 Make default min frame payload size to 16K
Previously we use 16K - 9 bytes (frame header) as frame payload size
so that whole frame fits in 1 TLS record size (16K).  But it turns out
that in proxy use case, we will receive 16K payload from backend and
we have to split it into 2 odd looking frames (16K - 9 and 9), and
latter is highly inefficient.  To avoid this situation, we decided to
use min frame payload size to 16K.  Since we operates on TLS as stream
of data, we are not so much restricted in its record size.
2015-02-12 00:09:18 +09:00
Tatsuhiro Tsujikawa 6b28e033de Fix compile error and memory leak 2015-02-09 22:37:11 +09:00
Tatsuhiro Tsujikawa eec8870ac1 Fix bug that client may send PROTOCOL_ERROR upon canceled push stream
Previously we treat stream in NGHTTP2_STREAM_RESERVED state specially,
that is we don't increment or decrement streams counts if stream is in
that state.  Because of this, we don't change the stream state to
NGHTTP2_STREAM_CLOSING if stream is in NGHTTP2_STREAM_RESERVED.  But
it turns out that it causes a problem.  If client canceled pushed
stream before push response HEADERS, stream is still in
NGHTTP2_STREAM_RESERVED state.  If push response HEADERS arrived in
this state, library happily accepts it and passed to application.

With this commit, this bug was corrected.  We now change stream state
to NGHTTP2_STREAM_CLOSING even if it was in NGHTTP2_STREAM_RESERVED
state.  We now use NGHTTP2_STREAM_FLAG_PUSH to determine whether we
have to increase/decrase stream count.
2015-02-09 22:23:20 +09:00
Tatsuhiro Tsujikawa e2bbc94616 Use NGHTTP2_PROTOCOL_ERROR when peer exceeds MAX_CONCURRENT_STREAMS limit
Kudos to h2spec to find this details
2015-02-02 00:14:17 +09:00
Tatsuhiro Tsujikawa fbd9bcb00e Use _LDADD to specify libraries instead of _LDFLAGS
This is because _LDFLAGS comes before _LDADD.  If we specify a library
and another library in _LDADD depends on it, we get undefined
reference error.
2015-01-25 00:58:30 +09:00
Tatsuhiro Tsujikawa 064bfcc9d2 Fix test failure 2015-01-23 01:29:41 +09:00
Tatsuhiro Tsujikawa b685747643 Add nghttp2_submit_shutdown_notice() to start graceful shutdown
nghttp2_submit_shutdown_notice() is used to notify the client that
graceful shutdown is started.  We expect that after this call, the
server application should send another GOAWAY using
nghttp2_submit_goaway() with appropriate last_stream_id.  In this
commit, we also added nghttp2_session_get_last_proc_stream_id(), which
can be used as last_stream_id parameter.

This commit implements graceful shutdown in nghttpx.  The integration
test for graceful shutdown is also added.
2015-01-22 23:21:58 +09:00
Tatsuhiro Tsujikawa a2e4a1eb26 tests: Remove unintended debug output 2015-01-09 10:07:57 +09:00
Tatsuhiro Tsujikawa a804117c83 Fix GOAWAY handling
On reception of GOAWAY, new stream creation is disallowed regardless
of last-stream-id in GOAWAY is larger than next stream ID.
2015-01-07 22:53:43 +09:00
Tatsuhiro Tsujikawa 959d05e6f8 failmalloc: Use nghttp2_mem instead of using dlsym 2014-12-20 23:56:33 +09:00
Tatsuhiro Tsujikawa 7c0a0c495d Rename nghttp2_stream.data_item to nghttp2_stream.item and related functions
Initially, we use nghttp2_stream.data_item to refer only item with
DATA frame.  But recently we use it to refer HEADERS frame as well.
So it is better to call just item rather than data_item.  This applies
to all related functions.
2014-12-20 21:48:31 +09:00
Tatsuhiro Tsujikawa e8513b3241 Make huffman encoding faster 2014-12-19 23:22:55 +09:00
Tatsuhiro Tsujikawa 280c9dfcf3 Keep idle streams in separate list
Previously we handle idle streams as closed streams.  We only keeps
sum of closed streams and active streams under max concurrent streams
limit, idle streams gets deleted earlier than client expects.

In this change, idle streams are kept in separate list and not handled
as closed streams.  To mitigate possible attack vector to make
unlimited idle streams, we cap the number of idle streams in a half of
max concurrent streams.  This is arbitrary choice.  It may be adjusted
in the future when we have interop experience.
2014-12-13 00:14:52 +09:00
Tatsuhiro Tsujikawa c0ffed7788 Support custom memory allocator
nghttp2_mem structure is introduced to hold custom memory allocator
functions and user supplied pointer.  nghttp2_mem object can be passed
to nghttp2_session_client_new3(), nghttp2_session_server_new3(),
nghttp2_hd_deflate_new2() and nghttp2_hd_inflate_new2() to replace
standard malloc(), free(), calloc() and realloc().  nghttp2_mem
structure has user supplied pointer mem_user_data which can be used as
per session/object memory pool.
2014-12-08 00:55:55 +09:00
Tatsuhiro Tsujikawa 21b48d24e4 Remove altsvc 2014-12-07 23:11:54 +09:00
Tatsuhiro Tsujikawa 54a3209cf5 configure.ac: Rename some variables so that they follow automake convention 2014-12-01 23:14:28 +09:00
Tatsuhiro Tsujikawa 7036859823 Do not change user variable CFLAGS in configure.ac 2014-12-01 23:06:11 +09:00
Tatsuhiro Tsujikawa ca57c2f6b6 Rename NGHTTP2_GOAWAY_FAIL_ON_SEND with NGHTTP2_GOAWAY_TERM_ON_FAIL 2014-11-29 16:28:08 +09:00
Tatsuhiro Tsujikawa d75ba74bbd Return error if invalid stream_id is given to nghttp2_submit_push_promise 2014-11-29 16:17:02 +09:00
Tatsuhiro Tsujikawa 9ff1925538 Robust GOAWAY handling
This change will utilize last_stream_id in GOAWAY extensively.  When
GOAWAY is received with a last_stream_id, library closes all outgoing
streams whose stream_id > received last_stream_id.
nghttp2_on_stream_callback is called for each stream to be closed.

When GOAWAY is sent with a last_stream_id, library closes all incoming
streams whose stream_id > sent last_stream_id.
nghttp2_on_stream_callback is called for each stream to be closed.
2014-11-29 16:02:13 +09:00
Tatsuhiro Tsujikawa 382a328ead Issue connection error if client receives HEADERS with idle stream ID
If stream ID is not idle, it might be valid HEADERS.  If stream ID is
idle, it is invalid regardless stream ID is even or odd, since client
is not expected to recieve request from server.  nghttp2 library
historically allows this, but now we forbids this.
2014-11-28 01:22:57 +09:00
Tatsuhiro Tsujikawa babfa41424 Just ignore HEADERS with non-idle stream ID and not found in stream map 2014-11-28 01:01:33 +09:00
Tatsuhiro Tsujikawa b1f807abd1 Reformat lines with clang-format-3.5 2014-11-27 23:56:30 +09:00
Alexis La Goutte bac44d7ffb Fix -Werror=unused-parameter using _U_ macro 2014-11-25 17:08:09 +01:00
Tatsuhiro Tsujikawa 8e94551881 Handle idle stream in priority field 2014-11-24 15:25:19 +09:00
Tatsuhiro Tsujikawa b7c0576eb5 Make certain type of HEADERS subject to priority
We make following HEADERS under priority control:
* push response HEADERS
* HEADERS submitted by nghttp2_submit_response

Currently, HEADERS submitted by nghttp2_submit_headers is not attached
to stream.  This is because it may be used as non-final response
header and application may submit final response using
nghttp2_submit_response without checking non-final response header
transmission.
2014-11-24 15:25:19 +09:00
Tatsuhiro Tsujikawa ae93f6345c Allow PRIORITY frame at anytime.
Allowing PRIORITY frame at anytime so that PRIORITY frame to idle
stream can create anchor node in dependency tree.  In this change, we
open stream with new NGHTTP2_STREAM_IDLE state, which is linked in
session->closed_stream_head and is treated as if it is closed stream.
One difference is that if the stream is opened, we remove it from
linked list and change the state to the appropriate one.  To O(1)
removal from linked list, we change session->closed_stream_head to
doubly linked list.
2014-11-24 15:25:19 +09:00
Tatsuhiro Tsujikawa c31be5af4d Assign default priority if dep_stream in PRIORITY does not exist 2014-11-08 16:12:13 +09:00
Tatsuhiro Tsujikawa 292c01fda2 Add test to make sure that default priority is assigned 2014-11-08 11:37:53 +09:00
Tatsuhiro Tsujikawa 62ede05c09 Fix heap-use-after-free due to duplicated push of DATA item 2014-11-06 23:47:41 +09:00
Tatsuhiro Tsujikawa 9a33116526 Fix bug in priority tree
This change fixes the bug that stream is out of dependency tree if the
number of nodes in a dependency tree which we add new node to is
already maximum (NGHTTP2_MAX_DEP_TREE_LENGTH) and the number of
maximum concurrent streams is more than more than
NGHTTP2_MAX_DEP_TREE_LENGTH.
2014-11-05 00:32:16 +09:00
Tatsuhiro Tsujikawa 76800dc8e7 Remove unused functions 2014-10-30 23:31:36 +09:00
Tatsuhiro Tsujikawa 4d93dd9d91 Upate to draft-15
* Add NGHTTP2_HTTP_1_1_REQUIRED error code
* Allow transmission of WINDOW_UPDATE on reserved (remote)
* Allow reception of WINDOW_UPDATE on reserved (local)
* Treat frame larger than MAX_FRAME_SIZE as FRAME_SIZE_ERROR

ALPN identifier is still h2-14 to continue interop, since draft-14 and
-15 are binary compatible.  The new error code was added in draft-15,
but HTTP/2 allows extensions can freely add new error code, so it is
not a problem.
2014-10-30 22:40:02 +09:00
Tatsuhiro Tsujikawa 502ff24568 Avoid iterate siblings when adding/removing stream tree 2014-10-16 01:12:59 +09:00
Tatsuhiro Tsujikawa 70c0558443 Set payload length when expected SETTINGS is not received 2014-10-10 21:46:02 +09:00
Tatsuhiro Tsujikawa 80dcb565eb Check first SETTINGS strictly 2014-10-09 21:37:18 +09:00
Tatsuhiro Tsujikawa 402c262de5 Push stream to queue after effective weight was calculated 2014-10-08 22:44:02 +09:00
Tatsuhiro Tsujikawa 03c4092862 Distribute closed or blocked stream's weight to its siblings
This also means that at least one stream whose dpri is
NGHTTP2_STREAM_DPRI_TOP exists, its siblings descendants have no
chance to send streams, even if their parent stream has
NGHTTP2_STREAM_DPRI_NODATA.
2014-10-07 23:52:36 +09:00
Tatsuhiro Tsujikawa 1d138accb9 Unify DATA and other frames in nghttp2_outbound_item and save malloc() 2014-10-03 21:31:37 +09:00
Tatsuhiro Tsujikawa e20b417b84 Embed aux_data to nghttp2_outbound_item so that we can save some malloc() calls 2014-09-30 21:45:15 +09:00
Tatsuhiro Tsujikawa a11fbf6e2f Optimize connection level remote flow control
Previously when connection level remote flow control window gets 0, we
mark the stream having DATA frame with
NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL.  When connection level
WINDOW_UPDATE is received, we checks all existing streams, including
closed ones, and call nghttp2_stream_resume_deferred_data().  The
profiler shows this is expensive.

Now we prepare dedicated priority queue for DATA frames.  And we don't
mark stream with NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL when DATA
cannot be sent solely due to connection level flow control.  Instead,
we just queue DATA item to queue.  We won't pop DATA item from queue
when connection level remote window size is 0.  This way, we avoid the
expensive operation for all streams when WINDOW_UPDATE is arrived.
2014-09-26 00:01:51 +09:00
Tatsuhiro Tsujikawa 89c3c08590 tests: Fix compiler warning 2014-09-19 00:20:54 +09:00
Tatsuhiro Tsujikawa b2f88f8fe3 Fix memory leak around stream->data_item
Previously we missed the case where stream->data_item is not deleted
and it caused leak.  Now stream->data_item is properly deleted when
session is deleted.  We decided not to delete data_item in
nghttp2_stream_free() since we need nghttp2_session to decide whether
data_item should be deleted or not there.
2014-09-17 23:16:00 +09:00
Tatsuhiro Tsujikawa 901de5fbce Add nghttp2_option_set_recv_client_preface()
By default, nghttp2 library only handles HTTP/2 frames and does not
recognize first 24 bytes of client connection preface. This design
choice is done due to the fact that server may want to detect the
application protocol based on first few bytes on clear text
communication. But for simple servers which only speak HTTP/2, it is
easier for developers if nghttp2 library takes care of client
connection preface.

If this option is used with nonzero val, nghttp2 library checks first
24 bytes client connection preface. If it is not a valid one,
nghttp2_session_recv() and nghttp2_session_mem_recv() will return
error NGHTTP2_ERR_BAD_PREFACE, which is fatal error.
2014-09-13 19:50:44 +09:00
Tatsuhiro Tsujikawa 9b2c24ad68 tests: Remove debug output 2014-08-28 23:32:14 +09:00
Tatsuhiro Tsujikawa b4bb6a6101 Add reserved bits to header and frames
Currently reserved bit is always set to 0.  The addition of reserved
bit is for future extension.
2014-08-28 23:30:42 +09:00
Tatsuhiro Tsujikawa f34cbf9b45 tests: Include config.h 2014-08-27 23:36:57 +09:00
Tatsuhiro Tsujikawa 4c11cd0671 Add test to submit DATA frame twice
This commit adds test to submit DATA frame twice and fixes the bug
that 2nd DATA is not sent.
2014-08-25 23:46:17 +09:00
Tatsuhiro Tsujikawa 4c5c6749a0 Check buffer capacity explicitly 2014-08-25 23:12:17 +09:00
Tatsuhiro Tsujikawa dd038bf753 Fix crash when buffer was reallocated after read_length_callback
Added test for this crash.
2014-08-25 23:05:39 +09:00
Tatsuhiro Tsujikawa 0b1ab90fb8 Move frame_type parameter in front of stream_id
This commit moves frame_type parameter of
nghttp2_data_soruce_read_length_callback in front of stream_id
parameter.  The motivation is that other callback is generally put
frame related parameters first.  To make it consistent, we move
frame_type, which is frame ralted parameter, to the left.
2014-08-25 22:31:11 +09:00
Tatsuhiro Tsujikawa 82bc7198e6 Change nghttp2_session_get_stream_remote_window_size behavior
Now it returns only stream's available remote window size, without
considering connection level window size.  For connection-level window
size, nghttp2_session_get_remote_window_size() is added by this
commit.  To get old behavior of
nghttp2_session_get_stream_remote_window_size() is use
min(nghttp2_session_get_stream_remote_window_size(),
nghttp2_session_get_remote_window_size()).  The reason of this change
is that it is desirable to know just stream level window size without
taking into connection level window size.  This is useful for
debugging purpose.
2014-08-25 21:44:22 +09:00
Tatsuhiro Tsujikawa a36c4c6f5f Add nghttp2_on_begin_frame_callback
nghttp2_on_begin_frame_callback will be invoked when a frame header is
received.
2014-08-25 21:26:50 +09:00
Tatsuhiro Tsujikawa 31528b6267 Use uint32_t for HTTP/2 error_code
h2-14 now allows extensions to define new error codes.  To allow
application callback to access such error codes, we uses uint32_t as
error_code type for structs and function parameters.  Previously we
treated unknown error code as INTERNAL_ERROR, but this change removes
this and unknown error code is passed to application callback as is.
2014-08-25 21:24:04 +09:00
Tatsuhiro Tsujikawa 3655090997 Merge branch 'window_size_control' of https://github.com/akamai/nghttp2 into akamai-window_size_control 2014-08-25 21:09:26 +09:00
Scott Mitchell 3cd08251ca Send window size API extension
Motivation:

The send window size is currently fixed by a macro at compile time.
In order for users of the library to impact the send window size they
would have to change a macro at compile time. The window size may be dynamic
depending on the environment and deployment scheme. The library users
currently have no way to change this parameter.

Modifications:

Add a new optional callback method which is called before data is sent to
obtain the desired send window size. The callback return value will be
subject to a range check for the current session, stream, and settings
limits defined by flow control.

Result:
Library users have control over their send sizes.
2014-08-24 11:32:44 -04:00
Tatsuhiro Tsujikawa bf48ef9bab Add test to check consumed size when no auto window update is enabled 2014-08-24 22:36:35 +09:00
Tatsuhiro Tsujikawa 9893ae81af Add nghttp2_bufs_realloc 2014-08-24 15:34:55 +09:00
Tatsuhiro Tsujikawa 7bfa276e96 Fix bug that NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE causes session failure
Previously returning NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE from
on_header_callback moves input offset badly and it causes header
decompression error on the subsequent frames.  This commit fix this
bug.
2014-08-24 00:50:55 +09:00
Tatsuhiro Tsujikawa bbe4f5a3d1 Allow frame submission immediately after nghttp2_submit_{request,headers,pp}
This commit makes handling of outgoing HEADERS and PUSH_PROMISE in the
same priority of other frames on the stream, so these frames are
processed in the order they are submitted.  This allows application to
submit frames to a stream returned by nghttp2_submit_{request,
headers, push_promise} immediately.  The only exception is
WINDOW_UPDATA frame, which requires nghttp2_stream object, which is
not created yet.
2014-08-17 17:31:43 +09:00
Tatsuhiro Tsujikawa 2fb750f2e3 nghttp2_check_header_value: Disallow 0x00 2014-08-02 00:30:09 +09:00
Tatsuhiro Tsujikawa 7952029752 Advertise h2-14 2014-07-31 23:34:54 +09:00
Tatsuhiro Tsujikawa b8a2bf2675 Remove END_SEGMENT flag 2014-07-31 23:05:53 +09:00