Remove 'testing' feature. Close stream on network error.

This is a breaking change.

The `testing` feature no longer exists. Testing structures can now be
accessed without any features enabled.

Prior to this change, Rocket would panic when draining from a network
stream failed. With this change, Rocket force closes the stream on any
error.

This change also ensures that the `Fairings` launch output only prints
if at least one fairing has been attached.
This commit is contained in:
Sergio Benitez 2017-04-20 20:30:41 -07:00
parent ac0c78a0cd
commit 1e5a1b8940
51 changed files with 155 additions and 322 deletions

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -9,6 +9,3 @@ rocket_codegen = { path = "../../codegen" }
serde = "0.9"
serde_json = "0.9"
serde_derive = "0.9"
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -11,6 +11,3 @@ rocket_codegen = { path = "../../codegen" }
path = "../../contrib"
default-features = false
features = ["handlebars_templates"]
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -14,6 +14,3 @@ serde_json = "0.9"
path = "../../contrib"
default-features = false
features = ["handlebars_templates"]
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib", features = ["tls"] }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -14,6 +14,3 @@ serde_derive = "0.9"
path = "../../contrib"
default-features = false
features = ["json"]
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -7,6 +7,3 @@ workspace = "../.."
crossbeam = "*"
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -5,6 +5,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -13,6 +13,3 @@ serde_derive = "0.9"
path = "../../contrib"
default-features = false
features = ["msgpack"]
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -7,6 +7,3 @@ workspace = "../../"
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
rand = "0.3"
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -7,6 +7,3 @@ workspace = "../../"
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
rusqlite = "0.10"
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -11,6 +11,3 @@ rocket_codegen = { path = "../../codegen" }
path = "../../contrib"
default-features = false
features = ["handlebars_templates"]
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -6,6 +6,3 @@ workspace = "../../"
[dependencies]
rocket = { path = "../../lib" }
rocket_codegen = { path = "../../codegen" }
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -13,6 +13,3 @@ lazy_static = "^0.2"
default-features = false
path = "../../contrib"
features = ["uuid"]
[dev-dependencies]
rocket = { path = "../../lib", features = ["testing"] }

View File

@ -15,7 +15,6 @@ build = "build.rs"
categories = ["web-programming::http-server"]
[features]
testing = []
tls = ["rustls", "hyper-rustls"]
[dependencies]

View File

