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.
If a client sent an illegal request (like a GET request with a message
body), or if there was a legal request with a body but the Handler
didn't read all of it, the remaining bytes would be left in the stream.
The next request to come from the same client would error, as the server
would confuse the remaining bytes, and think the request was malformed.
Fixes#197Fixes#309
As discussed in #177 hyper must support status code outside the
standard range for compatibility reasons.
BREAKING CHANGE: This removes unregistered status codes from the enum. Use
`FromPrimitive` methods to create them now. StatusCode and StatusClass can no
longer be casted to `u16`, use `ToPrimitive` methods now.
For example `status.to_u16().unwrap()` to get the status code number.
HttpAcceptor::accept()'s HTTPS logic passes IO errors from the underlying
SSL stream directly to the caller. Furthermore, the caller uses the
EndOfFile error code to detect that the server should stop accepting
connections. This means that if the TCP connection was succesfully
accepted, but an EOF condition was detected during the handshake, the
server will stop accepting connections and quit. This allows for a
trivial denial of service attack and can happen accidentally as well.
Change HttpAcceptor::accept such that if the TCP stream underlying
the SSL stream returns an IoError error, a ConnectionAborted IoError
is returned instead. This allows distinguishing between IoErrors from
the acceptor and the stream. The original error reason is stored in the
detail field.
Add the HTTP/1.1 `If-None-Match` header field makes the request method conditional
on a recipient cache or origin server either not having any current
representation of the target resource, when the field-value is "*",
or having a selected representation with an entity-tag that does not
match any of those listed in the field-value.
Closes#238
It turns out, we don't need capabilities of MuCell (or even RefCell).
We don't to have sophisticated interior mutability. We don't ever lend
out references that may be mutated later. Instead, if there is no value
to lend, then we generate the value, require interior mutability to save
the value internally, and then we return a reference. We never ever
change a value once it's been generated. It can be changed, but only via
&mut self methods, where we can safely reason about mutability.
This means we don't need keep borrow checking code at runtime, which
helps performance. We also are able to reduce the amount of unsafe
transmutes. The internal API more safely constrains the usage of unsafe,
enforcing our invariants, instead of shotgunning unsafe usage with Refs
and promising we're doing it correctly.
On a machine with lower memory (1GB):
Before:
test bench_mock_hyper ... bench: 251772 ns/iter (+/- 128445)
After:
test bench_mock_hyper ... bench: 152603 ns/iter (+/- 25928)
On a machine with more memory, weaker CPU:
Before:
test bench_mock_hyper ... bench: 129398 ns/iter (+/- 51740)
After:
test bench_mock_hyper ... bench: 115935 ns/iter (+/- 28555)
Closes#252
Allow use of EntityTag in other headers that use entity tags.
BREAKING CHANGE: for any consumers of the Etag header, since the entity
tag is now in a tuple.