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 5b68024f..03d5b470 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 daaafa08..2fd9cbcf 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 d1649138..3329fcfe 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 697d30a4..8804d13f 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 f19e2d17..104d28ed 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 c242333b..22d7ea86 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 38186449..cb8dae54 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 57ad4bf9..79f29a72 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 573fde41..026ecb87 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 7fb45bcc..812f099e 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 21e41531..bc40fe80 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 388fe754..e1b893f9 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 606bac22..6f502b0a 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 9fa27e71..53db3840 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