@ -18,7 +18,6 @@ fn rocket() -> rocket::Rocket {
.mount("/", routes![get, post])
}
#[cfg(feature = "testing")]
mod benches {
extern crate test;

View File

@ -31,7 +31,6 @@ fn rocket() -> rocket::Rocket {
.mount("/", routes![post, post2, post3])
}
#[cfg(feature = "testing")]
mod benches {
extern crate test;

View File

@ -34,7 +34,6 @@ fn rocket() -> rocket::Rocket {
index_b, index_c, index_dyn_a])
}
#[cfg(feature = "testing")]
mod benches {
extern crate test;

View File

@ -6,8 +6,9 @@ use std::mem::transmute;
#[cfg(feature = "tls")] use hyper_rustls::WrappedStream;
use super::data_stream::{DataStream, StreamReader, kill_stream};
use super::net_stream::NetStream;
use ext::ReadExt;
use super::data_stream::{DataStream, HyperNetStream, StreamReader, kill_stream};
use http::hyper::h1::HttpReader;
use http::hyper::buffer;
@ -17,6 +18,9 @@ use http::hyper::net::{HttpStream, NetworkStream};
pub type BodyReader<'a, 'b> =
self::HttpReader<&'a mut self::buffer::BufReader<&'b mut NetworkStream>>;
/// The number of bytes to read into the "peek" buffer.
const PEEK_BYTES: usize = 4096;
/// Type representing the data in the body of an incoming request.
///
/// This type is the only means by which the body of a request can be retrieved.
@ -90,19 +94,19 @@ impl Data {
let net_stream = h_body.get_ref().get_ref();
#[cfg(feature = "tls")]
fn concrete_stream(stream: &&mut NetworkStream) -> Option<HyperNetStream> {
fn concrete_stream(stream: &&mut NetworkStream) -> Option<NetStream> {
stream.downcast_ref::<HttpStream>()
.map(|s| HyperNetStream::Http(s.clone()))
.map(|s| NetStream::Http(s.clone()))
.or_else(|| {
stream.downcast_ref::<WrappedStream>()
.map(|s| HyperNetStream::Https(s.clone()))
.map(|s| NetStream::Https(s.clone()))
})
}
#[cfg(not(feature = "tls"))]
fn concrete_stream(stream: &&mut NetworkStream) -> Option<HyperNetStream> {
fn concrete_stream(stream: &&mut NetworkStream) -> Option<NetStream> {
stream.downcast_ref::<HttpStream>()
.map(|s| HyperNetStream::Http(s.clone()))
.map(|s| NetStream::Http(s.clone()))
}
// Retrieve the underlying HTTPStream from Hyper.
@ -164,15 +168,15 @@ impl Data {
}
// Creates a new data object with an internal buffer `buf`, where the cursor
// in the buffer is at `pos` and the buffer has `cap` valid bytes. The
// remainder of the data bytes can be read from `stream`.
// in the buffer is at `pos` and the buffer has `cap` valid bytes. Thus, the
// bytes `vec[pos..cap]` are buffered and unread. The remainder of the data
// bytes can be read from `stream`.
pub(crate) fn new(mut buf: Vec<u8>,
pos: usize,
mut cap: usize,
mut stream: StreamReader
) -> Data {
// Make sure the buffer is large enough for the bytes we want to peek.
const PEEK_BYTES: usize = 4096;
if buf.len() < PEEK_BYTES {
trace_!("Resizing peek buffer from {} to {}.", buf.len(), PEEK_BYTES);
buf.resize(PEEK_BYTES, 0);
@ -203,6 +207,27 @@ impl Data {
capacity: cap,
}
}
/// This creates a `data` object from a local data source `data`.
pub(crate) fn local(mut data: Vec<u8>) -> Data {
// Emulate peek buffering.
let (buf, rest) = if data.len() <= PEEK_BYTES {
(data, vec![])
} else {
let rest = data.split_off(PEEK_BYTES);
(data, rest)
};
let (buf_len, stream_len) = (buf.len(), rest.len() as u64);
let stream = NetStream::Local(Cursor::new(rest));
Data {
buffer: buf,
stream: HttpReader::SizedReader(stream, stream_len),
is_done: stream_len == 0,
position: 0,
capacity: buf_len,
}
}
}
impl Drop for Data {

View File

@ -1,80 +1,14 @@
use std::io::{self, BufRead, Read, Cursor, BufReader, Chain, Take};
use std::net::{SocketAddr, Shutdown};
use std::time::Duration;
use std::net::Shutdown;
#[cfg(feature = "tls")] use hyper_rustls::WrappedStream as RustlsStream;
use super::net_stream::NetStream;
use http::hyper::net::{HttpStream, NetworkStream};
use http::hyper::net::NetworkStream;
use http::hyper::h1::HttpReader;
pub type StreamReader = HttpReader<HyperNetStream>;
pub type StreamReader = HttpReader<NetStream>;
pub type InnerStream = Chain<Take<Cursor<Vec<u8>>>, BufReader<StreamReader>>;
#[derive(Clone)]
pub enum HyperNetStream {
Http(HttpStream),
#[cfg(feature = "tls")]
Https(RustlsStream)
}
macro_rules! with_inner {
($net:expr, |$stream:ident| $body:expr) => ({
trace!("{}:{}", file!(), line!());
match *$net {
HyperNetStream::Http(ref $stream) => $body,
#[cfg(feature = "tls")] HyperNetStream::Https(ref $stream) => $body
}
});
($net:expr, |mut $stream:ident| $body:expr) => ({
trace!("{}:{}", file!(), line!());
match *$net {
HyperNetStream::Http(ref mut $stream) => $body,
#[cfg(feature = "tls")] HyperNetStream::Https(ref mut $stream) => $body
}
})
}
impl io::Read for HyperNetStream {
#[inline(always)]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
with_inner!(self, |mut stream| io::Read::read(stream, buf))
}
}
impl io::Write for HyperNetStream {
#[inline(always)]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
with_inner!(self, |mut stream| io::Write::write(stream, buf))
}
#[inline(always)]
fn flush(&mut self) -> io::Result<()> {
with_inner!(self, |mut stream| io::Write::flush(stream))
}
}
impl NetworkStream for HyperNetStream {
#[inline(always)]
fn peer_addr(&mut self) -> io::Result<SocketAddr> {
with_inner!(self, |mut stream| NetworkStream::peer_addr(stream))
}
#[inline(always)]
fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
with_inner!(self, |stream| NetworkStream::set_read_timeout(stream, dur))
}
#[inline(always)]
fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
with_inner!(self, |stream| NetworkStream::set_write_timeout(stream, dur))
}
#[inline(always)]
fn close(&mut self, how: Shutdown) -> io::Result<()> {
with_inner!(self, |mut stream| NetworkStream::close(stream, how))
}
}
/// Raw data stream of a request body.
///
/// This stream can only be obtained by calling
@ -83,12 +17,12 @@ impl NetworkStream for HyperNetStream {
/// Instead, it must be used as an opaque `Read` or `BufRead` structure.
pub struct DataStream {
stream: InnerStream,
network: HyperNetStream,
network: NetStream,
}
impl DataStream {
#[inline(always)]
pub(crate) fn new(stream: InnerStream, network: HyperNetStream) -> DataStream {
pub(crate) fn new(stream: InnerStream, network: NetStream) -> DataStream {
DataStream { stream, network }
}
}
@ -112,19 +46,18 @@ impl BufRead for DataStream {
}
}
// pub fn kill_stream<S: Read>(stream: &mut S, network: &mut HyperNetStream) {
pub fn kill_stream<S: Read, N: NetworkStream>(stream: &mut S, network: &mut N) {
io::copy(&mut stream.take(1024), &mut io::sink()).expect("kill_stream: sink");
// If there are any more bytes, kill it.
let mut buf = [0];
if let Ok(n) = stream.read(&mut buf) {
if n > 0 {
pub fn kill_stream<S: Read, N: NetworkStream>(stream: &mut S, network: &mut N) {
// 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.");
if let Err(e) = network.close(Shutdown::Both) {
error_!("Failed to close network stream: {:?}", e);
}
}
Ok(n) => debug!("flushed {} unread bytes", n)
}
}

View File

@ -1,25 +1,8 @@
//! Types and traits for reading and parsing request body data.
#[cfg(any(test, feature = "testing"))]
#[path = "."]
mod items {
mod test_data;
pub use self::test_data::Data;
pub use self::test_data::DataStream;
}
#[cfg(not(any(test, feature = "testing")))]
#[path = "."]
mod items {
mod data;
mod data_stream;
pub use self::data::Data;
pub use self::data_stream::DataStream;
}
mod data;
mod data_stream;
mod net_stream;
mod from_data;
pub use self::data::Data;
pub use self::data_stream::DataStream;
pub use self::from_data::{FromData, Outcome};
pub use self::items::{Data, DataStream};

View File

@ -0,0 +1,87 @@
use std::io::{self, Cursor};
use std::net::{SocketAddr, Shutdown};
use std::time::Duration;
#[cfg(feature = "tls")] use hyper_rustls::WrappedStream as RustlsStream;
use http::hyper::net::{HttpStream, NetworkStream};
use self::NetStream::*;
// This is a representation of all of the possible network streams we might get.
// This really shouldn't be necessary, but, you know, Hyper.
#[derive(Clone)]
pub enum NetStream {
Http(HttpStream),
#[cfg(feature = "tls")]
Https(RustlsStream),
Local(Cursor<Vec<u8>>)
}
impl io::Read for NetStream {
#[inline(always)]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match *self {
Http(ref mut stream) => stream.read(buf),
Local(ref mut stream) => stream.read(buf),
#[cfg(feature = "tls")] Https(ref mut stream) => stream.read(buf)
}
}
}
impl io::Write for NetStream {
#[inline(always)]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match *self {
Http(ref mut stream) => stream.write(buf),
Local(ref mut stream) => stream.write(buf),
#[cfg(feature = "tls")] Https(ref mut stream) => stream.write(buf)
}
}
#[inline(always)]
fn flush(&mut self) -> io::Result<()> {
match *self {
Http(ref mut stream) => stream.flush(),
Local(ref mut stream) => stream.flush(),
#[cfg(feature = "tls")] Https(ref mut stream) => stream.flush()
}
}
}
impl NetworkStream for NetStream {
#[inline(always)]
fn peer_addr(&mut self) -> io::Result<SocketAddr> {
match *self {
Http(ref mut stream) => stream.peer_addr(),
#[cfg(feature = "tls")] Https(ref mut stream) => stream.peer_addr(),
Local(_) => Err(io::Error::from(io::ErrorKind::AddrNotAvailable)),
}
}
#[inline(always)]
fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
match *self {
Http(ref stream) => stream.set_read_timeout(dur),
#[cfg(feature = "tls")] Https(ref stream) => stream.set_read_timeout(dur),
Local(_) => Ok(()),
}
}
#[inline(always)]
fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
match *self {
Http(ref stream) => stream.set_write_timeout(dur),
#[cfg(feature = "tls")] Https(ref stream) => stream.set_write_timeout(dur),
Local(_) => Ok(()),
}
}
#[inline(always)]
fn close(&mut self, how: Shutdown) -> io::Result<()> {
match *self {
Http(ref mut stream) => stream.close(how),
#[cfg(feature = "tls")] Https(ref mut stream) => stream.close(how),
Local(_) => Ok(()),
}
}
}

