Commit Graph

54 Commits

Author SHA1 Message Date
Anthony Ramine
465f0337f8 Refactor errors internals (#556)
h2::Error now knows whether protocol errors happened because the user
sent them, because it was received from the remote peer, or because
the library itself emitted an error because it detected a protocol
violation.

It also keeps track of whether it came from a RST_STREAM or GO_AWAY
frame, and in the case of the latter, it includes the additional
debug data if any.

Fixes #530
2021-09-28 09:04:35 -07:00
Anthony Ramine
61b4f8fc34 Support very large headers
This completely refactors how headers are hpack-encoded.

Instead of trying to be clever, constructing frames on the go
while hpack-encoding, we just make a blob of all the
hpack-encoded headers first, and then we split that blob
in as many frames as necessary.
2021-09-08 10:20:30 -07:00
Yuchen Wu
11229702a0 Return an error instead of panicking when stuck in a CONTINUATION loop
It is not rare a large header can trigger such a CONTINUATION loop.
While the stream cannot recover from this issue, returning an error
instead of panicking makes the impact radius under better control.
2021-02-26 10:08:17 -08:00
Josh Soref
bcaaaf6dd9 Spelling fixes in comments (#508) 2021-02-25 08:59:18 -08:00
Markus Westerlind
30ca832790 Make some functions less-generic to reduce binary bloat (#503)
* refactor: Extract FramedWrite::buffer to a less generic function

Should cut out another 23 KiB (since I see it duplicated)

* refactor: Extract some duplicated code to a function

* refactor: Extract part of flush into a less generic function

* refactor: Extract a less generic part of connection

* refactor: Factor out a less generic part of Connection::poll2

* refactor: Extract a non-generic part of handshake2

* refactor: Don't duplicate Streams code on Peer (-3.5%)

The `P: Peer` parameter is rarely used and there is already a mechanism
for using it dynamically.

* refactor: Make recv_frame less generic (-2.3%)

* Move out part of Connection::poll

* refactor: Extract parts of Connection

* refactor: Extract a non-generic part of reclaim_frame

* comments
2021-02-18 11:17:49 -08:00
Kornel
6357e3256a de-generify FramedRead::decode_frame (#509)
* de-generify FramedRead::decode_frame

* Rename arg to decode_frame

Co-authored-by: Dan Burkert <dan@danburkert.com>
2021-02-16 12:21:29 -08:00
Sean McArthur
b4976675fa Update to Tokio and Bytes 1.0 (#504) 2020-12-23 10:01:44 -08:00
Eliza Weisman
73bf6a61ad re-enable vectored writes (#500)
Tokio's AsyncWrite trait once again has support for vectored writes in
Tokio 0.3.4 (see tokio-rs/tokio#3149.

This branch re-enables vectored writes in h2.

This change doesn't make all that big of a performance improvement in
Hyper's HTTP/2 benchmarks, but they use a BytesMut as the buffer.
With a buffer that turns into more IO vectors in bytes_vectored, there
might be a more noticeable performance improvement.

I spent a bit trying to refactor the flush logic to coalesce into fewer
writev calls with more buffers, but the current implementation seems
like about the best we're going to get without a bigger refactor. It's
basically the same as what h2 did previously, so it's probably fine.
2020-11-23 16:35:48 -08:00
Paolo Barbolini
5a92f256c0 Upgrade to bytes 0.6 (#497)
* Upgrade to bytes 0.6

* Update Cargo.toml

Co-authored-by: Eliza Weisman <eliza@buoyant.io>

* Update tests/h2-support/Cargo.toml

Co-authored-by: Eliza Weisman <eliza@buoyant.io>

Co-authored-by: Eliza Weisman <eliza@buoyant.io>
2020-11-19 14:38:56 -08:00
João Oliveira
cbbdd305b1 update to tokio 0.3 (#491) 2020-10-23 10:45:09 -07:00
eggyal
2b19acf132 Handle client-disabled server push (#486) 2020-09-17 17:25:31 -07:00
Eliza Weisman
fc7f63f641 start adding tracing spans to internals (#478)
We've adopted `tracing` for diagnostics, but currently, it is just being
used as a drop-in replacement for the `log` crate. Ideally, we would
want to start emitting more structured diagnostics, using `tracing`'s
`Span`s and structured key-value fields.

A lot of the logging in `h2` is already written in a style that imitates
the formatting of structured key-value logs, but as textual log
messages. Migrating the logs to structured `tracing` events therefore is
pretty easy to do. I've also started adding spans, mostly in the read
path.

Finally, I've updated the tests to use `tracing` rather than
`env_logger`. The tracing setup happens in a macro, so that a span for
each test with the test's name can be generated and entered. This will
make the test output easier to read if multiple tests are run
concurrently with `--nocapture`.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2020-08-17 17:29:22 -07:00
David Barsky
d3b9f1e36a feat(lib): switch from log to tracing (#475) 2020-07-07 15:55:24 -07:00
Sean McArthur
e41a1f130c Respect SETTINGS_HEADER_TABLE_SIZE (#459) 2020-03-30 11:53:22 -07:00
Sean McArthur
74d02933a5 Fix warnings about deprecated Error::description 2020-01-29 15:55:28 -08:00
Sean McArthur
ec751f3696 Remove Unpin requirement for the send Buf 2019-12-06 11:40:08 -08:00
Sean McArthur
4398e169e8 Update to Tokio 0.2 (#428) 2019-11-27 14:53:57 -08:00
Sean McArthur
4c1d797712 Add ability to adjust INITIAL_WINDOW_SIZE setting on an existing connection (#421) 2019-10-07 15:29:23 -07:00
Sean McArthur
2d90efee17 Prune futures-* dependencies 2019-08-30 14:53:49 -07:00
Sean McArthur
f31ec5d0da Remove deprecated-in-0.1.x APIs 2019-08-20 15:15:04 -07:00
Gurwinder Singh
f46840f3fa chore: cargo fmt, clippy 2019-08-16 22:27:39 -07:00
Gurwinder Singh
ad7ffa795f Updated as per review comments 2019-08-16 18:47:47 -07:00
Gurwinder Singh
c8fefd49f1 Update lib to std-future 2019-08-16 18:47:47 -07:00
Jakub Beránek
db6b841e67 Update crate to Rust 2018 (#383) 2019-07-23 10:18:43 -07:00
Eliza Weisman
0e9fbe4a90 Log protocol error causes at debug (#371)
Currently, there are many cases where `h2` will fail a connection or
stream with a PROTOCOL_ERROR, without recording why the protocol error
occurred. Since protocol errors may result from a bug in `h2` or from a
misbehaving peer, it is important to be able to debug the cause of
protocol errors.

This branch adds a log line to almost all cases where a protocol error
occurs. I've tried to make the new log lines consistent with the
existing logging, and in some cases, changed existing log lines to make
them internally consistent with other log lines in that module. All
receive-side errors that would send a reset are now logged at the debug
level, using a formatting based on the format used in `framed_read`.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2019-06-17 14:14:40 -07:00
Sean McArthur
6ebad4bb41 increase write buffer size to 16kb 2019-05-29 17:19:55 -07:00
Sean McArthur
91819bf25e check for overly large header field in send_headers 2019-05-29 17:19:55 -07:00
Sean McArthur
e512b6ccb6 panic if stuck in a CONTINUATION frame write loop 2019-05-29 17:19:55 -07:00
Sean McArthur
e3a73f726e Add user PING support (#346)
- Add `share::PingPong`, which can send `Ping`s, and poll for the `Pong`
  from the peer.
2019-02-18 15:59:11 -08:00
Carl Lerche
9bbbe7ebd5 Disable length_delimited deprecation warning. (#321)
Until tokio-rs/tokio#680 is resolved, we should allow using deprecated
APIs in the codec module.
2018-10-16 08:21:23 -07:00
Sean McArthur
3a4633d205 add SendResponse::poll_reset and SendStream::poll_reset to listen for reset streams (#279) 2018-05-30 22:57:43 +02:00
Carl Lerche
bb454e017c Enforce monotonic stream IDs for push promises (#275)
Previously, monotonic stream IDs (spec 5.1.1) for push promises were not
enforced. This was due to push promises going through an entirely
separate code path than normally initiated streams.

This patch unifies the code path for initializing streams via both
HEADERS and PUSH_PROMISE. This is done by first calling `recv.open` in
both cases.

Closes #272
2018-05-14 10:20:57 -07:00
Sean McArthur
1c5d4ded50 Add Graceful Shutdown support
If graceful shutdown is initiated, a GOAWAY of the max stream ID - 1 is
sent, followed by a PING frame, to measure RTT. When the PING is ACKed,
the connection sends a new GOAWAY with the proper last processed stream
ID. From there, once all active streams have completely, the connection
will finally close.
2018-03-29 13:51:30 -07: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
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
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
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
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
c4ca8f7def Client::poll_ready and send_request may return Connection Errors (#132)
Closes #131
2017-10-04 15:22:10 -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
0c8bd75224 check for StreamId overflow (#68) 2017-09-19 13:10:48 -07:00
Sean McArthur
21f7e54ce8 load headers when receiving PushPromise frames 2017-09-18 10:49:35 -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
Sean McArthur
92030f634f remove unstable for Codec methods used internally 2017-09-17 14:28:45 -07:00
Sean McArthur
c32015d48e add support for configuring max frame size
- 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
2017-09-14 17:03:43 -07:00
Carl Lerche
b01e3dff12 Annotate unstable API fns with cfg 2017-09-13 14:14:41 -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
11de86b34e Make Codec max frame length configurable (#57) 2017-09-11 12:56:40 -07:00