mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-28 09:42:40 +01:00
use BodyLength for request and response body
This commit is contained in:
parent
aa20e2670d
commit
3a4b16a6d5
36
src/body.rs
36
src/body.rs
@ -12,24 +12,26 @@ pub type BodyStream = Box<dyn Stream<Item = Bytes, Error = Error>>;
|
|||||||
/// Type represent streaming payload
|
/// Type represent streaming payload
|
||||||
pub type PayloadStream = Box<dyn Stream<Item = Bytes, Error = PayloadError>>;
|
pub type PayloadStream = Box<dyn Stream<Item = Bytes, Error = PayloadError>>;
|
||||||
|
|
||||||
/// Different type of bory
|
#[derive(Debug)]
|
||||||
pub enum BodyType {
|
/// Different type of body
|
||||||
|
pub enum BodyLength {
|
||||||
None,
|
None,
|
||||||
Zero,
|
Zero,
|
||||||
Sized(usize),
|
Sized(usize),
|
||||||
|
Sized64(u64),
|
||||||
Unsized,
|
Unsized,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Type that provides this trait can be streamed to a peer.
|
/// Type that provides this trait can be streamed to a peer.
|
||||||
pub trait MessageBody {
|
pub trait MessageBody {
|
||||||
fn tp(&self) -> BodyType;
|
fn length(&self) -> BodyLength;
|
||||||
|
|
||||||
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error>;
|
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MessageBody for () {
|
impl MessageBody for () {
|
||||||
fn tp(&self) -> BodyType {
|
fn length(&self) -> BodyLength {
|
||||||
BodyType::Zero
|
BodyLength::Zero
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
||||||
@ -271,8 +273,8 @@ impl AsRef<[u8]> for Binary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MessageBody for Bytes {
|
impl MessageBody for Bytes {
|
||||||
fn tp(&self) -> BodyType {
|
fn length(&self) -> BodyLength {
|
||||||
BodyType::Sized(self.len())
|
BodyLength::Sized(self.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
||||||
@ -285,8 +287,8 @@ impl MessageBody for Bytes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MessageBody for &'static str {
|
impl MessageBody for &'static str {
|
||||||
fn tp(&self) -> BodyType {
|
fn length(&self) -> BodyLength {
|
||||||
BodyType::Sized(self.len())
|
BodyLength::Sized(self.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
||||||
@ -301,8 +303,8 @@ impl MessageBody for &'static str {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MessageBody for &'static [u8] {
|
impl MessageBody for &'static [u8] {
|
||||||
fn tp(&self) -> BodyType {
|
fn length(&self) -> BodyLength {
|
||||||
BodyType::Sized(self.len())
|
BodyLength::Sized(self.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
||||||
@ -317,8 +319,8 @@ impl MessageBody for &'static [u8] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MessageBody for Vec<u8> {
|
impl MessageBody for Vec<u8> {
|
||||||
fn tp(&self) -> BodyType {
|
fn length(&self) -> BodyLength {
|
||||||
BodyType::Sized(self.len())
|
BodyLength::Sized(self.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
||||||
@ -334,8 +336,8 @@ impl MessageBody for Vec<u8> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MessageBody for String {
|
impl MessageBody for String {
|
||||||
fn tp(&self) -> BodyType {
|
fn length(&self) -> BodyLength {
|
||||||
BodyType::Sized(self.len())
|
BodyLength::Sized(self.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
||||||
@ -367,8 +369,8 @@ impl<S> MessageBody for MessageBodyStream<S>
|
|||||||
where
|
where
|
||||||
S: Stream<Item = Bytes, Error = Error>,
|
S: Stream<Item = Bytes, Error = Error>,
|
||||||
{
|
{
|
||||||
fn tp(&self) -> BodyType {
|
fn length(&self) -> BodyLength {
|
||||||
BodyType::Unsized
|
BodyLength::Unsized
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
||||||
|
@ -10,7 +10,7 @@ use tokio_io::{AsyncRead, AsyncWrite};
|
|||||||
use super::error::{ConnectorError, SendRequestError};
|
use super::error::{ConnectorError, SendRequestError};
|
||||||
use super::response::ClientResponse;
|
use super::response::ClientResponse;
|
||||||
use super::{Connect, Connection};
|
use super::{Connect, Connection};
|
||||||
use body::{BodyType, MessageBody, PayloadStream};
|
use body::{BodyLength, MessageBody, PayloadStream};
|
||||||
use error::PayloadError;
|
use error::PayloadError;
|
||||||
use h1;
|
use h1;
|
||||||
use message::RequestHead;
|
use message::RequestHead;
|
||||||
@ -25,7 +25,7 @@ where
|
|||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
I: Connection,
|
I: Connection,
|
||||||
{
|
{
|
||||||
let tp = body.tp();
|
let len = body.length();
|
||||||
|
|
||||||
connector
|
connector
|
||||||
// connect to the host
|
// connect to the host
|
||||||
@ -33,10 +33,10 @@ where
|
|||||||
.from_err()
|
.from_err()
|
||||||
// create Framed and send reqest
|
// create Framed and send reqest
|
||||||
.map(|io| Framed::new(io, h1::ClientCodec::default()))
|
.map(|io| Framed::new(io, h1::ClientCodec::default()))
|
||||||
.and_then(|framed| framed.send((head, tp).into()).from_err())
|
.and_then(|framed| framed.send((head, len).into()).from_err())
|
||||||
// send request body
|
// send request body
|
||||||
.and_then(move |framed| match body.tp() {
|
.and_then(move |framed| match body.length() {
|
||||||
BodyType::None | BodyType::Zero => Either::A(ok(framed)),
|
BodyLength::None | BodyLength::Zero => Either::A(ok(framed)),
|
||||||
_ => Either::B(SendBody::new(body, framed)),
|
_ => Either::B(SendBody::new(body, framed)),
|
||||||
})
|
})
|
||||||
// read response and init read body
|
// read response and init read body
|
||||||
@ -64,7 +64,7 @@ where
|
|||||||
struct SendBody<I, B> {
|
struct SendBody<I, B> {
|
||||||
body: Option<B>,
|
body: Option<B>,
|
||||||
framed: Option<Framed<I, h1::ClientCodec>>,
|
framed: Option<Framed<I, h1::ClientCodec>>,
|
||||||
write_buf: VecDeque<h1::Message<(RequestHead, BodyType)>>,
|
write_buf: VecDeque<h1::Message<(RequestHead, BodyLength)>>,
|
||||||
flushed: bool,
|
flushed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,9 +5,9 @@ use bytes::{BufMut, Bytes, BytesMut};
|
|||||||
use tokio_codec::{Decoder, Encoder};
|
use tokio_codec::{Decoder, Encoder};
|
||||||
|
|
||||||
use super::decoder::{MessageDecoder, PayloadDecoder, PayloadItem, PayloadType};
|
use super::decoder::{MessageDecoder, PayloadDecoder, PayloadItem, PayloadType};
|
||||||
use super::encoder::{RequestEncoder, ResponseLength};
|
use super::encoder::RequestEncoder;
|
||||||
use super::{Message, MessageType};
|
use super::{Message, MessageType};
|
||||||
use body::{Binary, Body, BodyType};
|
use body::{Binary, Body, BodyLength};
|
||||||
use client::ClientResponse;
|
use client::ClientResponse;
|
||||||
use config::ServiceConfig;
|
use config::ServiceConfig;
|
||||||
use error::{ParseError, PayloadError};
|
use error::{ParseError, PayloadError};
|
||||||
@ -104,7 +104,7 @@ impl ClientCodec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// prepare transfer encoding
|
/// prepare transfer encoding
|
||||||
pub fn prepare_te(&mut self, head: &mut RequestHead, btype: BodyType) {
|
pub fn prepare_te(&mut self, head: &mut RequestHead, length: BodyLength) {
|
||||||
self.inner.te.update(
|
self.inner.te.update(
|
||||||
head,
|
head,
|
||||||
self.inner.flags.contains(Flags::HEAD),
|
self.inner.flags.contains(Flags::HEAD),
|
||||||
@ -138,7 +138,7 @@ impl ClientCodecInner {
|
|||||||
fn encode_response(
|
fn encode_response(
|
||||||
&mut self,
|
&mut self,
|
||||||
msg: RequestHead,
|
msg: RequestHead,
|
||||||
btype: BodyType,
|
length: BodyLength,
|
||||||
buffer: &mut BytesMut,
|
buffer: &mut BytesMut,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
// render message
|
// render message
|
||||||
@ -157,20 +157,21 @@ impl ClientCodecInner {
|
|||||||
|
|
||||||
// content length
|
// content length
|
||||||
let mut len_is_set = true;
|
let mut len_is_set = true;
|
||||||
match btype {
|
match length {
|
||||||
BodyType::Sized(len) => {
|
BodyLength::Sized(len) => helpers::write_content_length(len, buffer),
|
||||||
|
BodyLength::Sized64(len) => {
|
||||||
buffer.extend_from_slice(b"\r\ncontent-length: ");
|
buffer.extend_from_slice(b"\r\ncontent-length: ");
|
||||||
write!(buffer.writer(), "{}", len)?;
|
write!(buffer.writer(), "{}", len)?;
|
||||||
buffer.extend_from_slice(b"\r\n");
|
buffer.extend_from_slice(b"\r\n");
|
||||||
}
|
}
|
||||||
BodyType::Unsized => {
|
BodyLength::Unsized => {
|
||||||
buffer.extend_from_slice(b"\r\ntransfer-encoding: chunked\r\n")
|
buffer.extend_from_slice(b"\r\ntransfer-encoding: chunked\r\n")
|
||||||
}
|
}
|
||||||
BodyType::Zero => {
|
BodyLength::Zero => {
|
||||||
len_is_set = false;
|
len_is_set = false;
|
||||||
buffer.extend_from_slice(b"\r\n")
|
buffer.extend_from_slice(b"\r\n")
|
||||||
}
|
}
|
||||||
BodyType::None => buffer.extend_from_slice(b"\r\n"),
|
BodyLength::None => buffer.extend_from_slice(b"\r\n"),
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut has_date = false;
|
let mut has_date = false;
|
||||||
@ -178,9 +179,9 @@ impl ClientCodecInner {
|
|||||||
for (key, value) in &msg.headers {
|
for (key, value) in &msg.headers {
|
||||||
match *key {
|
match *key {
|
||||||
TRANSFER_ENCODING => continue,
|
TRANSFER_ENCODING => continue,
|
||||||
CONTENT_LENGTH => match btype {
|
CONTENT_LENGTH => match length {
|
||||||
BodyType::None => (),
|
BodyLength::None => (),
|
||||||
BodyType::Zero => len_is_set = true,
|
BodyLength::Zero => len_is_set = true,
|
||||||
_ => continue,
|
_ => continue,
|
||||||
},
|
},
|
||||||
DATE => has_date = true,
|
DATE => has_date = true,
|
||||||
@ -263,7 +264,7 @@ impl Decoder for ClientPayloadCodec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Encoder for ClientCodec {
|
impl Encoder for ClientCodec {
|
||||||
type Item = Message<(RequestHead, BodyType)>;
|
type Item = Message<(RequestHead, BodyLength)>;
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
fn encode(
|
fn encode(
|
||||||
|
@ -6,9 +6,9 @@ use bytes::{BufMut, Bytes, BytesMut};
|
|||||||
use tokio_codec::{Decoder, Encoder};
|
use tokio_codec::{Decoder, Encoder};
|
||||||
|
|
||||||
use super::decoder::{MessageDecoder, PayloadDecoder, PayloadItem, PayloadType};
|
use super::decoder::{MessageDecoder, PayloadDecoder, PayloadItem, PayloadType};
|
||||||
use super::encoder::{ResponseEncoder, ResponseLength};
|
use super::encoder::ResponseEncoder;
|
||||||
use super::{Message, MessageType};
|
use super::{Message, MessageType};
|
||||||
use body::{Binary, Body};
|
use body::{Binary, Body, BodyLength};
|
||||||
use config::ServiceConfig;
|
use config::ServiceConfig;
|
||||||
use error::ParseError;
|
use error::ParseError;
|
||||||
use helpers;
|
use helpers;
|
||||||
@ -155,22 +155,20 @@ impl Codec {
|
|||||||
// content length
|
// content length
|
||||||
let mut len_is_set = true;
|
let mut len_is_set = true;
|
||||||
match self.te.length {
|
match self.te.length {
|
||||||
ResponseLength::Chunked => {
|
BodyLength::Unsized => {
|
||||||
buffer.extend_from_slice(b"\r\ntransfer-encoding: chunked\r\n")
|
buffer.extend_from_slice(b"\r\ntransfer-encoding: chunked\r\n")
|
||||||
}
|
}
|
||||||
ResponseLength::Zero => {
|
BodyLength::Zero => {
|
||||||
len_is_set = false;
|
len_is_set = false;
|
||||||
buffer.extend_from_slice(b"\r\n")
|
buffer.extend_from_slice(b"\r\n")
|
||||||
}
|
}
|
||||||
ResponseLength::Length(len) => {
|
BodyLength::Sized(len) => helpers::write_content_length(len, buffer),
|
||||||
helpers::write_content_length(len, buffer)
|
BodyLength::Sized64(len) => {
|
||||||
}
|
|
||||||
ResponseLength::Length64(len) => {
|
|
||||||
buffer.extend_from_slice(b"\r\ncontent-length: ");
|
buffer.extend_from_slice(b"\r\ncontent-length: ");
|
||||||
write!(buffer.writer(), "{}", len)?;
|
write!(buffer.writer(), "{}", len)?;
|
||||||
buffer.extend_from_slice(b"\r\n");
|
buffer.extend_from_slice(b"\r\n");
|
||||||
}
|
}
|
||||||
ResponseLength::None => buffer.extend_from_slice(b"\r\n"),
|
BodyLength::None => buffer.extend_from_slice(b"\r\n"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// write headers
|
// write headers
|
||||||
@ -182,8 +180,8 @@ impl Codec {
|
|||||||
match *key {
|
match *key {
|
||||||
TRANSFER_ENCODING => continue,
|
TRANSFER_ENCODING => continue,
|
||||||
CONTENT_LENGTH => match self.te.length {
|
CONTENT_LENGTH => match self.te.length {
|
||||||
ResponseLength::None => (),
|
BodyLength::None => (),
|
||||||
ResponseLength::Zero => {
|
BodyLength::Zero => {
|
||||||
len_is_set = true;
|
len_is_set = true;
|
||||||
}
|
}
|
||||||
_ => continue,
|
_ => continue,
|
||||||
|
@ -8,28 +8,17 @@ use bytes::{Bytes, BytesMut};
|
|||||||
use http::header::{HeaderValue, ACCEPT_ENCODING, CONTENT_LENGTH};
|
use http::header::{HeaderValue, ACCEPT_ENCODING, CONTENT_LENGTH};
|
||||||
use http::{StatusCode, Version};
|
use http::{StatusCode, Version};
|
||||||
|
|
||||||
use body::{Binary, Body};
|
use body::{Binary, Body, BodyLength};
|
||||||
use header::ContentEncoding;
|
use header::ContentEncoding;
|
||||||
use http::Method;
|
use http::Method;
|
||||||
use message::RequestHead;
|
use message::RequestHead;
|
||||||
use request::Request;
|
use request::Request;
|
||||||
use response::Response;
|
use response::Response;
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub(crate) enum ResponseLength {
|
|
||||||
Chunked,
|
|
||||||
/// Check if headers contains length or write 0
|
|
||||||
Zero,
|
|
||||||
Length(usize),
|
|
||||||
Length64(u64),
|
|
||||||
/// Do no set content-length
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct ResponseEncoder {
|
pub(crate) struct ResponseEncoder {
|
||||||
head: bool,
|
head: bool,
|
||||||
pub length: ResponseLength,
|
pub length: BodyLength,
|
||||||
pub te: TransferEncoding,
|
pub te: TransferEncoding,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +26,7 @@ impl Default for ResponseEncoder {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
ResponseEncoder {
|
ResponseEncoder {
|
||||||
head: false,
|
head: false,
|
||||||
length: ResponseLength::None,
|
length: BodyLength::None,
|
||||||
te: TransferEncoding::empty(),
|
te: TransferEncoding::empty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,18 +69,18 @@ impl ResponseEncoder {
|
|||||||
StatusCode::NO_CONTENT
|
StatusCode::NO_CONTENT
|
||||||
| StatusCode::CONTINUE
|
| StatusCode::CONTINUE
|
||||||
| StatusCode::SWITCHING_PROTOCOLS
|
| StatusCode::SWITCHING_PROTOCOLS
|
||||||
| StatusCode::PROCESSING => ResponseLength::None,
|
| StatusCode::PROCESSING => BodyLength::None,
|
||||||
_ => ResponseLength::Zero,
|
_ => BodyLength::Zero,
|
||||||
};
|
};
|
||||||
TransferEncoding::empty()
|
TransferEncoding::empty()
|
||||||
}
|
}
|
||||||
Body::Binary(_) => {
|
Body::Binary(_) => {
|
||||||
self.length = ResponseLength::Length(len);
|
self.length = BodyLength::Sized(len);
|
||||||
TransferEncoding::length(len as u64)
|
TransferEncoding::length(len as u64)
|
||||||
}
|
}
|
||||||
Body::Streaming(_) => {
|
Body::Streaming(_) => {
|
||||||
if resp.upgrade() {
|
if resp.upgrade() {
|
||||||
self.length = ResponseLength::None;
|
self.length = BodyLength::None;
|
||||||
TransferEncoding::eof()
|
TransferEncoding::eof()
|
||||||
} else {
|
} else {
|
||||||
self.streaming_encoding(version, resp)
|
self.streaming_encoding(version, resp)
|
||||||
@ -115,10 +104,10 @@ impl ResponseEncoder {
|
|||||||
Some(true) => {
|
Some(true) => {
|
||||||
// Enable transfer encoding
|
// Enable transfer encoding
|
||||||
if version == Version::HTTP_2 {
|
if version == Version::HTTP_2 {
|
||||||
self.length = ResponseLength::None;
|
self.length = BodyLength::None;
|
||||||
TransferEncoding::eof()
|
TransferEncoding::eof()
|
||||||
} else {
|
} else {
|
||||||
self.length = ResponseLength::Chunked;
|
self.length = BodyLength::Unsized;
|
||||||
TransferEncoding::chunked()
|
TransferEncoding::chunked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,7 +134,7 @@ impl ResponseEncoder {
|
|||||||
|
|
||||||
if !chunked {
|
if !chunked {
|
||||||
if let Some(len) = len {
|
if let Some(len) = len {
|
||||||
self.length = ResponseLength::Length64(len);
|
self.length = BodyLength::Sized64(len);
|
||||||
TransferEncoding::length(len)
|
TransferEncoding::length(len)
|
||||||
} else {
|
} else {
|
||||||
TransferEncoding::eof()
|
TransferEncoding::eof()
|
||||||
@ -154,11 +143,11 @@ impl ResponseEncoder {
|
|||||||
// Enable transfer encoding
|
// Enable transfer encoding
|
||||||
match version {
|
match version {
|
||||||
Version::HTTP_11 => {
|
Version::HTTP_11 => {
|
||||||
self.length = ResponseLength::Chunked;
|
self.length = BodyLength::Unsized;
|
||||||
TransferEncoding::chunked()
|
TransferEncoding::chunked()
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.length = ResponseLength::None;
|
self.length = BodyLength::None;
|
||||||
TransferEncoding::eof()
|
TransferEncoding::eof()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,7 +160,7 @@ impl ResponseEncoder {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct RequestEncoder {
|
pub(crate) struct RequestEncoder {
|
||||||
head: bool,
|
head: bool,
|
||||||
pub length: ResponseLength,
|
pub length: BodyLength,
|
||||||
pub te: TransferEncoding,
|
pub te: TransferEncoding,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +168,7 @@ impl Default for RequestEncoder {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
RequestEncoder {
|
RequestEncoder {
|
||||||
head: false,
|
head: false,
|
||||||
length: ResponseLength::None,
|
length: BodyLength::None,
|
||||||
te: TransferEncoding::empty(),
|
te: TransferEncoding::empty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ use rand;
|
|||||||
use sha1::Sha1;
|
use sha1::Sha1;
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
|
|
||||||
use body::BodyType;
|
use body::BodyLength;
|
||||||
use client::ClientResponse;
|
use client::ClientResponse;
|
||||||
use h1;
|
use h1;
|
||||||
use ws::Codec;
|
use ws::Codec;
|
||||||
@ -141,7 +141,7 @@ where
|
|||||||
// h1 protocol
|
// h1 protocol
|
||||||
let framed = Framed::new(io, h1::ClientCodec::default());
|
let framed = Framed::new(io, h1::ClientCodec::default());
|
||||||
framed
|
framed
|
||||||
.send((request.into_parts().0, BodyType::None).into())
|
.send((request.into_parts().0, BodyLength::None).into())
|
||||||
.map_err(ClientError::from)
|
.map_err(ClientError::from)
|
||||||
.and_then(|framed| {
|
.and_then(|framed| {
|
||||||
framed
|
framed
|
||||||
|
Loading…
Reference in New Issue
Block a user