Commit Graph

220 Commits

Author SHA1 Message Date
Sean McArthur
e3c6e0c590 Notify send_tasks when there is a connection error (#231) 2018-03-07 12:19:54 -08:00
Darren Tsung
ad90f9b97b Remove assert around self.pending_capacity.is_empty() (#225)
This assert does not hold as many streams can be pushed into
pending_capacity during a call to send_data(). See issue #224
for more discussion and sign-off.

Closes #224
2018-02-27 10:35:00 -08:00
Brian Smith
b6724f7d7a Upgrade to env_logger 0.5 & log 0.4; reduce related dependencies (#226)
Upgrade to env_logger 0.5 and log 0.4 so that projects that use those
versions don't have to build both those versions and the older ones
that h2 is currently using.

Don't enable the regex support in env_logger. Applications that want
the regex support can enable it themselves; this will happen
automatically when they add their env_logger dependency.

Disable the env_logger dependency in quickcheck.

The result of this is that there are fewer dependencies. For example,
regex and its dependencies are no longer required at all, as can be
seen by observing the changes to the Cargo.lock. That said,
env_logger 0.5 does add more dependencies itself; however it seems
applications are going to use env_logger 0.5 anyway so this is still
a net gain.

Submitted on behalf of Buoyant, Inc.

Signed-off-by: Brian Smith <brian@briansmith.org>
2018-02-23 20:25:42 -08:00
Darren Tsung
0c59957d88 When Streams are dropped, close Connection (#221) (#222)
When all Streams are dropped / finished, the Connection was held
open until the peer hangs up. Instead, the Connection should hang up
once it knows that nothing more will be sent.

To fix this, we notify the Connection when a stream is no longer
referenced. On the Connection poll(), we check that there are no
active, held, reset streams or any references to the Streams
and transition to sending a GOAWAY if that is case.

The specific behavior depends on if running as a client or server.
2018-02-15 13:14:18 -08:00
Carl Lerche
69bd8828ef Remove mock-io git dependency 2018-01-11 22:46:52 -08:00
Sean McArthur
aa23a9735d SETTINGS_MAX_HEADER_LIST_SIZE (#206)
This, uh, grew into something far bigger than expected, but it turns out, all of it was needed to eventually support this correctly.

- Adds configuration to client and server to set [SETTINGS_MAX_HEADER_LIST_SIZE](http://httpwg.org/specs/rfc7540.html#SETTINGS_MAX_HEADER_LIST_SIZE)
- If not set, a "sane default" of 16 MB is used (taken from golang's http2)
- Decoding header blocks now happens as they are received, instead of buffering up possibly forever until the last continuation frame is parsed.
- As each field is decoded, it's undecoded size is added to the total. Whenever a header block goes over the maximum size, the `frame` will be marked as such.
- Whenever a header block is deemed over max limit, decoding will still continue, but new fields will not be appended to `HeaderMap`. This is also can save wasted hashing.
- To protect against enormous string literals, such that they span multiple continuation frames, a check is made that the combined encoded bytes is less than the max allowed size. While technically not exactly what the spec suggests (counting decoded size instead), this should hopefully only happen when someone is indeed malicious. If found, a `GOAWAY` of `COMPRESSION_ERROR` is sent, and the connection shut down.
- After an oversize header block frame is finished decoding, the streams state machine will notice it is oversize, and handle that.
  - If the local peer is a server, a 431 response is sent, as suggested by the spec.
  - A `REFUSED_STREAM` reset is sent, since we cannot actually give the stream to the user.
- In order to be able to send both the 431 headers frame, and a reset frame afterwards, the scheduled `Canceled` machinery was made more general to a `Scheduled(Reason)` state instead.

Closes #18 
Closes #191
2018-01-05 09:23:48 -08:00
Sean McArthur
6f7b826b0a fix name change in server tests (#213) 2018-01-04 11:45:08 -08:00
Sean McArthur
3cbc158210 send reset CANCEL when SendStream is dropped with no end-of-stream sent (#210) 2018-01-04 11:06:06 -08:00
Carl Lerche
d0b5b6246a Misc renames (#202)
This patch renames a number of types and functions making
the API more consistent.

* `Server` -> `Connection`
* `Client` -> `SendRequest`
* `Respond` -> `SendResponse`.

It also moves the handshake fns off of `Connection` and make
them free fns in the module. And `Connection::builder` is removed
in favor of `Builder::new`.
2018-01-02 17:02:17 -08:00
Sean McArthur
26e7a2d416 remove erroneous assert when stream has buffered send data (#209) 2018-01-02 12:49:41 -08:00
Carl Lerche
fc75311fae Support writing continuation frames. (#198)
Large header sets might require being split up across multiple frames.
This patch adds support for doing so.
2017-12-20 17:24:29 -08:00
Sean McArthur
a89401dd91 reset pending push promises if user drops all refs (#199) 2017-12-20 16:50:20 -08:00
Sean McArthur
10d8ed7429 Add test that a window update can be received in reserved state (#195) 2017-12-19 20:07:39 -08:00
Sean McArthur
1552d62e7c ignore trailers for some time on locally reset streams (#194) 2017-12-19 15:06:05 -08:00
Sean McArthur
eafd6bfd98 release connection capacity when recv_data has stream error (#186) 2017-12-18 15:08:21 -08:00
Sean McArthur
1ea9a8fc7e ignore received frames on a stream locally reset for some time (#174)
- Adds config duration for how long to ignore frames on a reset stream
- Adds config for how many reset streams can be held at a time
2017-12-18 11:09:38 -08:00
Carl Lerche
9378846da8 Client should validate request URI. (#181)
This patch adds checks for the request URI and rejects invalid URIs. In
the case of forwarding an HTTP 1.1 request with a path, an "http" pseudo
header is added to satisfy the HTTP/2.0 spec.

Closes #179
2017-12-11 13:42:00 -06:00
Sean McArthur
6c68f72fbd notify stream send task when receiving EOF (#178)
* notify stream send task when receiving EOF

* record a conn_error on eof so client can see it

* fix stream id overflow test
2017-12-01 15:58:04 -08:00
Carl Lerche
5d54d8cd79 Fix flow control bug (#177)
This patch fixes a bug that prevents sent data from being flushed to the
socket.

When data is sent, the task managing the connection must be notified. A
guard exists that prevents unnecessary notification of the connection
when the stream does not have any send capacity. However, this guard was
buggy. Instead of notifying the connection if *any* data can be sent, it
notified the connection only when *all* data could be sent.

This patch fixes the check as well as adds some tests that ensure the
connection task is notified.
2017-11-29 12:54:23 -08:00
Sean McArthur
2be2523162 notify stream refs when the connection receives EOF (#176) 2017-11-28 13:42:22 -08:00
Sean McArthur
79003d0d45 reject connection-specific headers (#173)
- When receiving, return a PROTOCOL_ERROR.
- When sending, return a user error about malformed headers.

Closes #36
2017-11-14 11:16:29 -08:00
Eliza Weisman
05abb686cf Add test for #38 (#162)
As requested in https://github.com/carllerche/h2/issues/38#issuecomment-328254128, I've added a test to `stream_states.rs` to cover the case where we receive a HEADERS frame that gets rejected (due to being malformed), then the same stream ID is received with a valid HEADERS frame which gets accepted.

Closes #38
2017-10-27 15:22:12 -07:00
Eliza Weisman
8a1c4d3d52 Add test and assertion for idle state handling (#160) 2017-10-27 14:14:00 -07:00
Carl Lerche
c23d11306e Add RecvStream::is_end_stream. (#165)
This function returns true if the `RecvStream` has reached an end of
stream state. This is intended to replace `is_empty` which has confusing
behavior.
2017-10-21 09:59:27 -07:00
Sean McArthur
75db186378 fix panic when a stream is canceled (#164) 2017-10-20 17:47:58 -07:00
Carl Lerche
c4fc2928fe API cleanup (#155)
* Change send_reset to take &mut self.

While calling this function is the last thing that should be done with
the instance, the intent of the h2 library is not to be used directly by
users, but to be used as an implementation detail by other libraries.

Requiring `self` on `send_reset` is pretty annoying when calling the
function from inside a `Future` implementation. Also, all the other fns
on the type take `&mut self`.

* Remove the P: Peer generic from internals

* Split out `Respond` from `server::Stream`

This new type is used to send HTTP responses to the client as well as
reserve streams for push promises.

* Remove unused `Send` helper.

This could be brought back later when the API becomes stable.

* Unite `client` and `server` types

* Remove `B` generic from internal proto structs

This is a first step in removing the `B` generic from public API types
that do not strictly require it.

Currently, all public API types must be generic over `B` even if they do
not actually interact with the send data frame type. The first step in
removing this is to remove `B` as a generic on all internal types.

* Remove `Buffer<B>` from inner stream state

This is the next step in removing the `B` generic from all public API
types. The send buffer is the only type that requires `B`. It has now
been extracted from the rest of the stream state.

The strategy used in this PR requires an additional `Arc` and `Mutex`,
but this is not a fundamental requirement. The additional overhead can
be avoided with a little bit of unsafe code. However, this optimization
should not be made until it is proven that it is required.

* Remove `B` generic from `Body` + `ReleaseCapacity`

This commit actually removes the generic from these two public API
types. Also note, that removing the generic requires that `B: 'static`.
This is because there is no more generic on `Body` and `ReleaseCapacity`
and the compiler must be able to ensure that `B` outlives all `Body` and
`ReleaseCapacity` handles.

In practice, in an async world, passing a non 'static `B` is never going
to happen.

* Remove generic from `ResponseFuture`

This change also makes generic free types `Send`. The original strategy
of using a trait object meant that those handles could not be `Send`.
The solution was to avoid using the send buffer when canceling a stream.
This is done by transitioning the stream state to `Canceled`, a new
`Cause` variant.

* Simplify Send::send_reset

Now that implicit cancelation goes through a separate path, the
send_reset function can be simplified.

* Export types common to client & server at root

* Rename Stream -> SendStream, Body -> RecvStream

* Implement send_reset on server::Respond
2017-10-19 20:02:08 -07:00
Carl Lerche
58c55564e2 Fix race in test (#157)
This fixes a race condition in a test that has been exposed by
CI.

This commit also disables code coverage checks as it has been
causing CI to hang. See #156.
2017-10-18 11:00:56 -07:00
Carl Lerche
faf59f7e24 Split response future from client::Stream (#153) 2017-10-16 20:17:07 -07:00
Carl Lerche
7c287af0d0 Fix some flow control bugs. (#152)
* Release stream capacity back to the connection to avoid capacity
leaks.
* Actually notify waiting tasks when capacity becomes available.
2017-10-13 14:15:20 -07:00
Sean McArthur
5c1bde7d62 add set_target_window_size methods to Server and Client (#149)
Closes #101
2017-10-13 11:19:56 -07:00
Eliza Weisman
2fcf8c3740 Add methods to {client, server}::Builder to set max concurrent streams (#150)
This PR adds `max_concurrent_streams()` methods to the client and server `Builder`s to set the `max_concurrent_streams` setting. I've added unit tests to ensure the correct SETTINGS frame is sent.

Closes #106
2017-10-10 17:36:45 -05:00
Carl Lerche
4c7ecf158d Add ReleaseCapacity handle. (#148)
This enables releasing stream capacity without having the `Body` handle.
2017-10-09 14:00:28 -07:00
Carl Lerche
56db50526d Don't unwrap logger init in tests 2017-10-09 13:10:52 -07:00
Sean McArthur
08a642ab11 fix ICE when compiling prioritization tests (#147) 2017-10-09 13:05:15 -07:00
Holt Chesley
2aee78c7d7 Issue 128: Convert frame::Reason to struct (#142)
Alter frame::Reason to a struct with a single u32 member.
Introduce Constants to the impl for existing Reasons. Change all usage
in the library and its tests to adopt this change,
using the new constants.
2017-10-08 13:13:07 -07:00
Sean McArthur
7b81be04aa reduce available window capacity when settings lowers window size 2017-10-06 14:20:32 -07:00
Sean McArthur
431442735d reset streams when receiving invalid psuedo headers 2017-10-06 13:48:30 -07:00
Sean McArthur
7d1732a70d change unimplemented to unreachable in handshake 2017-10-06 09:59:03 -07:00
Sean McArthur
720fb20bbf remove unused pieces from PingPong (#134)
Adds some extra tests as well, to be sure.
2017-10-05 19:16:14 -07:00
Eliza Weisman
2e3dcf602c StreamRef sends RST_STREAM on drop (#109)
This PR modifies the `Drop` implementation for `StreamRef` to reset the underlying stream if it is the last reference to that stream. Since both `Stream` and `Body` are internally just a `StreamRef`, this means they will both reset the stream on drop; thus, this closes #100.

The assertion that the store no longer contains the dropped stream ID at the end of the `Drop` method  had to be removed, as the stream has to be reset from inside of a `transition` block (which now manages releasing that ID for us), and the `transition` closure moves the value of `stream`, making the assertion no longer possible.

Modifications to some of the tests in `flow_control.rs` were also necessary, in order to prevent `StreamRef`s from being dropped too early.
2017-10-05 18:05:18 -05:00
Sean McArthur
ecd2764f4b when receiving a GOAWAY, allow earlier streams to still process (#133)
Once all active streams have finished, send a GOAWAY back and close the
connection.
2017-10-05 15:32:13 -07:00
Sean McArthur
c4ca8f7def Client::poll_ready and send_request may return Connection Errors (#132)
Closes #131
2017-10-04 15:22:10 -07:00
Sean McArthur
f8efb053b9 split Client into (Client, Connection) (#107)
The Connection type is a `Future` that drives all of the IO of the
client connection.

The Client type is separate, and is used to send requests into the
connection.
2017-09-28 16:55:12 -07:00
Oliver Gould
0b289fd55d Fix stream-id double-accounting bug (#112)
Both Recv::open and Rev::recv_headers check new stream ids against the
previously stream id. The second such check fails.

Now, only Recv::open performs stream id checks.

Fixes #110
2017-09-26 10:42:12 -07:00
Carl Lerche
8911ee2a4b Remove h2-test-support crate (#119)
The h2-test-support caused the unstable flag to always be enabled.
2017-09-25 22:28:39 -07:00
Oliver Gould
b99c513334 Apply rustfmt to test/support crate (#116) 2017-09-25 08:29:54 -07:00
Oliver Gould
dad113e17b Disallow nightly failures (#115)
Always install rustfmt since nightly may change underneath it, causing
linking to break.

Apply rustfmt
2017-09-24 19:25:50 -07:00
Eliza Weisman
a72a6bc8f0 Rewrite flow control tests to use newer mock API (#108)
I've rewritten the tests `flow_control::stream_close_by_data_frame_releases_capacity()` and `flow_control::stream_close_by_trailers_frame_releases_capacity()` to use the new mock API. This will make modifying these tests a bit easier in order to expect the correct behavior in my reset-on-drop branch.
2017-09-21 12:58:50 -05:00
Sean McArthur
6ec7f38cd7 add test for client sending over max concurrent limit (#105) 2017-09-19 15:31:35 -07:00
Sean McArthur
db8c109817 Client::poll_ready() returns an Error if next stream ID would overflow (#103)
Closes #102
2017-09-19 14:16:32 -07:00