Reclose connection on unread data. Minimum nightly is 1.19.

This commit is contained in:
Sergio Benitez 2017-05-13 02:00:35 -07:00
parent 781477fff1
commit 9a7484f7a8
7 changed files with 36 additions and 42 deletions

View File

@ -8,7 +8,7 @@ use ansi_term::Color::{Red, Yellow, Blue, White};
use version_check::{is_nightly, is_min_version};
// Specifies the minimum nightly version needed to compile Rocket.
const MIN_VERSION: &'static str = "1.16.0-nightly";
const MIN_VERSION: &'static str = "1.19.0-nightly";
// Convenience macro for writing to stderr.
macro_rules! printerr {

View File

@ -5,7 +5,7 @@ use std::time::Duration;
#[cfg(feature = "tls")] use super::net_stream::HttpsStream;
use super::data_stream::DataStream;
use super::data_stream::{DataStream, kill_stream};
use super::net_stream::NetStream;
use ext::ReadExt;
@ -17,7 +17,7 @@ use http::hyper::net::{HttpStream, NetworkStream};
pub type HyperBodyReader<'a, 'b> =
self::HttpReader<&'a mut hyper::buffer::BufReader<&'b mut NetworkStream>>;
// |---- from hyper ----|
// |---- from hyper ----|
pub type BodyReader = HttpReader<Chain<Cursor<Vec<u8>>, NetStream>>;
/// The number of bytes to read into the "peek" buffer.
@ -217,11 +217,8 @@ impl Data {
}
}
// impl Drop for Data {
// fn drop(&mut self) {
// // FIXME: Do a read; if > 1024, kill the stream. Need access to the
// // internals of `Chain` to do this efficiently/without crazy baggage.
// // https://github.com/rust-lang/rust/pull/41463
// let _ = io::copy(&mut self.stream, &mut io::sink());
// }
// }
impl Drop for Data {
fn drop(&mut self) {
kill_stream(&mut self.stream);
}
}

View File

@ -1,6 +1,8 @@
use std::io::{self, Read, Cursor, Chain};
use std::net::Shutdown;
use super::data::BodyReader;
use http::hyper::net::NetworkStream;
// It's very unfortunate that we have to wrap `BodyReader` in a `BufReader`
// since it already contains another `BufReader`. The issue is that Hyper's
@ -38,11 +40,23 @@ impl Read for DataStream {
// }
// }
// impl Drop for DataStream {
// fn drop(&mut self) {
// // FIXME: Do a read; if > 1024, kill the stream. Need access to the
// // internals of `Chain` to do this efficiently/without crazy baggage.
// // https://github.com/rust-lang/rust/pull/41463
// let _ = io::copy(&mut self.0, &mut io::sink());
// }
// }
pub fn kill_stream(stream: &mut BodyReader) {
// Take <= 1k from the stream. If there might be more data, force close.
const FLUSH_LEN: u64 = 1024;
match io::copy(&mut stream.take(FLUSH_LEN), &mut io::sink()) {
Ok(FLUSH_LEN) | Err(_) => {
warn_!("Data left unread. Force closing network stream.");
let (_, network) = stream.get_mut().get_mut();
if let Err(e) = network.close(Shutdown::Both) {
error_!("Failed to close network stream: {:?}", e);
}
}
Ok(n) => debug!("flushed {} unread bytes", n)
}
}
impl Drop for DataStream {
fn drop(&mut self) {
kill_stream(&mut self.0.get_mut().1);
}
}

View File

@ -91,20 +91,3 @@ impl NetworkStream for NetStream {
}
}
}
// impl Drop for NetStream {
// fn drop(&mut self) {
// // Take <= 1k from the stream. If there might be more data, force close.
// trace_!("Dropping the network stream...");
// // const FLUSH_LEN: u64 = 1024;
// // match io::copy(&mut self.take(FLUSH_LEN), &mut io::sink()) {
// // Ok(FLUSH_LEN) | Err(_) => {
// // warn_!("Data left unread. Force closing network stream.");
// // if let Err(e) = self.close(Shutdown::Both) {
// // error_!("Failed to close network stream: {:?}", e);
// // }
// // }
// // Ok(n) => debug!("flushed {} unread bytes", n)
// // }
// }
// }

View File

@ -339,6 +339,7 @@ pub struct Segments<'a>(pub &'a str);
impl<'a> Iterator for Segments<'a> {
type Item = &'a str;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
// Find the start of the next segment (first that's not '/').
let i = match self.0.find(|c| c != '/') {
@ -348,8 +349,7 @@ impl<'a> Iterator for Segments<'a> {
// Get the index of the first character that _is_ a '/' after start.
// j = index of first character after i (hence the i +) that's not a '/'
let rest = &self.0[i..];
let j = rest.find('/').map_or(self.0.len(), |j| i + j);
let j = self.0[i..].find('/').map_or(self.0.len(), |j| i + j);
// Save the result, update the iterator, and return!
let result = Some(&self.0[i..j]);

View File

@ -8,6 +8,7 @@
#![feature(plugin)]
#![feature(never_type)]
#![feature(concat_idents)]
#![feature(more_io_inner_methods)]
#![plugin(pear_codegen)]

View File

@ -13,10 +13,9 @@ pub trait Collider<T: ?Sized = Self> {
#[inline(always)]
fn index_match_until(break_c: char,
a: &str,
b: &str,
dir: bool)
-> Option<(isize, isize)> {
a: &str,
b: &str,
dir: bool) -> Option<(isize, isize)> {
let (a_len, b_len) = (a.len() as isize, b.len() as isize);
let (mut i, mut j, delta) = if dir {
(0, 0, 1)