This commit updates to the most recent versions (released today) of the various
Tokio libraries in use. Namely the `tokio_core::io` module has now been
deprecated in favor of an external `tokio-io` crate. This commit pulls in that
crate and uses the `AsyncRead + AsyncWrite` abstraction instead of `Io` from
tokio-core.
BREAKING CHANGE: Any external types that were using that had implemented `Io` will need to
implement `AsyncRead + AsyncWrite` from tokio_io.
This implements `From<Message> for Request` and `Into<Message> for
Response`, allowing an `Http` instance to be used with a `TcpServer`
from tokio-proto.
Closes#1036
BREAKING CHANGE: This makes `Request.remote_addr` an
`Option<SocketAddr>`, instead of `SocketAddr`.
The main changes are:
* The entry point is how `Http`, the implementation of `ServerProto`.
This type has a `new` constructor as well as builder methods to
configure it.
* A high-level entry point of `Http::bind` was added which returns a
`Server`. Binding a protocol to a port requires a socket address
(where to bind) as well as the instance of `NewService`. Internally
this creates a core and a TCP listener.
* The returned `Server` has a few methods to learn about itself, e.g.
`local_addr` and `handle`, but mainly has two methods: `run` and
`run_until`.
* The `Server::run` entry point will execute a server infinitely, never
having it exit.
* The `Server::run_until` method is intended as a graceful shutdown
mechanism. When the provided future resolves the server stops
accepting connections immediately and then waits for a fixed period of
time for all active connections to get torn down, after which the
whole server is torn down anyway.
* Finally a `Http::bind_connection` method exists as a low-level entry
point to spawning a server connection. This is used by `Server::run`
as is intended for external use in other event loops if necessary or
otherwise low-level needs.
BREAKING CHANGE: `Server` is no longer the pimary entry point. Instead,
an `Http` type is created and then either `bind` to receiver a `Server`,
or it can be passed to other Tokio things.
There are many changes involved with this, but let's just talk about
user-facing changes.
- Creating a `Client` and `Server` now needs a Tokio `Core` event loop
to attach to.
- `Request` and `Response` both no longer implement the
`std::io::{Read,Write}` traits, but instead represent their bodies as a
`futures::Stream` of items, where each item is a `Chunk`.
- The `Client.request` method now takes a `Request`, instead of being
used as a builder, and returns a `Future` that resolves to `Response`.
- The `Handler` trait for servers is no more, and instead the Tokio
`Service` trait is used. This allows interoperability with generic
middleware.
BREAKING CHANGE: A big sweeping set of breaking changes.
We've been seeing a strange number of timeouts in our benchmarking.
Handling spurious timeouts as in this patch seems to fix it!
Note that managing the `timeout_start` needs to be done carefully. If
the current time is provided in the wrong place, it's possible requests
would never timeout.
I've had a couple of instances during stress testing now where
Conn::ready would overflow its stack due to recursing on itself. This
moves subsequent calls to ready() into a loop outside the function.
Methods added to `Client` and `Server` to control read and write
timeouts of the underlying socket.
Keep-Alive is re-enabled by default on the server, with a default
timeout of 5 seconds.
BREAKING CHANGE: This adds 2 required methods to the `NetworkStream`
trait, `set_read_timeout` and `set_write_timeout`. Any local
implementations will need to add them.
While these methods are marked unstable in libstd, this is behind a
feature flag, `timeouts`. The Client and Server both have
`set_read_timeout` and `set_write_timeout` methods, that will affect all
connections with that entity.
BREAKING CHANGE: Any custom implementation of NetworkStream must now
implement `set_read_timeout` and `set_write_timeout`, so those will
break. Most users who only use the provided streams should work with
no changes needed.
Closes#315
BREAKING CHANGE: Server::https was changed to allow any implementation
of Ssl. Server in general was also changed. HttpConnector no longer
uses SSL; using HttpsConnector instead.
The old names followed the old style of including the module name and
"Error" in each variant. The new style is to refer to an error from its
owning module, and variants are now scoped to their enum, so there's no
need to include the enum name in the variant name.
BREAKING CHANGE: The terms `Http` and `Error` have been removed from the Error
type and its variants. `HttpError` should now be accessed as `hyper::Error`,
and variants like `HttpIoError` should be accessed as `Error::Io`.
This adds a connection pool to the Client that is used by default. It
accepts any other NetworkConnector, and simply acts as a
NetworkConnector itself. Other Pools can exist by simply providing a
custom NetworkConnector. This Pool is only used by default if you also
use the default connector, which is `HttpConnector`. If you wish to use
the Pool with a custom connector, you'll need to create the Pool with
your custom connector, and then pass that pool to the
Client::with_connector.
This also adds a method to `NetworkStream`, `close`, which can be used
to know when the Stream should be put down, because a server requested
that the connection close instead of be kept alive.
Closes#363Closes#41
Allow a Server to operate without requiring the entire Server struct
to move into the with_listener function (instead only the handler
function needs to move). This, allows other members to not move, or
move separately, which will be needed for the next commit. See #471
This includes a custom BufReader, since the one in libstd doesn't allow
reading additional data into the buffer without consuming it. This is
required because some connections may send shorter packets, and so we
need to perform multiple reads. After each read, the contents of the
buffer are passed to httparse to see if have a valid message. If so, the
proper amount of bytes are consumed. The additional bytes are left in
the buffer since they are the beginning of the body.
The buffer in this BufReader also grows in size, compared to the libstd
which is sized once. This is because we start with a smaller buffer,
since the majority of messages will be able to include their head in a
packet or 2. Therefore, it's a wasteful performance hit to allocate the
maximum size for every message. However, some headers can be quite big,
and to allow for many of them to be set, we include a maximum size. Once
we've hit the maximum buffer size, and still haven't determined the end
of the headers, a HttpTooLargeError will be returned.
Closes#389
httparse is a http1 stateless push parser. This not only speeds up
parsing right now with sync io, but will also be useful for when we get
async io, since it's push based instead of pull.
BREAKING CHANGE: Several public functions and types in the `http` module
have been removed. They have been replaced with 2 methods that handle
all of the http1 parsing.