feat(http1): Add higher-level HTTP upgrade support to Client and Server (#1563)

- Adds `Body::on_upgrade()` that returns an `OnUpgrade` future.
- Adds `hyper::upgrade` module containing types for dealing with
  upgrades.
- Adds `server::conn::Connection::with_upgrades()` method to enable
  these upgrades when using lower-level API (because of a missing
  `Send` bound on the transport generic).
- Client connections are automatically enabled.
- Optimizes request parsing, to make up for extra work to look for
  upgrade requests.
  - Returns a smaller `DecodedLength` type instead of the fatter
    `Decoder`, which should also allow a couple fewer branches.
  - Removes the `Decode::Ignore` wrapper enum, and instead ignoring
    1xx responses is handled directly in the response parsing code.

Ref #1563 

Closes #1395
This commit is contained in:
Sean McArthur
2018-06-14 13:39:29 -07:00
committed by GitHub
parent 1c3fbfd6bf
commit fea29b29e2
26 changed files with 1271 additions and 574 deletions

View File

@@ -79,6 +79,7 @@ pub struct AsyncIo<T> {
inner: T,
max_read_vecs: usize,
num_writes: usize,
panic: bool,
park_tasks: bool,
task: Option<Task>,
}
@@ -93,6 +94,7 @@ impl<T> AsyncIo<T> {
inner: inner,
max_read_vecs: READ_VECS_CNT,
num_writes: 0,
panic: false,
park_tasks: false,
task: None,
}
@@ -110,6 +112,11 @@ impl<T> AsyncIo<T> {
self.error = Some(err);
}
#[cfg(feature = "nightly")]
pub fn panic(&mut self) {
self.panic = true;
}
pub fn max_read_vecs(&mut self, cnt: usize) {
assert!(cnt <= READ_VECS_CNT);
self.max_read_vecs = cnt;
@@ -185,6 +192,7 @@ impl<S: AsRef<[u8]>, T: AsRef<[u8]>> PartialEq<S> for AsyncIo<T> {
impl<T: Read> Read for AsyncIo<T> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
assert!(!self.panic, "AsyncIo::read panic");
self.blocked = false;
if let Some(err) = self.error.take() {
Err(err)
@@ -201,6 +209,7 @@ impl<T: Read> Read for AsyncIo<T> {
impl<T: Write> Write for AsyncIo<T> {
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
assert!(!self.panic, "AsyncIo::write panic");
self.num_writes += 1;
if let Some(err) = self.error.take() {
trace!("AsyncIo::write error");
@@ -233,6 +242,7 @@ impl<T: Read + Write> AsyncWrite for AsyncIo<T> {
}
fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
assert!(!self.panic, "AsyncIo::write_buf panic");
if self.max_read_vecs == 0 {
return self.write_no_vecs(buf);
}