use iota for more content-length insertions

This commit is contained in:
Rob Ede 2021-03-07 10:20:39 +00:00
parent 78384c3ff5
commit a6c65a1743
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
5 changed files with 37 additions and 25 deletions

View File

@ -1,4 +1,3 @@
use std::convert::TryFrom;
use std::future::Future; use std::future::Future;
use std::time; use std::time;
@ -61,10 +60,14 @@ where
BodySize::Empty => req BodySize::Empty => req
.headers_mut() .headers_mut()
.insert(CONTENT_LENGTH, HeaderValue::from_static("0")), .insert(CONTENT_LENGTH, HeaderValue::from_static("0")),
BodySize::Sized(len) => req.headers_mut().insert( BodySize::Sized(len) => {
CONTENT_LENGTH, let mut buf = itoa::Buffer::new();
HeaderValue::try_from(format!("{}", len)).unwrap(),
), req.headers_mut().insert(
CONTENT_LENGTH,
HeaderValue::from_str(buf.format(len)).unwrap(),
)
}
}; };
// Extracting extra headers from RequestHeadType. HeaderMap::new() does not allocate. // Extracting extra headers from RequestHeadType. HeaderMap::new() does not allocate.
@ -87,7 +90,10 @@ where
// copy headers // copy headers
for (key, value) in headers { for (key, value) in headers {
match *key { match *key {
CONNECTION | TRANSFER_ENCODING => continue, // http2 specific // TODO: consider skipping other headers according to:
// https://tools.ietf.org/html/rfc7540#section-8.1.2.2
// omit HTTP/1.x only headers
CONNECTION | TRANSFER_ENCODING => continue,
CONTENT_LENGTH if skip_len => continue, CONTENT_LENGTH if skip_len => continue,
// DATE => has_date = true, // DATE => has_date = true,
_ => {} _ => {}

View File

@ -633,9 +633,9 @@ mod tests {
let mut res: Response<()> = let mut res: Response<()> =
Response::new(StatusCode::SWITCHING_PROTOCOLS).into_body::<()>(); Response::new(StatusCode::SWITCHING_PROTOCOLS).into_body::<()>();
res.headers_mut() res.headers_mut()
.insert(DATE, HeaderValue::from_static(&"")); .insert(DATE, HeaderValue::from_static(""));
res.headers_mut() res.headers_mut()
.insert(CONTENT_LENGTH, HeaderValue::from_static(&"0")); .insert(CONTENT_LENGTH, HeaderValue::from_static("0"));
let _ = res.encode_headers( let _ = res.encode_headers(
&mut bytes, &mut bytes,

View File

@ -125,7 +125,7 @@ where
let pl = Payload::<crate::payload::PayloadStream>::H2(pl); let pl = Payload::<crate::payload::PayloadStream>::H2(pl);
let mut req = Request::with_payload(pl); let mut req = Request::with_payload(pl);
let head = &mut req.head_mut(); let head = req.head_mut();
head.uri = parts.uri; head.uri = parts.uri;
head.method = parts.method; head.method = parts.method;
head.version = parts.version; head.version = parts.version;
@ -203,16 +203,22 @@ where
BodySize::Empty => res BodySize::Empty => res
.headers_mut() .headers_mut()
.insert(CONTENT_LENGTH, HeaderValue::from_static("0")), .insert(CONTENT_LENGTH, HeaderValue::from_static("0")),
BodySize::Sized(len) => res.headers_mut().insert( BodySize::Sized(len) => {
CONTENT_LENGTH, let mut buf = itoa::Buffer::new();
HeaderValue::try_from(format!("{}", len)).unwrap(),
), res.headers_mut().insert(
CONTENT_LENGTH,
HeaderValue::from_str(buf.format(len)).unwrap(),
)
}
}; };
// copy headers // copy headers
for (key, value) in head.headers.iter() { for (key, value) in head.headers.iter() {
match *key { match *key {
// omit HTTP/1 only headers // TODO: consider skipping other headers according to:
// https://tools.ietf.org/html/rfc7540#section-8.1.2.2
// omit HTTP/1.x only headers
CONNECTION | TRANSFER_ENCODING => continue, CONNECTION | TRANSFER_ENCODING => continue,
CONTENT_LENGTH if skip_len => continue, CONTENT_LENGTH if skip_len => continue,
DATE => has_date = true, DATE => has_date = true,

View File

@ -498,7 +498,8 @@ impl ResponseBuilder {
/// Disable chunked transfer encoding for HTTP/1.1 streaming responses. /// Disable chunked transfer encoding for HTTP/1.1 streaming responses.
#[inline] #[inline]
pub fn no_chunking(&mut self, len: u64) -> &mut Self { pub fn no_chunking(&mut self, len: u64) -> &mut Self {
self.insert_header((header::CONTENT_LENGTH, len)); let mut buf = itoa::Buffer::new();
self.insert_header((header::CONTENT_LENGTH, buf.format(len)));
if let Some(parts) = parts(&mut self.head, &self.err) { if let Some(parts) = parts(&mut self.head, &self.err) {
parts.no_chunking(true); parts.no_chunking(true);

View File

@ -248,29 +248,28 @@ impl ClientRequest {
/// Set content length /// Set content length
#[inline] #[inline]
pub fn content_length(self, len: u64) -> Self { pub fn content_length(self, len: u64) -> Self {
self.append_header((header::CONTENT_LENGTH, len)) let mut buf = itoa::Buffer::new();
self.insert_header((header::CONTENT_LENGTH, buf.format(len)))
} }
/// Set HTTP basic authorization header /// Set HTTP basic authorization header
pub fn basic_auth<U>(self, username: U, password: Option<&str>) -> Self pub fn basic_auth(
where self,
U: fmt::Display, username: impl fmt::Display,
{ password: Option<impl fmt::Display>,
) -> Self {
let auth = match password { let auth = match password {
Some(password) => format!("{}:{}", username, password), Some(password) => format!("{}:{}", username, password),
None => format!("{}:", username), None => format!("{}:", username),
}; };
self.append_header(( self.insert_header((
header::AUTHORIZATION, header::AUTHORIZATION,
format!("Basic {}", base64::encode(&auth)), format!("Basic {}", base64::encode(&auth)),
)) ))
} }
/// Set HTTP bearer authentication header /// Set HTTP bearer authentication header
pub fn bearer_auth<T>(self, token: T) -> Self pub fn insert_auth(self, token: impl fmt::Display) -> Self {
where
T: fmt::Display,
{
self.append_header((header::AUTHORIZATION, format!("Bearer {}", token))) self.append_header((header::AUTHORIZATION, format!("Bearer {}", token)))
} }