- Placed all cases of "unexpected bytes" errors into the
`UnexpectedMessage` variant.
- Placed all cases of "unexpected EOF" errors into the
`IncompleteMessage` variant. Description is now generic about
"connection closed before message completed", instead of mentioning
"request" or "response.
- Added `Error::is_incomplete_message()` accessor to help checking for
unexpected closures.
- Renamed some variants to be clearer when viewing the `Debug` format.
- Collected all "user" errors into an internal `User` enum, to prevent
forgetting to update the `is_user()` method.
The `Error::source()` is searched for an `h2::Error` to allow sending
different error codes in the GOAWAY. If none is found, it defaults to
`INTERNAL_ERROR`.
The default read strategy for HTTP/1 connections is now adaptive. It
increases or decreases the size of the read buffer depending on the
number of bytes that are received in a `read` call. If a transport
continuously fills the read buffer, it will continue to grow (up to the
`max_buf_size`), allowing for reading faster. If the transport
consistently only fills a portion of the read buffer, it will be shrunk.
This doesn't provide much benefit to small requests/responses, but
benchmarks show it to be a noticeable improvement to throughput when
streaming larger bodies.
Closes#1708
This option determines whether a read EOF should close the connection
automatically. The behavior was to always allow read EOF while waiting
to respond, so this option has a default of `true`.
Setting this option to `false` will allow Service futures to be canceled
as soon as disconnect is noticed.
Closes#1716
If the Response was received and the body finished while the Request
body was still streaming, the connection could get into a state where it
was never polled again, thus never re-inserting into the connection pool
or being dropped.
Closes#1717
Until this commit, servers have required that `Service` and their
`Future` to be `Send`, since the server needs to spawn some internal
tasks to an executor, and by default, that is `tokio::spawn`, which
could be spawning to a threadpool. This was true even if the user were
certain there was no threadpool involved, and was instead using a
different single-threaded runtime, like
`tokio::runtime::current_thread`.
This changes makes all the server pieces generic over an `E`, which is
essentially `Executor<PrivateTypes<Server::Future>>`. There's a new set
of internal traits, `H2Exec` and `NewSvcExec`, which allow for the type
signature to only show the generics that the user is providing. The
traits cannot be implemented explicitly, but there are blanket
implementations for `E: Executor<SpecificType>`. If the user provides
their own executor, it simply needs to have a generic `impl<F>
Executor<F> for MyExec`. That impl can have bounds deciding whether to
require `F: Send`. If the executor does require `Send`, and the
`Service` futures are `!Send`, there will be compiler errors.
To prevent a breaking change, all the types that gained the `E` generic
have a default type set, which is the original `tokio::spawn` executor.
rustc issue: https://github.com/rust-lang/rust/issues/55105
Steps to reproduce:
```
rustup target add armv7-linux-androideabi
RUSTFLAGS="-Ctarget-feature=+neon" cargo build --target armv7-linux-androideabi --release
```
Output without this change:
```
Compiling hyper v0.12.11 (/home/simon/projects/servo-deps/hyper)
LLVM ERROR: ran out of registers during register allocation
error: Could not compile `hyper`.
```
Change behaviour of connection or server response when the request is
version 1.0 and the Connection: keep-alive header is not present.
1. If the response is also version 1.0, then connection is closed if the
server keep-alive header is not present.
2. If the response is version 1.1, then the keep-alive header is added
when downgrading to version 1.0.
Closes#1614
If a user makes use of `Body::is_end_stream` to optimize so as to not
need to do make a final poll just to receive `None`, previously the
connection would not have progressed its reading state to a finished
body, and so the connection would be closed.
Now, upon reading any chunk, the connection state will check if it
can know that the body would be finished, and progresses to a body
finished state sooner.
The integration tests were amplified by adding a naive hyper proxy
as a secondary test, which happens to make use of that optimization,
and thus caught the issue.