View File

@ -1,75 +0,0 @@
use std::io::{self, Read, BufRead, Write, Cursor, BufReader};
use std::path::Path;
use std::fs::File;
use http::hyper::h1::HttpReader;
use http::hyper::net::NetworkStream;
use http::hyper::buffer;
pub type BodyReader<'a, 'b> =
self::HttpReader<&'a mut self::buffer::BufReader<&'b mut NetworkStream>>;
const PEEK_BYTES: usize = 4096;
pub struct DataStream {
stream: BufReader<Cursor<Vec<u8>>>,
}
impl Read for DataStream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.stream.read(buf)
}
}
impl BufRead for DataStream {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
self.stream.fill_buf()
}
fn consume(&mut self, amt: usize) {
self.stream.consume(amt)
}
}
pub struct Data {
data: Vec<u8>,
}
impl Data {
pub fn open(self) -> DataStream {
DataStream { stream: BufReader::new(Cursor::new(self.data)) }
}
#[inline]
pub fn peek(&self) -> &[u8] {
&self.data[..::std::cmp::min(PEEK_BYTES, self.data.len())]
}
#[inline]
pub fn peek_complete(&self) -> bool {
self.data.len() <= PEEK_BYTES
}
#[inline]
pub fn stream_to<W: Write>(self, writer: &mut W) -> io::Result<u64> {
io::copy(&mut self.open(), writer)
}
#[inline]
pub fn stream_to_file<P: AsRef<Path>>(self, path: P) -> io::Result<u64> {
io::copy(&mut self.open(), &mut File::create(path)?)
}
pub(crate) fn from_hyp(mut h_body: BodyReader) -> Result<Data, &'static str> {
let mut vec = Vec::new();
if let Err(_) = io::copy(&mut h_body, &mut vec) {
return Err("Reading from body failed.");
};
Ok(Data::new(vec))
}
pub(crate) fn new(data: Vec<u8>) -> Data {
Data { data: data }
}
}

