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
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.
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
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.
* 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
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.
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
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.
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.
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.
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
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.
- Adds `max_frame_size` to client and server builders
- Pushes max_frame_size into Codec
- Detects when the Codec triggers an error from a frame too big
- Sends a GOAWAY when FRAME_SIZE_ERROR is encountered reading a frame
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.
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.
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.