Commit Graph

189 Commits

Author SHA1 Message Date
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
8a1c4d3d52 Add test and assertion for idle state handling (#160) 2017-10-27 14:14:00 -07:00
Eliza Weisman
6a0800d7a4 Clear up unreachable message (#161) 2017-10-21 13:00:15 -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
Eliza Weisman
1e126aa752 Unbox server handshake future (#52)
Server-side version of #42. I've rewritten `server::Handshake` as a hand-rolled `Future` rather than as a `Box<Future>`. In addition to removing a `Box`, this also means that the `'static` lifetime bounds on the type parameters `T` and `B` can be removed.

The type of the server handshake future is somewhat more complex than the client-side handshake future. Note also that I've had to re-export `proto::streams::Prioritized` as `pub(crate)` from `proto`, as it appears in the type of the handshake future.

I've ran the tests against this branch and everything passes. Since no new functionality was added, I haven't added any additional tests.

This also fixes #158 - I had accidentally committed a Darwin h2spec executable and that's what was breaking CI.
2017-10-19 12:21:13 -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
Oliver Gould
80e3478c00 Use remote window size for send flow control (#145)
The initial window size of both the send and recv flow controllers are
configured from the same setting. The send flow controller should be
configured from the remote's initial window size.
2017-10-09 15:16:22 -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
bc679035f9 remove panic from Debug of StreamRef is mutex is poisoned 2017-10-06 14:20:32 -07:00
Sean McArthur
7b81be04aa reduce available window capacity when settings lowers window size 2017-10-06 14:20:32 -07:00
Sean McArthur
9737d0c6a0 convert several unimplemented into proper asserts 2017-10-06 09:59:03 -07:00
Sean McArthur
38900df185 reset stream if invalid content-length received 2017-10-06 09:59:03 -07:00
Sean McArthur
447102beeb return PayloadTooBig if user calls send_data with buffer over max window size 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
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
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
Sean McArthur
0c8bd75224 check for StreamId overflow (#68) 2017-09-19 13:10:48 -07:00
Sean McArthur
a8a4cd2be1 add Client config to disable server push
- Adds `Client::builder().enable_push(false)` to disable push
- Client sends a GO_AWAY if receiving a push when it's disabled
2017-09-18 10:49:35 -07:00
Carl Lerche
f84a1bdd1f Notify connection on connection window expansion (#86)
When capacity is released back to the connection and a connection level
window update needs to be sent out, the connection task needs to be
notified in order for the send to actually happen.
2017-09-14 13:50:52 -07:00
Sean McArthur
3ec0e85e56 add test when stream window overflows before conn window 2017-09-13 14:32:27 -07:00
Sean McArthur
e2cda1860b fix Body to return errors when there is recv error 2017-09-13 14:32:27 -07:00
Sean McArthur
ed472f109c add client::Builder to configure Clients 2017-09-13 14:32:27 -07:00
Sean McArthur
d0afe30ab3 fix recv connection flow should always use default initial window size 2017-09-13 14:32:27 -07:00
Sean McArthur
f7d14861e5 rustfmt: add trailing commas in match arms, set fn call to block stle (#85) 2017-09-12 19:29:06 -07:00
Oliver Gould
897bf84163 Use rustfmt to enforce consistent formatting
This change adds a .rustfmt.toml that includes ALL supported settings,
12 of which we have overridden to attempt to cater to our own
proclivities.

rustfmt is checked in the rust-nightly CI job.
2017-09-12 22:29:35 +00:00
Carl Lerche
93925e6d1f Limit send flow control bug to window_size (#78)
Senders could set the available capacity greater than the current
`window_size`.  This caused a panic when the sender attempted
to send more than the receiver could accept.
2017-09-12 10:48:11 -07:00
Eliza Weisman
9448a19408 Factor out reset on RecvError::Stream (#76) 2017-09-11 13:07:37 -07:00
Carl Lerche
5c0efcf8c4 Ref count stream state and release when final (#73)
Previously, stream state was never released so that long-lived connections
leaked memory.

Now, stream states are reference-counted and freed from the stream slab
when complete.  Locally reset streams are retained so that received frames
may be ignored.
2017-09-10 16:01:19 -07:00
Oliver Gould
17bebe719a Increment stream window capacity when sending window update (#67) 2017-09-08 12:24:06 -07:00
Carl Lerche
c47717204c Flow control bug fix (#70)
The requested capacity was not decreased as data is written.
2017-09-08 12:15:46 -07:00
Carl Lerche
ae6bad6cef Fix some flow control bugs
When a stream is closed, connection level capacity should be released
back to the connection and then assigned to other streams waiting for
capacity.
2017-09-07 16:45:20 -07:00
Carl Lerche
38bbf30b2f Fix bug in prioritization (#63)
The stream buffered data counter was never decremented.
2017-09-07 14:12:21 -07:00
Sean McArthur
09744f38ef add a ReleaseCapacityTooBig variant to UserError 2017-09-07 08:20:03 -07:00
Sean McArthur
452e49dc3e aggregate WINDOW_UPDATE frames until change is over 50% available 2017-09-07 08:20:03 -07:00
Carl Lerche
0cc611df35 Add Codec::set_max_send_frame_size 2017-09-05 14:01:32 -07:00
Carl Lerche
c2e6eb35d8 Track HTTP crate 2017-09-05 10:21:31 -07:00
Carl Lerche
b4fa5134f9 Data frame (#50)
* Rename DataFlag -> DataFlags
* Polish Data frame API
2017-09-05 10:00:05 -07:00
Carl Lerche
c122e97127 Refactor errors (#46)
This patch does a bunch of refactoring, mostly around error types, but it also
paves the way to allow `Codec` to be used standalone.

* `Codec` (and `FramedRead` / `FramedWrite`) is broken out into a codec module.
* An h2-codec crate is created that re-exports the frame and codec modules.
* New error types are introduced in the internals:
  * `RecvError` represents errors caused by trying to receive a frame.
  * `SendError` represents errors caused by trying to send a frame.
  * `UserError` is an enum of potential errors caused by invalid usage
    by the user of the lib.
  * `ProtoError` is either a `Reason` or an `io::Error`. However it doesn't
    specify connection or stream level.
  * `h2::Error` is an opaque error type and is the only error type exposed
    by the public API (used to be `ConnectionError`).

There are misc code changes to enable this as well. The biggest is a new "sink"
API for `Codec`. It provides buffer which queues up a frame followed by flush
which writes everything that is queued. This departs from the `Sink` trait in
order to provide more accurate error values. For example, buffer can never fail
(but it will panic if `poll_ready` is not called first).
2017-09-02 11:12:50 -07:00
Carl Lerche
6fd9674759 Validate received content-length header (#43)
If a content-length header is provided, the value should match the sum
of all data frame lengths. If there is a mismatch, then the stream is
reset.
2017-08-31 12:40:02 -04:00
Carl Lerche
2452cc4423 Validate & convert messages before buffering
Malformed requests and responses should immediately result in a
RST_STREAM. To support this, received header frames are validated and
converted to Request / Response values immediately on receipt and before
buffering.
2017-08-30 18:16:21 -04:00
Carl Lerche
9bb34d907a Thread P generic through all 2017-08-30 18:16:21 -04:00