1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-06-27 15:29:03 +02:00

refactor HttpRequest mutability

This commit is contained in:
Nikolay Kim
2018-06-25 10:58:04 +06:00
parent 445ea043dd
commit fec6047ddc
51 changed files with 2239 additions and 2156 deletions

View File

@ -60,6 +60,7 @@ use httprequest::HttpRequest;
use httpresponse::HttpResponse;
use middleware::{Middleware, Response, Started};
use resource::ResourceHandler;
use server::Request;
/// A set of errors that can occur during processing CORS
#[derive(Debug, Fail)]
@ -279,11 +280,13 @@ impl Cors {
/// `ResourceHandler::middleware()` method, but in that case *Cors*
/// middleware wont be able to handle *OPTIONS* requests.
pub fn register<S: 'static>(self, resource: &mut ResourceHandler<S>) {
resource.method(Method::OPTIONS).h(|_| HttpResponse::Ok());
resource
.method(Method::OPTIONS)
.h(|_: &_| HttpResponse::Ok());
resource.middleware(self);
}
fn validate_origin<S>(&self, req: &mut HttpRequest<S>) -> Result<(), CorsError> {
fn validate_origin(&self, req: &Request) -> Result<(), CorsError> {
if let Some(hdr) = req.headers().get(header::ORIGIN) {
if let Ok(origin) = hdr.to_str() {
return match self.inner.origins {
@ -303,9 +306,7 @@ impl Cors {
}
}
fn validate_allowed_method<S>(
&self, req: &mut HttpRequest<S>,
) -> Result<(), CorsError> {
fn validate_allowed_method(&self, req: &Request) -> Result<(), CorsError> {
if let Some(hdr) = req.headers().get(header::ACCESS_CONTROL_REQUEST_METHOD) {
if let Ok(meth) = hdr.to_str() {
if let Ok(method) = Method::try_from(meth) {
@ -323,9 +324,7 @@ impl Cors {
}
}
fn validate_allowed_headers<S>(
&self, req: &mut HttpRequest<S>,
) -> Result<(), CorsError> {
fn validate_allowed_headers(&self, req: &Request) -> Result<(), CorsError> {
match self.inner.headers {
AllOrSome::All => Ok(()),
AllOrSome::Some(ref allowed_headers) => {
@ -356,11 +355,11 @@ impl Cors {
}
impl<S> Middleware<S> for Cors {
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
fn start(&self, req: &HttpRequest<S>) -> Result<Started> {
if self.inner.preflight && Method::OPTIONS == *req.method() {
self.validate_origin(req)?;
self.validate_allowed_method(req)?;
self.validate_allowed_headers(req)?;
self.validate_allowed_method(&req)?;
self.validate_allowed_headers(&req)?;
// allowed headers
let headers = if let Some(headers) = self.inner.headers.as_ref() {
@ -434,7 +433,7 @@ impl<S> Middleware<S> for Cors {
}
fn response(
&self, req: &mut HttpRequest<S>, mut resp: HttpResponse,
&self, req: &HttpRequest<S>, mut resp: HttpResponse,
) -> Result<Response> {
match self.inner.origins {
AllOrSome::All => {
@ -945,10 +944,9 @@ mod tests {
#[test]
fn validate_origin_allows_all_origins() {
let cors = Cors::default();
let mut req =
TestRequest::with_header("Origin", "https://www.example.com").finish();
let req = TestRequest::with_header("Origin", "https://www.example.com").finish();
assert!(cors.start(&mut req).ok().unwrap().is_done())
assert!(cors.start(&req).ok().unwrap().is_done())
}
#[test]
@ -961,20 +959,20 @@ mod tests {
.allowed_header(header::CONTENT_TYPE)
.finish();
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
let req = TestRequest::with_header("Origin", "https://www.example.com")
.method(Method::OPTIONS)
.finish();
assert!(cors.start(&mut req).is_err());
assert!(cors.start(&req).is_err());
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
let req = TestRequest::with_header("Origin", "https://www.example.com")
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "put")
.method(Method::OPTIONS)
.finish();
assert!(cors.start(&mut req).is_err());
assert!(cors.start(&req).is_err());
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
let req = TestRequest::with_header("Origin", "https://www.example.com")
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST")
.header(
header::ACCESS_CONTROL_REQUEST_HEADERS,
@ -983,7 +981,7 @@ mod tests {
.method(Method::OPTIONS)
.finish();
let resp = cors.start(&mut req).unwrap().response();
let resp = cors.start(&req).unwrap().response();
assert_eq!(
&b"*"[..],
resp.headers()
@ -1007,7 +1005,7 @@ mod tests {
// as_bytes());
Rc::get_mut(&mut cors.inner).unwrap().preflight = false;
assert!(cors.start(&mut req).unwrap().is_done());
assert!(cors.start(&req).unwrap().is_done());
}
// #[test]
@ -1017,7 +1015,7 @@ mod tests {
// .allowed_origin("https://www.example.com")
// .finish();
// let mut req = HttpRequest::default();
// cors.start(&mut req).unwrap();
// cors.start(&req).unwrap();
// }
#[test]
@ -1027,10 +1025,10 @@ mod tests {
.allowed_origin("https://www.example.com")
.finish();
let mut req = TestRequest::with_header("Origin", "https://www.unknown.com")
let req = TestRequest::with_header("Origin", "https://www.unknown.com")
.method(Method::GET)
.finish();
cors.start(&mut req).unwrap();
cors.start(&req).unwrap();
}
#[test]
@ -1039,30 +1037,30 @@ mod tests {
.allowed_origin("https://www.example.com")
.finish();
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
let req = TestRequest::with_header("Origin", "https://www.example.com")
.method(Method::GET)
.finish();
assert!(cors.start(&mut req).unwrap().is_done());
assert!(cors.start(&req).unwrap().is_done());
}
#[test]
fn test_no_origin_response() {
let cors = Cors::build().finish();
let mut req = TestRequest::default().method(Method::GET).finish();
let req = TestRequest::default().method(Method::GET).finish();
let resp: HttpResponse = HttpResponse::Ok().into();
let resp = cors.response(&mut req, resp).unwrap().response();
let resp = cors.response(&req, resp).unwrap().response();
assert!(
resp.headers()
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
.is_none()
);
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
let req = TestRequest::with_header("Origin", "https://www.example.com")
.method(Method::OPTIONS)
.finish();
let resp = cors.response(&mut req, resp).unwrap().response();
let resp = cors.response(&req, resp).unwrap().response();
assert_eq!(
&b"https://www.example.com"[..],
resp.headers()
@ -1083,12 +1081,12 @@ mod tests {
.allowed_header(header::CONTENT_TYPE)
.finish();
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
let req = TestRequest::with_header("Origin", "https://www.example.com")
.method(Method::OPTIONS)
.finish();
let resp: HttpResponse = HttpResponse::Ok().into();
let resp = cors.response(&mut req, resp).unwrap().response();
let resp = cors.response(&req, resp).unwrap().response();
assert_eq!(
&b"*"[..],
resp.headers()
@ -1103,7 +1101,7 @@ mod tests {
let resp: HttpResponse =
HttpResponse::Ok().header(header::VARY, "Accept").finish();
let resp = cors.response(&mut req, resp).unwrap().response();
let resp = cors.response(&req, resp).unwrap().response();
assert_eq!(
&b"Accept, Origin"[..],
resp.headers().get(header::VARY).unwrap().as_bytes()
@ -1114,7 +1112,7 @@ mod tests {
.allowed_origin("https://www.example.com")
.finish();
let resp: HttpResponse = HttpResponse::Ok().into();
let resp = cors.response(&mut req, resp).unwrap().response();
let resp = cors.response(&req, resp).unwrap().response();
assert_eq!(
&b"https://www.example.com"[..],
resp.headers()

View File

@ -25,7 +25,7 @@
//! use actix_web::middleware::csrf;
//! use actix_web::{http, App, HttpRequest, HttpResponse};
//!
//! fn handle_post(_: HttpRequest) -> &'static str {
//! fn handle_post(_: &HttpRequest) -> &'static str {
//! "This action should only be triggered with requests from the same site"
//! }
//!
@ -54,6 +54,7 @@ use httpmessage::HttpMessage;
use httprequest::HttpRequest;
use httpresponse::HttpResponse;
use middleware::{Middleware, Started};
use server::Request;
/// Potential cross-site request forgery detected.
#[derive(Debug, Fail)]
@ -187,7 +188,7 @@ impl CsrfFilter {
self
}
fn validate<S>(&self, req: &mut HttpRequest<S>) -> Result<(), CsrfError> {
fn validate(&self, req: &Request) -> Result<(), CsrfError> {
let is_upgrade = req.headers().contains_key(header::UPGRADE);
let is_safe = req.method().is_safe() && (self.allow_upgrade || !is_upgrade);
@ -209,7 +210,7 @@ impl CsrfFilter {
}
impl<S> Middleware<S> for CsrfFilter {
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
fn start(&self, req: &HttpRequest<S>) -> Result<Started> {
self.validate(req)?;
Ok(Started::Done)
}
@ -225,35 +226,35 @@ mod tests {
fn test_safe() {
let csrf = CsrfFilter::new().allowed_origin("https://www.example.com");
let mut req = TestRequest::with_header("Origin", "https://www.w3.org")
let req = TestRequest::with_header("Origin", "https://www.w3.org")
.method(Method::HEAD)
.finish();
assert!(csrf.start(&mut req).is_ok());
assert!(csrf.start(&req).is_ok());
}
#[test]
fn test_csrf() {
let csrf = CsrfFilter::new().allowed_origin("https://www.example.com");
let mut req = TestRequest::with_header("Origin", "https://www.w3.org")
let req = TestRequest::with_header("Origin", "https://www.w3.org")
.method(Method::POST)
.finish();
assert!(csrf.start(&mut req).is_err());
assert!(csrf.start(&req).is_err());
}
#[test]
fn test_referer() {
let csrf = CsrfFilter::new().allowed_origin("https://www.example.com");
let mut req = TestRequest::with_header(
let req = TestRequest::with_header(
"Referer",
"https://www.example.com/some/path?query=param",
).method(Method::POST)
.finish();
assert!(csrf.start(&mut req).is_ok());
assert!(csrf.start(&req).is_ok());
}
#[test]
@ -264,13 +265,13 @@ mod tests {
.allowed_origin("https://www.example.com")
.allow_upgrade();
let mut req = TestRequest::with_header("Origin", "https://cswsh.com")
let req = TestRequest::with_header("Origin", "https://cswsh.com")
.header("Connection", "Upgrade")
.header("Upgrade", "websocket")
.method(Method::GET)
.finish();
assert!(strict_csrf.start(&mut req).is_err());
assert!(lax_csrf.start(&mut req).is_ok());
assert!(strict_csrf.start(&req).is_err());
assert!(lax_csrf.start(&req).is_ok());
}
}

View File

@ -74,9 +74,7 @@ impl DefaultHeaders {
}
impl<S> Middleware<S> for DefaultHeaders {
fn response(
&self, _: &mut HttpRequest<S>, mut resp: HttpResponse,
) -> Result<Response> {
fn response(&self, _: &HttpRequest<S>, mut resp: HttpResponse) -> Result<Response> {
for (key, value) in self.headers.iter() {
if !resp.headers().contains_key(key) {
resp.headers_mut().insert(key, value.clone());
@ -97,22 +95,23 @@ impl<S> Middleware<S> for DefaultHeaders {
mod tests {
use super::*;
use http::header::CONTENT_TYPE;
use test::TestRequest;
#[test]
fn test_default_headers() {
let mw = DefaultHeaders::new().header(CONTENT_TYPE, "0001");
let mut req = HttpRequest::default();
let req = TestRequest::default().finish();
let resp = HttpResponse::Ok().finish();
let resp = match mw.response(&mut req, resp) {
let resp = match mw.response(&req, resp) {
Ok(Response::Done(resp)) => resp,
_ => panic!(),
};
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
let resp = HttpResponse::Ok().header(CONTENT_TYPE, "0002").finish();
let resp = match mw.response(&mut req, resp) {
let resp = match mw.response(&req, resp) {
Ok(Response::Done(resp)) => resp,
_ => panic!(),
};

View File

@ -6,7 +6,7 @@ use httprequest::HttpRequest;
use httpresponse::HttpResponse;
use middleware::{Middleware, Response};
type ErrorHandler<S> = Fn(&mut HttpRequest<S>, HttpResponse) -> Result<Response>;
type ErrorHandler<S> = Fn(&HttpRequest<S>, HttpResponse) -> Result<Response>;
/// `Middleware` for allowing custom handlers for responses.
///
@ -21,7 +21,7 @@ type ErrorHandler<S> = Fn(&mut HttpRequest<S>, HttpResponse) -> Result<Response>
/// use actix_web::middleware::{ErrorHandlers, Response};
/// use actix_web::{http, App, HttpRequest, HttpResponse, Result};
///
/// fn render_500<S>(_: &mut HttpRequest<S>, resp: HttpResponse) -> Result<Response> {
/// fn render_500<S>(_: &HttpRequest<S>, resp: HttpResponse) -> Result<Response> {
/// let mut builder = resp.into_builder();
/// builder.header(http::header::CONTENT_TYPE, "application/json");
/// Ok(Response::Done(builder.into()))
@ -62,7 +62,7 @@ impl<S> ErrorHandlers<S> {
/// Register error handler for specified status code
pub fn handler<F>(mut self, status: StatusCode, handler: F) -> Self
where
F: Fn(&mut HttpRequest<S>, HttpResponse) -> Result<Response> + 'static,
F: Fn(&HttpRequest<S>, HttpResponse) -> Result<Response> + 'static,
{
self.handlers.insert(status, Box::new(handler));
self
@ -70,9 +70,7 @@ impl<S> ErrorHandlers<S> {
}
impl<S: 'static> Middleware<S> for ErrorHandlers<S> {
fn response(
&self, req: &mut HttpRequest<S>, resp: HttpResponse,
) -> Result<Response> {
fn response(&self, req: &HttpRequest<S>, resp: HttpResponse) -> Result<Response> {
if let Some(handler) = self.handlers.get(&resp.status()) {
handler(req, resp)
} else {
@ -91,7 +89,10 @@ mod tests {
use middleware::Started;
use test;
fn render_500<S>(_: &mut HttpRequest<S>, resp: HttpResponse) -> Result<Response> {
use server::Request;
use test::TestRequest;
fn render_500<S>(_: &HttpRequest<S>, resp: HttpResponse) -> Result<Response> {
let mut builder = resp.into_builder();
builder.header(CONTENT_TYPE, "0001");
Ok(Response::Done(builder.into()))
@ -102,7 +103,7 @@ mod tests {
let mw =
ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
let mut req = HttpRequest::default();
let mut req = TestRequest::default().finish();
let resp = HttpResponse::InternalServerError().finish();
let resp = match mw.response(&mut req, resp) {
Ok(Response::Done(resp)) => resp,
@ -121,7 +122,7 @@ mod tests {
struct MiddlewareOne;
impl<S> Middleware<S> for MiddlewareOne {
fn start(&self, _req: &mut HttpRequest<S>) -> Result<Started, Error> {
fn start(&self, _: &HttpRequest<S>) -> Result<Started, Error> {
Err(ErrorInternalServerError("middleware error"))
}
}

View File

@ -46,6 +46,7 @@
//! ));
//! }
//! ```
use std::cell::RefCell;
use std::rc::Rc;
use cookie::{Cookie, CookieJar, Key};
@ -58,6 +59,7 @@ use http::header::{self, HeaderValue};
use httprequest::HttpRequest;
use httpresponse::HttpResponse;
use middleware::{Middleware, Response, Started};
use server::Request;
/// The helper trait to obtain your identity from a request.
///
@ -88,32 +90,32 @@ use middleware::{Middleware, Response, Started};
pub trait RequestIdentity {
/// Return the claimed identity of the user associated request or
/// ``None`` if no identity can be found associated with the request.
fn identity(&self) -> Option<&str>;
fn identity(&self) -> Option<String>;
/// Remember identity.
fn remember(&mut self, identity: String);
fn remember(&self, identity: String);
/// This method is used to 'forget' the current identity on subsequent
/// requests.
fn forget(&mut self);
fn forget(&self);
}
impl<S> RequestIdentity for HttpRequest<S> {
fn identity(&self) -> Option<&str> {
fn identity(&self) -> Option<String> {
if let Some(id) = self.extensions().get::<IdentityBox>() {
return id.0.identity();
return id.0.identity().map(|s| s.to_owned());
}
None
}
fn remember(&mut self, identity: String) {
if let Some(id) = self.extensions_mut().get_mut::<IdentityBox>() {
return id.0.remember(identity);
fn remember(&self, identity: String) {
if let Some(mut id) = self.extensions_mut().get_mut::<IdentityBox>() {
return id.0.as_mut().remember(identity);
}
}
fn forget(&mut self) {
if let Some(id) = self.extensions_mut().get_mut::<IdentityBox>() {
fn forget(&self) {
if let Some(mut id) = self.extensions_mut().get_mut::<IdentityBox>() {
return id.0.forget();
}
}
@ -145,7 +147,7 @@ pub trait IdentityPolicy<S>: Sized + 'static {
type Future: Future<Item = Self::Identity, Error = Error>;
/// Parse the session from request and load data from a service identity.
fn from_request(&self, request: &mut HttpRequest<S>) -> Self::Future;
fn from_request(&self, request: &HttpRequest<S>) -> Self::Future;
}
/// Request identity middleware
@ -178,27 +180,21 @@ impl<T> IdentityService<T> {
struct IdentityBox(Box<Identity>);
impl<S: 'static, T: IdentityPolicy<S>> Middleware<S> for IdentityService<T> {
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
let mut req = req.clone();
let fut = self
.backend
.from_request(&mut req)
.then(move |res| match res {
Ok(id) => {
req.extensions_mut().insert(IdentityBox(Box::new(id)));
FutOk(None)
}
Err(err) => FutErr(err),
});
fn start(&self, req: &HttpRequest<S>) -> Result<Started> {
let req = req.clone();
let fut = self.backend.from_request(&req).then(move |res| match res {
Ok(id) => {
req.extensions_mut().insert(IdentityBox(Box::new(id)));
FutOk(None)
}
Err(err) => FutErr(err),
});
Ok(Started::Future(Box::new(fut)))
}
fn response(
&self, req: &mut HttpRequest<S>, resp: HttpResponse,
) -> Result<Response> {
if let Some(mut id) = req.extensions_mut().remove::<IdentityBox>() {
id.0.write(resp)
fn response(&self, req: &HttpRequest<S>, resp: HttpResponse) -> Result<Response> {
if let Some(ref mut id) = req.extensions_mut().get_mut::<IdentityBox>() {
id.0.as_mut().write(resp)
} else {
Ok(Response::Done(resp))
}
@ -291,9 +287,9 @@ impl CookieIdentityInner {
Ok(())
}
fn load<S>(&self, req: &mut HttpRequest<S>) -> Option<String> {
fn load<S>(&self, req: &HttpRequest<S>) -> Option<String> {
if let Ok(cookies) = req.cookies() {
for cookie in cookies {
for cookie in cookies.iter() {
if cookie.name() == self.name {
let mut jar = CookieJar::new();
jar.add_original(cookie.clone());
@ -382,7 +378,7 @@ impl<S> IdentityPolicy<S> for CookieIdentityPolicy {
type Identity = CookieIdentity;
type Future = FutureResult<CookieIdentity, Error>;
fn from_request(&self, req: &mut HttpRequest<S>) -> Self::Future {
fn from_request(&self, req: &HttpRequest<S>) -> Self::Future {
let identity = self.0.load(req);
FutOk(CookieIdentity {
identity,

View File

@ -11,6 +11,7 @@ use httpmessage::HttpMessage;
use httprequest::HttpRequest;
use httpresponse::HttpResponse;
use middleware::{Finished, Middleware, Started};
use server::Request;
/// `Middleware` for logging request and response info to the terminal.
///
@ -107,7 +108,7 @@ impl Default for Logger {
struct StartTime(time::Tm);
impl Logger {
fn log<S>(&self, req: &mut HttpRequest<S>, resp: &HttpResponse) {
fn log<S>(&self, req: &HttpRequest<S>, resp: &HttpResponse) {
if let Some(entry_time) = req.extensions().get::<StartTime>() {
let render = |fmt: &mut Formatter| {
for unit in &self.format.0 {
@ -121,14 +122,14 @@ impl Logger {
}
impl<S> Middleware<S> for Logger {
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
fn start(&self, req: &HttpRequest<S>) -> Result<Started> {
if !self.exclude.contains(req.path()) {
req.extensions_mut().insert(StartTime(time::now()));
}
Ok(Started::Done)
}
fn finish(&self, req: &mut HttpRequest<S>, resp: &HttpResponse) -> Finished {
fn finish(&self, req: &HttpRequest<S>, resp: &HttpResponse) -> Finished {
self.log(req, resp);
Finished::Done
}
@ -312,34 +313,27 @@ mod tests {
use http::header::{self, HeaderMap};
use http::{Method, StatusCode, Uri, Version};
use std::str::FromStr;
use test::TestRequest;
use time;
#[test]
fn test_logger() {
let logger = Logger::new("%% %{User-Agent}i %{X-Test}o %{HOME}e %D test");
let mut headers = HeaderMap::new();
headers.insert(
let req = TestRequest::with_header(
header::USER_AGENT,
header::HeaderValue::from_static("ACTIX-WEB"),
);
let mut req = HttpRequest::new(
Method::GET,
Uri::from_str("/").unwrap(),
Version::HTTP_11,
headers,
None,
);
).finish();
let resp = HttpResponse::build(StatusCode::OK)
.header("X-Test", "ttt")
.force_close()
.finish();
match logger.start(&mut req) {
match logger.start(&req) {
Ok(Started::Done) => (),
_ => panic!(),
};
match logger.finish(&mut req, &resp) {
match logger.finish(&req, &resp) {
Finished::Done => (),
_ => panic!(),
}
@ -358,18 +352,10 @@ mod tests {
fn test_default_format() {
let format = Format::default();
let mut headers = HeaderMap::new();
headers.insert(
let req = TestRequest::with_header(
header::USER_AGENT,
header::HeaderValue::from_static("ACTIX-WEB"),
);
let req = HttpRequest::new(
Method::GET,
Uri::from_str("/").unwrap(),
Version::HTTP_11,
headers,
None,
);
).finish();
let resp = HttpResponse::build(StatusCode::OK).force_close().finish();
let entry_time = time::now();
@ -384,13 +370,7 @@ mod tests {
assert!(s.contains("200 0"));
assert!(s.contains("ACTIX-WEB"));
let req = HttpRequest::new(
Method::GET,
Uri::from_str("/?test").unwrap(),
Version::HTTP_11,
HeaderMap::new(),
None,
);
let req = TestRequest::with_uri("/?test").finish();
let resp = HttpResponse::build(StatusCode::OK).force_close().finish();
let entry_time = time::now();

View File

@ -4,6 +4,7 @@ use futures::Future;
use error::{Error, Result};
use httprequest::HttpRequest;
use httpresponse::HttpResponse;
use server::Request;
mod logger;
@ -51,20 +52,18 @@ pub enum Finished {
pub trait Middleware<S>: 'static {
/// Method is called when request is ready. It may return
/// future, which should resolve before next middleware get called.
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
fn start(&self, req: &HttpRequest<S>) -> Result<Started> {
Ok(Started::Done)
}
/// Method is called when handler returns response,
/// but before sending http message to peer.
fn response(
&self, req: &mut HttpRequest<S>, resp: HttpResponse,
) -> Result<Response> {
fn response(&self, req: &HttpRequest<S>, resp: HttpResponse) -> Result<Response> {
Ok(Response::Done(resp))
}
/// Method is called after body stream get sent to peer.
fn finish(&self, req: &mut HttpRequest<S>, resp: &HttpResponse) -> Finished {
fn finish(&self, req: &HttpRequest<S>, resp: &HttpResponse) -> Finished {
Finished::Done
}
}

View File

@ -83,6 +83,7 @@ use handler::FromRequest;
use httprequest::HttpRequest;
use httpresponse::HttpResponse;
use middleware::{Middleware, Response, Started};
use server::Request;
/// The helper trait to obtain your session data from a request.
///
@ -246,7 +247,7 @@ impl<S, T: SessionBackend<S>> SessionStorage<T, S> {
}
impl<S: 'static, T: SessionBackend<S>> Middleware<S> for SessionStorage<T, S> {
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
fn start(&self, req: &HttpRequest<S>) -> Result<Started> {
let mut req = req.clone();
let fut = self.0.from_request(&mut req).then(move |res| match res {
@ -260,10 +261,8 @@ impl<S: 'static, T: SessionBackend<S>> Middleware<S> for SessionStorage<T, S> {
Ok(Started::Future(Box::new(fut)))
}
fn response(
&self, req: &mut HttpRequest<S>, resp: HttpResponse,
) -> Result<Response> {
if let Some(s_box) = req.extensions_mut().remove::<Arc<SessionImplCell>>() {
fn response(&self, req: &HttpRequest<S>, resp: HttpResponse) -> Result<Response> {
if let Some(s_box) = req.extensions().get::<Arc<SessionImplCell>>() {
s_box.0.borrow_mut().write(resp)
} else {
Ok(Response::Done(resp))
@ -421,7 +420,7 @@ impl CookieSessionInner {
fn load<S>(&self, req: &mut HttpRequest<S>) -> HashMap<String, String> {
if let Ok(cookies) = req.cookies() {
for cookie in cookies {
for cookie in cookies.iter() {
if cookie.name() == self.name {
let mut jar = CookieJar::new();
jar.add_original(cookie.clone());