mirror of https://github.com/rwf2/Rocket.git
Reclose connection on unread data. Minimum nightly is 1.19.
This commit is contained in:
parent
781477fff1
commit
9a7484f7a8
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
// // }
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#![feature(plugin)]
|
||||
#![feature(never_type)]
|
||||
#![feature(concat_idents)]
|
||||
#![feature(more_io_inner_methods)]
|
||||
|
||||
#![plugin(pear_codegen)]
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue