Using `time::Tm` directly in HTTP header fields requires special handling to parse and format
the header values., this stops us from using the header macros. By wrapping `time::Time` in a
`HttpDate`, we can use the `FromStr` and `Display` traits of `HttpDate` like for most other values.
BREAKING_CHANGE: All code using one of the `Date`, `Expires`, `If-Modified-Since`,
`If-Unmodified-Since`, `Last-Modified` header fields needs to wrap `time::Tm`
with `HttpDate`. Removed `FromStr` trait of `Date`, `If-Modified-Sice` and `If-Unmodified-Sice`,
implementing the trait here is inconsistent with other headers.
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.
All instances of `old_io` and `old_path` were switched to use the new
shiny `std::io`, `std::net`, and `std::path` modules. This means that
`Request` and `Response` implement `Read` and `Write` now.
Because of the changes to `TcpListener`, this also takes the opportunity
to correct the method usage of `Server`. As with other
languages/frameworks, the server is first created with a handler, and
then a host/port is passed to a `listen` method. This reverses what
`Server` used to do.
Closes#347
BREAKING CHANGE: Check the docs. Everything was touched.
Change AcceptorPool to not spawn detached threads anymore. This,
together with the recent `Send` changes, allows the `work` closure to
close over non-`'static` data.
This doesn't change the high-level `Server` interface, because that
would make it's `listen` a blocking call (it's currently non-blocking)
- which would be a breaking change.
This is a modified and specialized thread pool meant for
managing an acceptor in a multi-threaded way. A single handler
is provided which will be invoked on each stream.
Unlike the old thread pool, this returns a join guard which
will block until the acceptor closes, enabling friendly behavior
for the listening guard.
The task pool itself is also faster as it only pays for message passing
if sub-threads panic. In the optimistic case where there are few panics,
this saves using channels for any other communication.
This improves performance by around 15%, all the way to 105k req/sec
on my machine, which usually gets about 90k.
BREAKING_CHANGE: server::Listening::await is removed.
Currently headers are exported at many places. For example you can access
`Transfer-Encoding` header at `header`, `header::common` and
`header::common::transfer_encoding`. Per discussion on IRC with
@seanmonstar and @reem, all contents of headers will be exposed at `header`
directly. Parsing utilities will be exposed at `header::parsing`. Header
macros can now be used from other crates.
This breaks much code using headers. It should use everything it needs
directly from `header::`, encodings are exposed at `header::Encoding::`,
connection options are exposed at `header::ConnectionOption`.
Implements the missing enum cases in Http* and adds a new
method to the default Server implementation to take advantage
of the new TLS support
Closes#1
- Some stray deriving -> derive changes
- use::{mod} -> use::{self}
- fmt.write -> fmt.write_str
This does not catch the last case of fmt.write_str in the
Show impl of a Header Item. This will need to be changed
separately.
- Includes ergonomic traits like IntoUrl and IntoBody, allowing easy
usage.
- Client can have a RedirectPolicy.
- Client can have a SslVerifier.
Updated benchmarks for client. (Disabled rust-http client bench since it
hangs.)
Internals have been shuffled around such that Request and Reponse are
now given only a mutable reference to the stream, instead of being
allowed to consume it. This allows the server to re-use the streams if
keep-alive is true.
A task pool is used, and the number of the threads can currently be
adjusted by using the `listen_threads()` method on Server.
[breaking-change]