View File

@ -173,9 +173,17 @@ impl Fairings {
}
}
fn num_attached(&self) -> usize {
self.launch.len() + self.request.len() + self.response.len()
}
pub fn pretty_print_counts(&self) {
use term_painter::ToStyle;
use term_painter::Color::White;
use term_painter::Color::{White, Magenta};
if self.num_attached() > 0 {
info!("📡 {}:", Magenta.paint("Fairings"));
}
if !self.launch.is_empty() {
info_!("{} launch", White.paint(self.launch.len()));

View File

@ -117,7 +117,7 @@ extern crate smallvec;
#[cfg(test)] #[macro_use] extern crate lazy_static;
#[doc(hidden)] #[macro_use] pub mod logger;
#[cfg(any(test, feature = "testing"))] pub mod testing;
pub mod testing;
pub mod http;
pub mod request;
pub mod response;

View File

@ -645,7 +645,6 @@ impl Rocket {
return LaunchError::from(LaunchErrorKind::Collision);
}
info!("📡 {}:", Magenta.paint("Fairings"));
self.fairings.pretty_print_counts();
let full_addr = format!("{}:{}", self.config.address, self.config.port);

View File

@ -1,33 +1,5 @@
//! A tiny module for testing Rocket applications.
//!
//! # Enabling
//!
//! The `testing` module is only available when Rocket is compiled with the
//! `testing` feature flag. The suggested way to enable the `testing` module is
//! through Cargo's `[dev-dependencies]` feature which allows features (and
//! other dependencies) to be enabled exclusively when testing/benchmarking your
//! application.
//!
//! To compile Rocket with the `testing` feature for testing/benchmarking, add
//! the following to your `Cargo.toml`:
//!
//! ```toml
//! [dev-dependencies]
//! rocket = { version = "*", features = ["testing"] }
//! ```
//!
//! Then, in your testing module, `use` the testing types. This typically looks
//! as follows:
//!
//! ```rust,ignore
//! #[cfg(test)]
//! mod test {
//! use super::rocket;
//! use rocket::testing::MockRequest;
//! use rocket::http::Method::*;
//! }
//! ```
//!
//! # Usage
//!
//! The testing methadology is simple:
@ -51,9 +23,10 @@
//! builds a request for submitting a login form with three fields:
//!
//! ```rust
//! # use rocket::http::Method::*;
//! # use rocket::testing::MockRequest;
//! # use rocket::http::ContentType;
//! use rocket::http::Method::*;
//! use rocket::http::ContentType;
//! use rocket::testing::MockRequest;
//!
//! let (username, password, age) = ("user", "password", 32);
//! MockRequest::new(Post, "/login")
//! .header(ContentType::Form)
@ -119,7 +92,7 @@ impl<'r> MockRequest<'r> {
pub fn new<S: AsRef<str>>(method: Method, uri: S) -> Self {
MockRequest {
request: Request::new(method, uri.as_ref().to_string()),
data: Data::new(vec![])
data: Data::local(vec![])
}
}
@ -222,7 +195,7 @@ impl<'r> MockRequest<'r> {
/// ```
#[inline]
pub fn body<S: AsRef<[u8]>>(mut self, body: S) -> Self {
self.data = Data::new(body.as_ref().into());
self.data = Data::local(body.as_ref().into());
self
}
@ -261,7 +234,7 @@ impl<'r> MockRequest<'r> {
/// # }
/// ```
pub fn dispatch_with<'s>(&'s mut self, rocket: &'r Rocket) -> Response<'s> {
let data = ::std::mem::replace(&mut self.data, Data::new(vec![]));
let data = ::std::mem::replace(&mut self.data, Data::local(vec![]));
rocket.dispatch(&mut self.request, data)
}
}

View File

@ -16,7 +16,6 @@ fn bug(form_data: Form<FormData>) -> &'static str {
"OK"
}
#[cfg(feature = "testing")]
mod tests {
use super::*;
use rocket::testing::MockRequest;

View File

@ -15,7 +15,6 @@ fn bug(form_data: Form<FormData>) -> String {
form_data.into_inner().form_data
}
#[cfg(feature = "testing")]
mod tests {
use super::*;
use rocket::testing::MockRequest;

View File

@ -20,7 +20,6 @@ fn other() -> content::JSON<()> {
content::JSON(())
}
#[cfg(feature = "testing")]
mod tests {
use super::*;

View File

@ -15,7 +15,6 @@ fn index(form: Form<Simple>) -> String {
form.into_inner().value
}
#[cfg(feature = "testing")]
mod tests {
use rocket;
use rocket::config::{Environment, Config, Limits};

View File

@ -23,7 +23,6 @@ fn specified_html() -> &'static str {
"specified_html"
}
#[cfg(feature = "testing")]
mod tests {
use super::*;

View File

@ -18,7 +18,6 @@ fn second() -> &'static str {
"no query"
}
#[cfg(feature = "testing")]
mod tests {
use super::*;

View File

@ -10,7 +10,6 @@ fn not_found() -> Redirect {
Redirect::to("/")
}
#[cfg(feature = "testing")]
mod tests {
use super::*;
use rocket::testing::MockRequest;

View File

@ -10,7 +10,6 @@ fn get_ip(remote: SocketAddr) -> String {
remote.to_string()
}
#[cfg(feature = "testing")]
mod remote_rewrite_tests {
use super::*;
use rocket::testing::MockRequest;

View File

@ -30,7 +30,6 @@ fn dual(user: String, path: Segments) -> String {
user + "/is/" + &path.collect::<Vec<_>>().join("/")
}
#[cfg(feature = "testing")]
mod tests {
use super::*;
use rocket::testing::MockRequest;