Add BodySize enum
This commit is contained in:
24
src/body.rs
24
src/body.rs
@@ -43,11 +43,21 @@ impl Default for Payload {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The size of the body.
|
||||||
|
///
|
||||||
|
/// *Internal API*
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) enum BodySize {
|
||||||
|
Empty,
|
||||||
|
Unknown,
|
||||||
|
Known(u64),
|
||||||
|
}
|
||||||
|
|
||||||
/// Payloads are turned into this type where we can hold both a size and the reader.
|
/// Payloads are turned into this type where we can hold both a size and the reader.
|
||||||
///
|
///
|
||||||
/// *Internal API*
|
/// *Internal API*
|
||||||
pub(crate) struct SizedReader {
|
pub(crate) struct SizedReader {
|
||||||
pub size: Option<usize>,
|
pub size: BodySize,
|
||||||
pub reader: Box<dyn Read + 'static>,
|
pub reader: Box<dyn Read + 'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +68,7 @@ impl fmt::Debug for SizedReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SizedReader {
|
impl SizedReader {
|
||||||
fn new(size: Option<usize>, reader: Box<dyn Read + 'static>) -> Self {
|
fn new(size: BodySize, reader: Box<dyn Read + 'static>) -> Self {
|
||||||
SizedReader { size, reader }
|
SizedReader { size, reader }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +76,7 @@ impl SizedReader {
|
|||||||
impl Payload {
|
impl Payload {
|
||||||
pub fn into_read(self) -> SizedReader {
|
pub fn into_read(self) -> SizedReader {
|
||||||
match self {
|
match self {
|
||||||
Payload::Empty => SizedReader::new(Some(0), Box::new(empty())),
|
Payload::Empty => SizedReader::new(BodySize::Empty, Box::new(empty())),
|
||||||
Payload::Text(text, _charset) => {
|
Payload::Text(text, _charset) => {
|
||||||
#[cfg(feature = "charset")]
|
#[cfg(feature = "charset")]
|
||||||
let bytes = {
|
let bytes = {
|
||||||
@@ -79,20 +89,20 @@ impl Payload {
|
|||||||
let bytes = text.into_bytes();
|
let bytes = text.into_bytes();
|
||||||
let len = bytes.len();
|
let len = bytes.len();
|
||||||
let cursor = Cursor::new(bytes);
|
let cursor = Cursor::new(bytes);
|
||||||
SizedReader::new(Some(len), Box::new(cursor))
|
SizedReader::new(BodySize::Known(len as u64), Box::new(cursor))
|
||||||
}
|
}
|
||||||
#[cfg(feature = "json")]
|
#[cfg(feature = "json")]
|
||||||
Payload::JSON(v) => {
|
Payload::JSON(v) => {
|
||||||
let bytes = serde_json::to_vec(&v).expect("Bad JSON in payload");
|
let bytes = serde_json::to_vec(&v).expect("Bad JSON in payload");
|
||||||
let len = bytes.len();
|
let len = bytes.len();
|
||||||
let cursor = Cursor::new(bytes);
|
let cursor = Cursor::new(bytes);
|
||||||
SizedReader::new(Some(len), Box::new(cursor))
|
SizedReader::new(BodySize::Known(len as u64), Box::new(cursor))
|
||||||
}
|
}
|
||||||
Payload::Reader(read) => SizedReader::new(None, read),
|
Payload::Reader(read) => SizedReader::new(BodySize::Unknown, read),
|
||||||
Payload::Bytes(bytes) => {
|
Payload::Bytes(bytes) => {
|
||||||
let len = bytes.len();
|
let len = bytes.len();
|
||||||
let cursor = Cursor::new(bytes);
|
let cursor = Cursor::new(bytes);
|
||||||
SizedReader::new(Some(len), Box::new(cursor))
|
SizedReader::new(BodySize::Known(len as u64), Box::new(cursor))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use qstring::QString;
|
|||||||
use url::{form_urlencoded, Url};
|
use url::{form_urlencoded, Url};
|
||||||
|
|
||||||
use crate::agent::{self, Agent, AgentState};
|
use crate::agent::{self, Agent, AgentState};
|
||||||
|
use crate::body::BodySize;
|
||||||
use crate::body::{Payload, SizedReader};
|
use crate::body::{Payload, SizedReader};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::header::{self, Header};
|
use crate::header::{self, Header};
|
||||||
@@ -604,8 +605,14 @@ impl Request {
|
|||||||
// Sized bodies are retryable only if they are zero-length because of
|
// Sized bodies are retryable only if they are zero-length because of
|
||||||
// coincidences of the current implementation - the function responsible
|
// coincidences of the current implementation - the function responsible
|
||||||
// for retries doesn't have a way to replay a Payload.
|
// for retries doesn't have a way to replay a Payload.
|
||||||
let no_body = body.size.is_none() || body.size.unwrap() > 0;
|
let retryable_body = match body.size {
|
||||||
idempotent && no_body
|
BodySize::Unknown => false,
|
||||||
|
BodySize::Known(0) => true,
|
||||||
|
BodySize::Known(_) => false,
|
||||||
|
BodySize::Empty => true,
|
||||||
|
};
|
||||||
|
|
||||||
|
idempotent && retryable_body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
18
src/unit.rs
18
src/unit.rs
@@ -8,7 +8,7 @@ use url::Url;
|
|||||||
use cookie::{Cookie, CookieJar};
|
use cookie::{Cookie, CookieJar};
|
||||||
|
|
||||||
use crate::agent::AgentState;
|
use crate::agent::AgentState;
|
||||||
use crate::body::{self, Payload, SizedReader};
|
use crate::body::{self, BodySize, Payload, SizedReader};
|
||||||
use crate::header;
|
use crate::header;
|
||||||
use crate::resolve::ArcResolver;
|
use crate::resolve::ArcResolver;
|
||||||
use crate::stream::{self, connect_test, Stream};
|
use crate::stream::{self, connect_test, Stream};
|
||||||
@@ -56,15 +56,17 @@ impl Unit {
|
|||||||
// Content-Length,
|
// Content-Length,
|
||||||
// otherwise, use the chunked Transfer-Encoding (only if no other Transfer-Encoding
|
// otherwise, use the chunked Transfer-Encoding (only if no other Transfer-Encoding
|
||||||
// has been set
|
// has been set
|
||||||
if let Some(size) = body.size {
|
match body.size {
|
||||||
if size != 0 {
|
BodySize::Known(size) => {
|
||||||
extra.push(Header::new("Content-Length", &format!("{}", size)));
|
extra.push(Header::new("Content-Length", &format!("{}", size)))
|
||||||
}
|
}
|
||||||
} else {
|
BodySize::Unknown => {
|
||||||
if !is_transfer_encoding_set {
|
if !is_transfer_encoding_set {
|
||||||
extra.push(Header::new("Transfer-Encoding", "chunked"));
|
extra.push(Header::new("Transfer-Encoding", "chunked"));
|
||||||
is_chunked = true;
|
is_chunked = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
BodySize::Empty => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user