Skip to content

Commit

Permalink
refactor HttpRequest mutability
Browse files Browse the repository at this point in the history
  • Loading branch information
fafhrd91 committed Jul 2, 2018
1 parent 445ea04 commit fec6047
Show file tree
Hide file tree
Showing 51 changed files with 2,231 additions and 2,148 deletions.
214 changes: 100 additions & 114 deletions src/application.rs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub use self::connector::{
Pause, Resume,
};
pub(crate) use self::parser::{HttpResponseParser, HttpResponseParserError};
pub(crate) use self::pipeline::Pipeline;
pub use self::pipeline::{SendRequest, SendRequestError};
pub use self::request::{ClientRequest, ClientRequestBuilder};
pub use self::response::ClientResponse;
Expand Down
16 changes: 13 additions & 3 deletions src/client/pipeline.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bytes::{Bytes, BytesMut};
use futures::sync::oneshot;
use futures::{Async, Future, Poll};
use futures::{Async, Future, Poll, Stream};
use http::header::CONTENT_ENCODING;
use std::time::{Duration, Instant};
use std::{io, mem};
Expand Down Expand Up @@ -230,7 +230,7 @@ impl Future for SendRequest {
}
}

pub(crate) struct Pipeline {
pub struct Pipeline {
body: IoBody,
body_completed: bool,
conn: Option<Connection>,
Expand Down Expand Up @@ -315,7 +315,7 @@ impl Pipeline {
}

#[inline]
pub fn poll(&mut self) -> Poll<Option<Bytes>, PayloadError> {
pub(crate) fn poll(&mut self) -> Poll<Option<Bytes>, PayloadError> {
if self.conn.is_none() {
return Ok(Async::Ready(None));
}
Expand Down Expand Up @@ -522,3 +522,13 @@ impl Drop for Pipeline {
}
}
}

/// Future that resolves to a complete request body.
impl Stream for Box<Pipeline> {
type Item = Bytes;
type Error = PayloadError;

fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
Pipeline::poll(self)
}
}
31 changes: 14 additions & 17 deletions src/client/response.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::cell::RefCell;
use std::{fmt, str};

use bytes::Bytes;
Expand Down Expand Up @@ -30,23 +31,33 @@ impl Default for ClientMessage {
}

/// An HTTP Client response
pub struct ClientResponse(ClientMessage, Option<Box<Pipeline>>);
pub struct ClientResponse(ClientMessage, RefCell<Option<Box<Pipeline>>>);

impl HttpMessage for ClientResponse {
type Stream = Box<Pipeline>;

/// Get the headers from the response.
#[inline]
fn headers(&self) -> &HeaderMap {
&self.0.headers
}

#[inline]
fn payload(&self) -> Box<Pipeline> {
self.1
.borrow_mut()
.take()
.expect("Payload is already consumed.")
}
}

impl ClientResponse {
pub(crate) fn new(msg: ClientMessage) -> ClientResponse {
ClientResponse(msg, None)
ClientResponse(msg, RefCell::new(None))
}

pub(crate) fn set_pipeline(&mut self, pl: Box<Pipeline>) {
self.1 = Some(pl);
*self.1.borrow_mut() = Some(pl);
}

/// Get the HTTP version of this response.
Expand Down Expand Up @@ -95,20 +106,6 @@ impl fmt::Debug for ClientResponse {
}
}

/// Future that resolves to a complete request body.
impl Stream for ClientResponse {
type Item = Bytes;
type Error = PayloadError;

fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
if let Some(ref mut pl) = self.1 {
pl.poll()
} else {
Ok(Async::Ready(None))
}
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
3 changes: 0 additions & 3 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,9 +612,6 @@ pub enum UrlGenerationError {
/// Not all path pattern covered
#[fail(display = "Not all path pattern covered")]
NotEnoughElements,
/// Router is not available
#[fail(display = "Router is not available")]
RouterNotAvailable,
/// URL parse error
#[fail(display = "{}", _0)]
ParseError(#[cause] UrlParseError),
Expand Down
68 changes: 34 additions & 34 deletions src/extractor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,12 +267,12 @@ where

#[inline]
fn from_request(req: &HttpRequest<S>, cfg: &Self::Config) -> Self::Result {
let req = req.clone();
let req2 = req.clone();
let err = Rc::clone(&cfg.ehandler);
Box::new(
UrlEncoded::new(req.clone())
UrlEncoded::new(req)
.limit(cfg.limit)
.map_err(move |e| (*err)(e, req))
.map_err(move |e| (*err)(e, &req2))
.map(Form),
)
}
Expand Down Expand Up @@ -321,7 +321,7 @@ impl<T: fmt::Display> fmt::Display for Form<T> {
/// ```
pub struct FormConfig<S> {
limit: usize,
ehandler: Rc<Fn(UrlencodedError, HttpRequest<S>) -> Error>,
ehandler: Rc<Fn(UrlencodedError, &HttpRequest<S>) -> Error>,
}

impl<S> FormConfig<S> {
Expand All @@ -334,7 +334,7 @@ impl<S> FormConfig<S> {
/// Set custom error handler
pub fn error_handler<F>(&mut self, f: F) -> &mut Self
where
F: Fn(UrlencodedError, HttpRequest<S>) -> Error + 'static,
F: Fn(UrlencodedError, &HttpRequest<S>) -> Error + 'static,
{
self.ehandler = Rc::new(f);
self
Expand Down Expand Up @@ -383,9 +383,7 @@ impl<S: 'static> FromRequest<S> for Bytes {
// check content-type
cfg.check_mimetype(req)?;

Ok(Box::new(
MessageBody::new(req.clone()).limit(cfg.limit).from_err(),
))
Ok(Box::new(MessageBody::new(req).limit(cfg.limit).from_err()))
}
}

Expand Down Expand Up @@ -429,7 +427,7 @@ impl<S: 'static> FromRequest<S> for String {
let encoding = req.encoding()?;

Ok(Box::new(
MessageBody::new(req.clone())
MessageBody::new(req)
.limit(cfg.limit)
.from_err()
.and_then(move |body| {
Expand Down Expand Up @@ -617,7 +615,6 @@ mod tests {
use mime;
use resource::ResourceHandler;
use router::{Resource, Router};
use server::ServerSettings;
use test::TestRequest;

#[derive(Deserialize, Debug, PartialEq)]
Expand All @@ -628,9 +625,9 @@ mod tests {
#[test]
fn test_bytes() {
let cfg = PayloadConfig::default();
let mut req = TestRequest::with_header(header::CONTENT_LENGTH, "11").finish();
req.payload_mut()
.unread_data(Bytes::from_static(b"hello=world"));
let req = TestRequest::with_header(header::CONTENT_LENGTH, "11")
.set_payload(Bytes::from_static(b"hello=world"))
.finish();

match Bytes::from_request(&req, &cfg).unwrap().poll().unwrap() {
Async::Ready(s) => {
Expand All @@ -643,9 +640,9 @@ mod tests {
#[test]
fn test_string() {
let cfg = PayloadConfig::default();
let mut req = TestRequest::with_header(header::CONTENT_LENGTH, "11").finish();
req.payload_mut()
.unread_data(Bytes::from_static(b"hello=world"));
let req = TestRequest::with_header(header::CONTENT_LENGTH, "11")
.set_payload(Bytes::from_static(b"hello=world"))
.finish();

match String::from_request(&req, &cfg).unwrap().poll().unwrap() {
Async::Ready(s) => {
Expand All @@ -657,13 +654,12 @@ mod tests {

#[test]
fn test_form() {
let mut req = TestRequest::with_header(
let req = TestRequest::with_header(
header::CONTENT_TYPE,
"application/x-www-form-urlencoded",
).header(header::CONTENT_LENGTH, "11")
.set_payload(Bytes::from_static(b"hello=world"))
.finish();
req.payload_mut()
.unread_data(Bytes::from_static(b"hello=world"));

let mut cfg = FormConfig::default();
cfg.limit(4096);
Expand All @@ -677,7 +673,7 @@ mod tests {

#[test]
fn test_payload_config() {
let req = HttpRequest::default();
let req = TestRequest::default().finish();
let mut cfg = PayloadConfig::default();
cfg.mimetype(mime::APPLICATION_JSON);
assert!(cfg.check_mimetype(&req).is_err());
Expand Down Expand Up @@ -712,14 +708,15 @@ mod tests {

#[test]
fn test_request_extract() {
let mut req = TestRequest::with_uri("/name/user1/?id=test").finish();
let req = TestRequest::with_uri("/name/user1/?id=test").finish();

let mut resource = ResourceHandler::<()>::default();
resource.name("index");
let mut routes = Vec::new();
routes.push((Resource::new("index", "/{key}/{value}/"), Some(resource)));
let (router, _) = Router::new("", ServerSettings::default(), routes);
assert!(router.recognize(&mut req).is_some());
let (router, _) = Router::new("", routes);
let info = router.recognize(&req).unwrap().1;
let req = req.with_route_info(info);

let s = Path::<MyStruct>::from_request(&req, &()).unwrap();
assert_eq!(s.key, "name");
Expand All @@ -732,8 +729,9 @@ mod tests {
let s = Query::<Id>::from_request(&req, &()).unwrap();
assert_eq!(s.id, "test");

let mut req = TestRequest::with_uri("/name/32/").finish();
assert!(router.recognize(&mut req).is_some());
let req = TestRequest::with_uri("/name/32/").finish_with_router(router.clone());
let info = router.recognize(&req).unwrap().1;
let req = req.with_route_info(info);

let s = Path::<Test2>::from_request(&req, &()).unwrap();
assert_eq!(s.as_ref().key, "name");
Expand All @@ -754,24 +752,26 @@ mod tests {
resource.name("index");
let mut routes = Vec::new();
routes.push((Resource::new("index", "/{value}/"), Some(resource)));
let (router, _) = Router::new("", ServerSettings::default(), routes);

let mut req = TestRequest::with_uri("/32/").finish();
assert!(router.recognize(&mut req).is_some());
let (router, _) = Router::new("", routes);

assert_eq!(*Path::<i8>::from_request(&mut req, &()).unwrap(), 32);
let req = TestRequest::with_uri("/32/").finish_with_router(router.clone());
let info = router.recognize(&req).unwrap().1;
let req = req.with_route_info(info);
assert_eq!(*Path::<i8>::from_request(&req, &()).unwrap(), 32);
}

#[test]
fn test_tuple_extract() {
let mut req = TestRequest::with_uri("/name/user1/?id=test").finish();

let mut resource = ResourceHandler::<()>::default();
resource.name("index");
let mut routes = Vec::new();
routes.push((Resource::new("index", "/{key}/{value}/"), Some(resource)));
let (router, _) = Router::new("", ServerSettings::default(), routes);
assert!(router.recognize(&mut req).is_some());
let (router, _) = Router::new("", routes);

let mut req = TestRequest::with_uri("/name/user1/?id=test")
.finish_with_router(router.clone());
let info = router.recognize(&req).unwrap().1;
let req = req.with_route_info(info);

let res = match <(Path<(String, String)>,)>::extract(&req).poll() {
Ok(Async::Ready(res)) => res,
Expand Down
Loading

0 comments on commit fec6047

Please sign in to comment.