From 118606262be9dcfe64b9870308cd2dccb26111d3 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Wed, 13 Feb 2019 13:52:11 -0800 Subject: [PATCH] refactor payload handling --- examples/echo.rs | 2 +- examples/echo2.rs | 2 +- src/client/h1proto.rs | 5 ++- src/client/h2proto.rs | 7 ++-- src/client/response.rs | 22 +++++----- src/h1/dispatcher.rs | 4 +- src/h1/service.rs | 3 +- src/httpmessage.rs | 95 ++++++++++++++++++++++++++++-------------- src/json.rs | 31 +++++++++----- src/message.rs | 25 ++++++++++- src/payload.rs | 20 ++++----- src/request.rs | 71 ++++++++++++++++--------------- tests/test_client.rs | 4 +- tests/test_server.rs | 20 ++++----- 14 files changed, 186 insertions(+), 125 deletions(-) diff --git a/examples/echo.rs b/examples/echo.rs index 5b68024f1..03d5b4706 100644 --- a/examples/echo.rs +++ b/examples/echo.rs @@ -18,7 +18,7 @@ fn main() { .client_timeout(1000) .client_disconnect(1000) .server_hostname("localhost") - .finish(|req: Request| { + .finish(|mut req: Request| { req.body().limit(512).and_then(|bytes: Bytes| { info!("request body: {:?}", bytes); let mut res = Response::Ok(); diff --git a/examples/echo2.rs b/examples/echo2.rs index daaafa087..2fd9cbcff 100644 --- a/examples/echo2.rs +++ b/examples/echo2.rs @@ -8,7 +8,7 @@ use futures::Future; use log::info; use std::env; -fn handle_request(req: Request) -> impl Future { +fn handle_request(mut req: Request) -> impl Future { req.body().limit(512).from_err().and_then(|bytes: Bytes| { info!("request body: {:?}", bytes); let mut res = Response::Ok(); diff --git a/src/client/h1proto.rs b/src/client/h1proto.rs index d16491385..3329fcfec 100644 --- a/src/client/h1proto.rs +++ b/src/client/h1proto.rs @@ -13,7 +13,6 @@ use crate::body::{BodyLength, MessageBody}; use crate::error::PayloadError; use crate::h1; use crate::message::RequestHead; -use crate::payload::PayloadStream; pub(crate) fn send_request( io: T, @@ -205,7 +204,9 @@ pub(crate) struct Payload { } impl Payload { - pub fn stream(framed: Framed) -> PayloadStream { + pub fn stream( + framed: Framed, + ) -> Box> { Box::new(Payload { framed: Some(framed.map_codec(|codec| codec.into_payload_codec())), }) diff --git a/src/client/h2proto.rs b/src/client/h2proto.rs index 697d30a41..8804d13f2 100644 --- a/src/client/h2proto.rs +++ b/src/client/h2proto.rs @@ -1,4 +1,3 @@ -use std::cell::RefCell; use std::time; use actix_codec::{AsyncRead, AsyncWrite}; @@ -10,7 +9,7 @@ use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCOD use http::{request::Request, HttpTryFrom, Version}; use crate::body::{BodyLength, MessageBody}; -use crate::message::{RequestHead, ResponseHead}; +use crate::message::{Message, RequestHead, ResponseHead}; use super::connection::{ConnectionType, IoConnection}; use super::error::SendRequestError; @@ -103,14 +102,14 @@ where .and_then(|resp| { let (parts, body) = resp.into_parts(); - let mut head = ResponseHead::default(); + let mut head: Message = Message::new(); head.version = parts.version; head.status = parts.status; head.headers = parts.headers; Ok(ClientResponse { head, - payload: RefCell::new(body.into()), + payload: body.into(), }) }) .from_err() diff --git a/src/client/response.rs b/src/client/response.rs index f19e2d17a..104d28ed7 100644 --- a/src/client/response.rs +++ b/src/client/response.rs @@ -1,5 +1,4 @@ -use std::cell::RefCell; -use std::{fmt, mem}; +use std::fmt; use bytes::Bytes; use futures::{Poll, Stream}; @@ -7,13 +6,13 @@ use http::{HeaderMap, StatusCode, Version}; use crate::error::PayloadError; use crate::httpmessage::HttpMessage; -use crate::message::{Head, ResponseHead}; +use crate::message::{Head, Message, ResponseHead}; use crate::payload::{Payload, PayloadStream}; /// Client Response pub struct ClientResponse { - pub(crate) head: ResponseHead, - pub(crate) payload: RefCell, + pub(crate) head: Message, + pub(crate) payload: Payload, } impl HttpMessage for ClientResponse { @@ -23,9 +22,8 @@ impl HttpMessage for ClientResponse { &self.head.headers } - #[inline] - fn payload(&self) -> Payload { - mem::replace(&mut *self.payload.borrow_mut(), Payload::None) + fn take_payload(&mut self) -> Payload { + std::mem::replace(&mut self.payload, Payload::None) } } @@ -33,8 +31,8 @@ impl ClientResponse { /// Create new Request instance pub fn new() -> ClientResponse { ClientResponse { - head: ResponseHead::default(), - payload: RefCell::new(Payload::None), + head: Message::new(), + payload: Payload::None, } } @@ -80,7 +78,7 @@ impl ClientResponse { /// Set response payload pub fn set_payload(&mut self, payload: Payload) { - *self.payload.get_mut() = payload; + self.payload = payload; } } @@ -89,7 +87,7 @@ impl Stream for ClientResponse { type Error = PayloadError; fn poll(&mut self) -> Poll, Self::Error> { - self.payload.get_mut().poll() + self.payload.poll() } } diff --git a/src/h1/dispatcher.rs b/src/h1/dispatcher.rs index c242333b9..22d7ea865 100644 --- a/src/h1/dispatcher.rs +++ b/src/h1/dispatcher.rs @@ -316,7 +316,9 @@ where match self.framed.get_codec().message_type() { MessageType::Payload => { let (ps, pl) = Payload::create(false); - req = req.set_payload(crate::Payload::H1(pl)); + let (req1, _) = + req.replace_payload(crate::Payload::H1(pl)); + req = req1; self.payload = Some(ps); } MessageType::Stream => { diff --git a/src/h1/service.rs b/src/h1/service.rs index 381864498..cb8dae54d 100644 --- a/src/h1/service.rs +++ b/src/h1/service.rs @@ -12,7 +12,6 @@ use log::error; use crate::body::MessageBody; use crate::config::{KeepAlive, ServiceConfig}; use crate::error::{DispatchError, ParseError}; -use crate::payload::PayloadStream; use crate::request::Request; use crate::response::Response; @@ -29,7 +28,7 @@ pub struct H1Service { impl H1Service where - S: NewService>, + S: NewService, S::Error: Debug, S::Response: Into>, S::Service: 'static, diff --git a/src/httpmessage.rs b/src/httpmessage.rs index 57ad4bf95..79f29a723 100644 --- a/src/httpmessage.rs +++ b/src/httpmessage.rs @@ -1,4 +1,4 @@ -use std::{mem, str}; +use std::str; use bytes::{Bytes, BytesMut}; use encoding::all::UTF_8; @@ -21,13 +21,13 @@ use crate::payload::Payload; /// Trait that implements general purpose operations on http messages pub trait HttpMessage: Sized { /// Type of message payload stream - type Stream: Stream + Sized; + type Stream; /// Read the message headers. fn headers(&self) -> &HeaderMap; /// Message payload stream - fn payload(&self) -> Payload; + fn take_payload(&mut self) -> Payload; #[doc(hidden)] /// Get a header @@ -130,7 +130,10 @@ pub trait HttpMessage: Sized { /// } /// # fn main() {} /// ``` - fn body(&self) -> MessageBody { + fn body(&mut self) -> MessageBody + where + Self::Stream: Stream + Sized, + { MessageBody::new(self) } @@ -164,7 +167,10 @@ pub trait HttpMessage: Sized { /// } /// # fn main() {} /// ``` - fn urlencoded(&self) -> UrlEncoded { + fn urlencoded(&mut self) -> UrlEncoded + where + Self::Stream: Stream, + { UrlEncoded::new(self) } @@ -200,12 +206,18 @@ pub trait HttpMessage: Sized { /// } /// # fn main() {} /// ``` - fn json(&self) -> JsonBody { + fn json(&mut self) -> JsonBody + where + Self::Stream: Stream + 'static, + { JsonBody::new(self) } /// Return stream of lines. - fn readlines(&self) -> Readlines { + fn readlines(&mut self) -> Readlines + where + Self::Stream: Stream + 'static, + { Readlines::new(self) } } @@ -220,16 +232,20 @@ pub struct Readlines { err: Option, } -impl Readlines { +impl Readlines +where + T: HttpMessage, + T::Stream: Stream, +{ /// Create a new stream to read request line by line. - fn new(req: &T) -> Self { + fn new(req: &mut T) -> Self { let encoding = match req.encoding() { Ok(enc) => enc, Err(err) => return Self::err(err.into()), }; Readlines { - stream: req.payload(), + stream: req.take_payload(), buff: BytesMut::with_capacity(262_144), limit: 262_144, checked_buff: true, @@ -256,7 +272,11 @@ impl Readlines { } } -impl Stream for Readlines { +impl Stream for Readlines +where + T: HttpMessage, + T::Stream: Stream, +{ type Item = String; type Error = ReadlinesError; @@ -362,9 +382,13 @@ pub struct MessageBody { fut: Option>>, } -impl MessageBody { +impl MessageBody +where + T: HttpMessage, + T::Stream: Stream, +{ /// Create `MessageBody` for request. - pub fn new(req: &T) -> MessageBody { + pub fn new(req: &mut T) -> MessageBody { let mut len = None; if let Some(l) = req.headers().get(header::CONTENT_LENGTH) { if let Ok(s) = l.to_str() { @@ -379,9 +403,9 @@ impl MessageBody { } MessageBody { + stream: req.take_payload(), limit: 262_144, length: len, - stream: req.payload(), fut: None, err: None, } @@ -406,7 +430,8 @@ impl MessageBody { impl Future for MessageBody where - T: HttpMessage + 'static, + T: HttpMessage, + T::Stream: Stream + 'static, { type Item = Bytes; type Error = PayloadError; @@ -429,7 +454,7 @@ where // future let limit = self.limit; self.fut = Some(Box::new( - mem::replace(&mut self.stream, Payload::None) + std::mem::replace(&mut self.stream, Payload::None) .from_err() .fold(BytesMut::with_capacity(8192), move |mut body, chunk| { if (body.len() + chunk.len()) > limit { @@ -455,9 +480,13 @@ pub struct UrlEncoded { fut: Option>>, } -impl UrlEncoded { +impl UrlEncoded +where + T: HttpMessage, + T::Stream: Stream, +{ /// Create a new future to URL encode a request - pub fn new(req: &T) -> UrlEncoded { + pub fn new(req: &mut T) -> UrlEncoded { // check content type if req.content_type().to_lowercase() != "application/x-www-form-urlencoded" { return Self::err(UrlencodedError::ContentType); @@ -482,7 +511,7 @@ impl UrlEncoded { UrlEncoded { encoding, - stream: req.payload(), + stream: req.take_payload(), limit: 262_144, length: len, fut: None, @@ -510,7 +539,8 @@ impl UrlEncoded { impl Future for UrlEncoded where - T: HttpMessage + 'static, + T: HttpMessage, + T::Stream: Stream + 'static, U: DeserializeOwned + 'static, { type Item = U; @@ -535,7 +565,7 @@ where // future let encoding = self.encoding; - let fut = mem::replace(&mut self.stream, Payload::None) + let fut = std::mem::replace(&mut self.stream, Payload::None) .from_err() .fold(BytesMut::with_capacity(8192), move |mut body, chunk| { if (body.len() + chunk.len()) > limit { @@ -691,7 +721,7 @@ mod tests { #[test] fn test_urlencoded_error() { - let req = TestRequest::with_header( + let mut req = TestRequest::with_header( header::CONTENT_TYPE, "application/x-www-form-urlencoded", ) @@ -702,7 +732,7 @@ mod tests { UrlencodedError::UnknownLength ); - let req = TestRequest::with_header( + let mut req = TestRequest::with_header( header::CONTENT_TYPE, "application/x-www-form-urlencoded", ) @@ -713,7 +743,7 @@ mod tests { UrlencodedError::Overflow ); - let req = TestRequest::with_header(header::CONTENT_TYPE, "text/plain") + let mut req = TestRequest::with_header(header::CONTENT_TYPE, "text/plain") .header(header::CONTENT_LENGTH, "10") .finish(); assert_eq!( @@ -724,7 +754,7 @@ mod tests { #[test] fn test_urlencoded() { - let req = TestRequest::with_header( + let mut req = TestRequest::with_header( header::CONTENT_TYPE, "application/x-www-form-urlencoded", ) @@ -740,7 +770,7 @@ mod tests { }) ); - let req = TestRequest::with_header( + let mut req = TestRequest::with_header( header::CONTENT_TYPE, "application/x-www-form-urlencoded; charset=utf-8", ) @@ -759,19 +789,20 @@ mod tests { #[test] fn test_message_body() { - let req = TestRequest::with_header(header::CONTENT_LENGTH, "xxxx").finish(); + let mut req = TestRequest::with_header(header::CONTENT_LENGTH, "xxxx").finish(); match req.body().poll().err().unwrap() { PayloadError::UnknownLength => (), _ => unreachable!("error"), } - let req = TestRequest::with_header(header::CONTENT_LENGTH, "1000000").finish(); + let mut req = + TestRequest::with_header(header::CONTENT_LENGTH, "1000000").finish(); match req.body().poll().err().unwrap() { PayloadError::Overflow => (), _ => unreachable!("error"), } - let req = TestRequest::default() + let mut req = TestRequest::default() .set_payload(Bytes::from_static(b"test")) .finish(); match req.body().poll().ok().unwrap() { @@ -779,7 +810,7 @@ mod tests { _ => unreachable!("error"), } - let req = TestRequest::default() + let mut req = TestRequest::default() .set_payload(Bytes::from_static(b"11111111111111")) .finish(); match req.body().limit(5).poll().err().unwrap() { @@ -790,14 +821,14 @@ mod tests { #[test] fn test_readlines() { - let req = TestRequest::default() + let mut req = TestRequest::default() .set_payload(Bytes::from_static( b"Lorem Ipsum is simply dummy text of the printing and typesetting\n\ industry. Lorem Ipsum has been the industry's standard dummy\n\ Contrary to popular belief, Lorem Ipsum is not simply random text.", )) .finish(); - let mut r = Readlines::new(&req); + let mut r = Readlines::new(&mut req); match r.poll().ok().unwrap() { Async::Ready(Some(s)) => assert_eq!( s, diff --git a/src/json.rs b/src/json.rs index 573fde411..026ecb871 100644 --- a/src/json.rs +++ b/src/json.rs @@ -2,11 +2,12 @@ use bytes::BytesMut; use futures::{Future, Poll, Stream}; use http::header::CONTENT_LENGTH; +use bytes::Bytes; use mime; use serde::de::DeserializeOwned; use serde_json; -use crate::error::JsonPayloadError; +use crate::error::{JsonPayloadError, PayloadError}; use crate::httpmessage::HttpMessage; use crate::payload::Payload; @@ -41,7 +42,7 @@ use crate::payload::Payload; /// } /// # fn main() {} /// ``` -pub struct JsonBody { +pub struct JsonBody { limit: usize, length: Option, stream: Payload, @@ -49,9 +50,14 @@ pub struct JsonBody { fut: Option>>, } -impl JsonBody { +impl JsonBody +where + T: HttpMessage, + T::Stream: Stream + 'static, + U: DeserializeOwned + 'static, +{ /// Create `JsonBody` for request. - pub fn new(req: &T) -> Self { + pub fn new(req: &mut T) -> Self { // check content-type let json = if let Ok(Some(mime)) = req.mime_type() { mime.subtype() == mime::JSON || mime.suffix() == Some(mime::JSON) @@ -80,7 +86,7 @@ impl JsonBody { JsonBody { limit: 262_144, length: len, - stream: req.payload(), + stream: req.take_payload(), fut: None, err: None, } @@ -93,7 +99,12 @@ impl JsonBody { } } -impl Future for JsonBody { +impl Future for JsonBody +where + T: HttpMessage, + T::Stream: Stream + 'static, + U: DeserializeOwned + 'static, +{ type Item = U; type Error = JsonPayloadError; @@ -162,11 +173,11 @@ mod tests { #[test] fn test_json_body() { - let req = TestRequest::default().finish(); + let mut req = TestRequest::default().finish(); let mut json = req.json::(); assert_eq!(json.poll().err().unwrap(), JsonPayloadError::ContentType); - let req = TestRequest::default() + let mut req = TestRequest::default() .header( header::CONTENT_TYPE, header::HeaderValue::from_static("application/text"), @@ -175,7 +186,7 @@ mod tests { let mut json = req.json::(); assert_eq!(json.poll().err().unwrap(), JsonPayloadError::ContentType); - let req = TestRequest::default() + let mut req = TestRequest::default() .header( header::CONTENT_TYPE, header::HeaderValue::from_static("application/json"), @@ -188,7 +199,7 @@ mod tests { let mut json = req.json::().limit(100); assert_eq!(json.poll().err().unwrap(), JsonPayloadError::Overflow); - let req = TestRequest::default() + let mut req = TestRequest::default() .header( header::CONTENT_TYPE, header::HeaderValue::from_static("application/json"), diff --git a/src/message.rs b/src/message.rs index 7fb45bcc5..812f099e4 100644 --- a/src/message.rs +++ b/src/message.rs @@ -2,9 +2,8 @@ use std::cell::{Ref, RefCell, RefMut}; use std::collections::VecDeque; use std::rc::Rc; -use http::{HeaderMap, Method, StatusCode, Uri, Version}; - use crate::extensions::Extensions; +use crate::http::{HeaderMap, Method, StatusCode, Uri, Version}; /// Represents various types of connection #[derive(Copy, Clone, PartialEq, Debug)] @@ -21,6 +20,12 @@ pub enum ConnectionType { pub trait Head: Default + 'static { fn clear(&mut self); + /// Read the message headers. + fn headers(&self) -> &HeaderMap; + + /// Mutable reference to the message headers. + fn headers_mut(&mut self) -> &mut HeaderMap; + /// Connection type fn connection_type(&self) -> ConnectionType; @@ -68,6 +73,14 @@ impl Head for RequestHead { self.extensions.borrow_mut().clear(); } + fn headers(&self) -> &HeaderMap { + &self.headers + } + + fn headers_mut(&mut self) -> &mut HeaderMap { + &mut self.headers + } + fn set_connection_type(&mut self, ctype: ConnectionType) { self.ctype = Some(ctype) } @@ -129,6 +142,14 @@ impl Head for ResponseHead { self.headers.clear(); } + fn headers(&self) -> &HeaderMap { + &self.headers + } + + fn headers_mut(&mut self) -> &mut HeaderMap { + &mut self.headers + } + fn set_connection_type(&mut self, ctype: ConnectionType) { self.ctype = Some(ctype) } diff --git a/src/payload.rs b/src/payload.rs index 21e415313..bc40fe807 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -15,21 +15,21 @@ pub enum Payload { Stream(S), } -impl From for Payload { - fn from(v: RecvStream) -> Self { - Payload::H2(crate::h2::Payload::new(v)) - } -} - impl From for Payload { - fn from(pl: crate::h1::Payload) -> Self { - Payload::H1(pl) + fn from(v: crate::h1::Payload) -> Self { + Payload::H1(v) } } impl From for Payload { - fn from(pl: crate::h2::Payload) -> Self { - Payload::H2(pl) + fn from(v: crate::h2::Payload) -> Self { + Payload::H2(v) + } +} + +impl From for Payload { + fn from(v: RecvStream) -> Self { + Payload::H2(crate::h2::Payload::new(v)) } } diff --git a/src/request.rs b/src/request.rs index 388fe7543..e1b893f95 100644 --- a/src/request.rs +++ b/src/request.rs @@ -1,11 +1,8 @@ -use std::cell::{Ref, RefCell, RefMut}; -use std::{fmt, mem}; +use std::cell::{Ref, RefMut}; +use std::fmt; -use bytes::Bytes; -use futures::Stream; use http::{header, HeaderMap, Method, Uri, Version}; -use crate::error::PayloadError; use crate::extensions::Extensions; use crate::httpmessage::HttpMessage; use crate::message::{Message, RequestHead}; @@ -13,31 +10,27 @@ use crate::payload::{Payload, PayloadStream}; /// Request pub struct Request

{ - pub(crate) payload: RefCell>, - pub(crate) inner: Message, + pub(crate) payload: Payload

, + pub(crate) head: Message, } -impl

HttpMessage for Request

-where - P: Stream, -{ +impl

HttpMessage for Request

{ type Stream = P; fn headers(&self) -> &HeaderMap { &self.head().headers } - #[inline] - fn payload(&self) -> Payload { - mem::replace(&mut *self.payload.borrow_mut(), Payload::None) + fn take_payload(&mut self) -> Payload

{ + std::mem::replace(&mut self.payload, Payload::None) } } -impl

From> for Request

{ - fn from(msg: Message) -> Self { +impl From> for Request { + fn from(head: Message) -> Self { Request { - payload: RefCell::new(Payload::None), - inner: msg, + head, + payload: Payload::None, } } } @@ -46,8 +39,8 @@ impl Request { /// Create new Request instance pub fn new() -> Request { Request { - payload: RefCell::new(Payload::None), - inner: Message::new(), + head: Message::new(), + payload: Payload::None, } } } @@ -56,38 +49,44 @@ impl

Request

{ /// Create new Request instance pub fn with_payload(payload: Payload

) -> Request

{ Request { - payload: RefCell::new(payload), - inner: Message::new(), + payload, + head: Message::new(), } } /// Create new Request instance - pub fn set_payload(self, payload: I) -> Request - where - I: Into>, - { - Request { - payload: RefCell::new(payload.into()), - inner: self.inner, - } + pub fn replace_payload(self, payload: Payload) -> (Request, Payload

) { + let pl = self.payload; + ( + Request { + payload, + head: self.head, + }, + pl, + ) + } + + /// Get request's payload + pub fn take_payload(&mut self) -> Payload

{ + std::mem::replace(&mut self.payload, Payload::None) } /// Split request into request head and payload pub fn into_parts(self) -> (Message, Payload

) { - (self.inner, self.payload.into_inner()) + (self.head, self.payload) } #[inline] /// Http message part of the request pub fn head(&self) -> &RequestHead { - &*self.inner + &*self.head } #[inline] #[doc(hidden)] /// Mutable reference to a http message part of the request pub fn head_mut(&mut self) -> &mut RequestHead { - &mut *self.inner + &mut *self.head } /// Request's uri. @@ -135,13 +134,13 @@ impl

Request

{ /// Request extensions #[inline] pub fn extensions(&self) -> Ref { - self.inner.extensions() + self.head.extensions() } /// Mutable reference to a the request's extensions #[inline] pub fn extensions_mut(&self) -> RefMut { - self.inner.extensions_mut() + self.head.extensions_mut() } /// Check if request requires connection upgrade @@ -155,7 +154,7 @@ impl

Request

{ } } -impl fmt::Debug for Request { +impl

fmt::Debug for Request

{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!( f, diff --git a/tests/test_client.rs b/tests/test_client.rs index 606bac22a..6f502b0af 100644 --- a/tests/test_client.rs +++ b/tests/test_client.rs @@ -47,7 +47,7 @@ fn test_h1_v2() { assert!(repr.contains("ClientRequest")); assert!(repr.contains("x-test")); - let response = srv.block_on(request.send(&mut connector)).unwrap(); + let mut response = srv.block_on(request.send(&mut connector)).unwrap(); assert!(response.status().is_success()); // read response @@ -55,7 +55,7 @@ fn test_h1_v2() { assert_eq!(bytes, Bytes::from_static(STR.as_ref())); let request = srv.post().finish().unwrap(); - let response = srv.block_on(request.send(&mut connector)).unwrap(); + let mut response = srv.block_on(request.send(&mut connector)).unwrap(); assert!(response.status().is_success()); // read response diff --git a/tests/test_server.rs b/tests/test_server.rs index 9fa27e71b..53db38403 100644 --- a/tests/test_server.rs +++ b/tests/test_server.rs @@ -89,7 +89,7 @@ fn test_h2_body() -> std::io::Result<()> { .map_err(|e| println!("Openssl error: {}", e)) .and_then( h2::H2Service::build() - .finish(|req: Request<_>| { + .finish(|mut req: Request<_>| { req.body() .limit(1024 * 1024) .and_then(|body| Ok(Response::Ok().body(body))) @@ -101,7 +101,7 @@ fn test_h2_body() -> std::io::Result<()> { let req = client::ClientRequest::get(srv.surl("/")) .body(data.clone()) .unwrap(); - let response = srv.send_request(req).unwrap(); + let mut response = srv.send_request(req).unwrap(); assert!(response.status().is_success()); let body = srv.block_on(response.body().limit(1024 * 1024)).unwrap(); @@ -350,7 +350,7 @@ fn test_headers() { let req = srv.get().finish().unwrap(); - let response = srv.block_on(req.send(&mut connector)).unwrap(); + let mut response = srv.block_on(req.send(&mut connector)).unwrap(); assert!(response.status().is_success()); // read response @@ -387,7 +387,7 @@ fn test_body() { }); let req = srv.get().finish().unwrap(); - let response = srv.send_request(req).unwrap(); + let mut response = srv.send_request(req).unwrap(); assert!(response.status().is_success()); // read response @@ -402,7 +402,7 @@ fn test_head_empty() { }); let req = client::ClientRequest::head(srv.url("/")).finish().unwrap(); - let response = srv.send_request(req).unwrap(); + let mut response = srv.send_request(req).unwrap(); assert!(response.status().is_success()); { @@ -428,7 +428,7 @@ fn test_head_binary() { }); let req = client::ClientRequest::head(srv.url("/")).finish().unwrap(); - let response = srv.send_request(req).unwrap(); + let mut response = srv.send_request(req).unwrap(); assert!(response.status().is_success()); { @@ -477,7 +477,7 @@ fn test_body_length() { }); let req = srv.get().finish().unwrap(); - let response = srv.send_request(req).unwrap(); + let mut response = srv.send_request(req).unwrap(); assert!(response.status().is_success()); // read response @@ -496,7 +496,7 @@ fn test_body_chunked_explicit() { }); let req = srv.get().finish().unwrap(); - let response = srv.send_request(req).unwrap(); + let mut response = srv.send_request(req).unwrap(); assert!(response.status().is_success()); // read response @@ -517,7 +517,7 @@ fn test_body_chunked_implicit() { }); let req = srv.get().finish().unwrap(); - let response = srv.send_request(req).unwrap(); + let mut response = srv.send_request(req).unwrap(); assert!(response.status().is_success()); // read response @@ -540,7 +540,7 @@ fn test_response_http_error_handling() { }); let req = srv.get().finish().unwrap(); - let response = srv.send_request(req).unwrap(); + let mut response = srv.send_request(req).unwrap(); assert_eq!(response.status(), http::StatusCode::INTERNAL_SERVER_ERROR); // read response