Add RequestBuilder::version() method to set HTTP version (#1243)
Closes #1240
This commit is contained in:
@@ -1106,7 +1106,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn execute_request(&self, req: Request) -> Pending {
|
pub(super) fn execute_request(&self, req: Request) -> Pending {
|
||||||
let (method, url, mut headers, body, timeout) = req.pieces();
|
let (method, url, mut headers, body, timeout, version) = req.pieces();
|
||||||
if url.scheme() != "http" && url.scheme() != "https" {
|
if url.scheme() != "http" && url.scheme() != "https" {
|
||||||
return Pending::new_err(error::url_bad_scheme(url));
|
return Pending::new_err(error::url_bad_scheme(url));
|
||||||
}
|
}
|
||||||
@@ -1157,6 +1157,7 @@ impl Client {
|
|||||||
let mut req = hyper::Request::builder()
|
let mut req = hyper::Request::builder()
|
||||||
.method(method.clone())
|
.method(method.clone())
|
||||||
.uri(uri)
|
.uri(uri)
|
||||||
|
.version(version)
|
||||||
.body(body.into_stream())
|
.body(body.into_stream())
|
||||||
.expect("valid request parts");
|
.expect("valid request parts");
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use super::response::Response;
|
|||||||
use crate::header::CONTENT_LENGTH;
|
use crate::header::CONTENT_LENGTH;
|
||||||
use crate::header::{HeaderMap, HeaderName, HeaderValue, CONTENT_TYPE};
|
use crate::header::{HeaderMap, HeaderName, HeaderValue, CONTENT_TYPE};
|
||||||
use crate::{Method, Url};
|
use crate::{Method, Url};
|
||||||
use http::{request::Parts, Request as HttpRequest};
|
use http::{request::Parts, Request as HttpRequest, Version};
|
||||||
|
|
||||||
/// A request which can be executed with `Client::execute()`.
|
/// A request which can be executed with `Client::execute()`.
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
@@ -27,6 +27,7 @@ pub struct Request {
|
|||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
body: Option<Body>,
|
body: Option<Body>,
|
||||||
timeout: Option<Duration>,
|
timeout: Option<Duration>,
|
||||||
|
version: Version,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A builder to construct the properties of a `Request`.
|
/// A builder to construct the properties of a `Request`.
|
||||||
@@ -48,6 +49,7 @@ impl Request {
|
|||||||
headers: HeaderMap::new(),
|
headers: HeaderMap::new(),
|
||||||
body: None,
|
body: None,
|
||||||
timeout: None,
|
timeout: None,
|
||||||
|
version: Version::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,6 +113,18 @@ impl Request {
|
|||||||
&mut self.timeout
|
&mut self.timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the http version.
|
||||||
|
#[inline]
|
||||||
|
pub fn version(&self) -> Version {
|
||||||
|
self.version
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a mutable reference to the http version.
|
||||||
|
#[inline]
|
||||||
|
pub fn version_mut(&mut self) -> &mut Version {
|
||||||
|
&mut self.version
|
||||||
|
}
|
||||||
|
|
||||||
/// Attempt to clone the request.
|
/// Attempt to clone the request.
|
||||||
///
|
///
|
||||||
/// `None` is returned if the request can not be cloned, i.e. if the body is a stream.
|
/// `None` is returned if the request can not be cloned, i.e. if the body is a stream.
|
||||||
@@ -122,12 +136,29 @@ impl Request {
|
|||||||
let mut req = Request::new(self.method().clone(), self.url().clone());
|
let mut req = Request::new(self.method().clone(), self.url().clone());
|
||||||
*req.timeout_mut() = self.timeout().cloned();
|
*req.timeout_mut() = self.timeout().cloned();
|
||||||
*req.headers_mut() = self.headers().clone();
|
*req.headers_mut() = self.headers().clone();
|
||||||
|
*req.version_mut() = self.version().clone();
|
||||||
req.body = body;
|
req.body = body;
|
||||||
Some(req)
|
Some(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn pieces(self) -> (Method, Url, HeaderMap, Option<Body>, Option<Duration>) {
|
pub(super) fn pieces(
|
||||||
(self.method, self.url, self.headers, self.body, self.timeout)
|
self,
|
||||||
|
) -> (
|
||||||
|
Method,
|
||||||
|
Url,
|
||||||
|
HeaderMap,
|
||||||
|
Option<Body>,
|
||||||
|
Option<Duration>,
|
||||||
|
Version,
|
||||||
|
) {
|
||||||
|
(
|
||||||
|
self.method,
|
||||||
|
self.url,
|
||||||
|
self.headers,
|
||||||
|
self.body,
|
||||||
|
self.timeout,
|
||||||
|
self.version,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,6 +353,14 @@ impl RequestBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set HTTP version
|
||||||
|
pub fn version(mut self, version: Version) -> RequestBuilder {
|
||||||
|
if let Ok(ref mut req) = self.request {
|
||||||
|
req.version = version;
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Send a form body.
|
/// Send a form body.
|
||||||
pub fn form<T: Serialize + ?Sized>(mut self, form: &T) -> RequestBuilder {
|
pub fn form<T: Serialize + ?Sized>(mut self, form: &T) -> RequestBuilder {
|
||||||
let mut error = None;
|
let mut error = None;
|
||||||
@@ -516,6 +555,7 @@ where
|
|||||||
method,
|
method,
|
||||||
uri,
|
uri,
|
||||||
headers,
|
headers,
|
||||||
|
version,
|
||||||
..
|
..
|
||||||
} = parts;
|
} = parts;
|
||||||
let url = Url::parse(&uri.to_string()).map_err(crate::error::builder)?;
|
let url = Url::parse(&uri.to_string()).map_err(crate::error::builder)?;
|
||||||
@@ -525,13 +565,14 @@ where
|
|||||||
headers,
|
headers,
|
||||||
body: Some(body.into()),
|
body: Some(body.into()),
|
||||||
timeout: None,
|
timeout: None,
|
||||||
|
version: version,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Client, HttpRequest, Request};
|
use super::{Client, HttpRequest, Request, Version};
|
||||||
use crate::Method;
|
use crate::Method;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
@@ -753,6 +794,26 @@ mod tests {
|
|||||||
assert_eq!(req.url().as_str(), "http://localhost/");
|
assert_eq!(req.url().as_str(), "http://localhost/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn set_http_request_version() {
|
||||||
|
let http_request = HttpRequest::builder()
|
||||||
|
.method("GET")
|
||||||
|
.uri("http://localhost/")
|
||||||
|
.header("User-Agent", "my-awesome-agent/1.0")
|
||||||
|
.version(Version::HTTP_11)
|
||||||
|
.body("test test test")
|
||||||
|
.unwrap();
|
||||||
|
let req: Request = Request::try_from(http_request).unwrap();
|
||||||
|
assert_eq!(req.body().is_none(), false);
|
||||||
|
let test_data = b"test test test";
|
||||||
|
assert_eq!(req.body().unwrap().as_bytes(), Some(&test_data[..]));
|
||||||
|
let headers = req.headers();
|
||||||
|
assert_eq!(headers.get("User-Agent").unwrap(), "my-awesome-agent/1.0");
|
||||||
|
assert_eq!(req.method(), Method::GET);
|
||||||
|
assert_eq!(req.url().as_str(), "http://localhost/");
|
||||||
|
assert_eq!(req.version(), Version::HTTP_11);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
use {body, Method};
|
use {body, Method};
|
||||||
use super::Client;
|
use super::Client;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::fmt;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use base64::encode;
|
use base64::encode;
|
||||||
use http::{request::Parts, Request as HttpRequest};
|
use http::{request::Parts, Request as HttpRequest, Version};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
#[cfg(feature = "json")]
|
#[cfg(feature = "json")]
|
||||||
use serde_json;
|
use serde_json;
|
||||||
@@ -78,6 +78,18 @@ impl Request {
|
|||||||
self.inner.headers_mut()
|
self.inner.headers_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the http version.
|
||||||
|
#[inline]
|
||||||
|
pub fn version(&self) -> Version {
|
||||||
|
self.inner.version()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a mutable reference to the http version.
|
||||||
|
#[inline]
|
||||||
|
pub fn version_mut(&mut self) -> &mut Version {
|
||||||
|
self.inner.version_mut()
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the body.
|
/// Get the body.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn body(&self) -> Option<&Body> {
|
pub fn body(&self) -> Option<&Body> {
|
||||||
@@ -118,6 +130,7 @@ impl Request {
|
|||||||
};
|
};
|
||||||
let mut req = Request::new(self.method().clone(), self.url().clone());
|
let mut req = Request::new(self.method().clone(), self.url().clone());
|
||||||
*req.headers_mut() = self.headers().clone();
|
*req.headers_mut() = self.headers().clone();
|
||||||
|
*req.version_mut() = self.version().clone();
|
||||||
req.body = body;
|
req.body = body;
|
||||||
Some(req)
|
Some(req)
|
||||||
}
|
}
|
||||||
@@ -394,6 +407,14 @@ impl RequestBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set HTTP version
|
||||||
|
pub fn version(mut self, version: Version) -> RequestBuilder {
|
||||||
|
if let Ok(ref mut req) = self.request {
|
||||||
|
*req.version_mut() = version;
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Send a form body.
|
/// Send a form body.
|
||||||
///
|
///
|
||||||
/// Sets the body to the url encoded serialization of the passed value,
|
/// Sets the body to the url encoded serialization of the passed value,
|
||||||
@@ -640,7 +661,7 @@ fn fmt_request_fields<'a, 'b>(
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::super::{body, Client};
|
use super::super::{body, Client};
|
||||||
use super::{HttpRequest, Request};
|
use super::{HttpRequest, Request, Version};
|
||||||
use crate::header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE, HOST};
|
use crate::header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE, HOST};
|
||||||
use crate::Method;
|
use crate::Method;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@@ -988,6 +1009,26 @@ mod tests {
|
|||||||
assert_eq!(req.url().as_str(), "http://localhost/");
|
assert_eq!(req.url().as_str(), "http://localhost/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn set_http_request_version() {
|
||||||
|
let http_request = HttpRequest::builder()
|
||||||
|
.method("GET")
|
||||||
|
.uri("http://localhost/")
|
||||||
|
.header("User-Agent", "my-awesome-agent/1.0")
|
||||||
|
.version(Version::HTTP_11)
|
||||||
|
.body("test test test")
|
||||||
|
.unwrap();
|
||||||
|
let req: Request = Request::try_from(http_request).unwrap();
|
||||||
|
assert_eq!(req.body().is_none(), false);
|
||||||
|
let test_data = b"test test test";
|
||||||
|
assert_eq!(req.body().unwrap().as_bytes(), Some(&test_data[..]));
|
||||||
|
let headers = req.headers();
|
||||||
|
assert_eq!(headers.get("User-Agent").unwrap(), "my-awesome-agent/1.0");
|
||||||
|
assert_eq!(req.method(), Method::GET);
|
||||||
|
assert_eq!(req.url().as_str(), "http://localhost/");
|
||||||
|
assert_eq!(req.version(), Version::HTTP_11);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basic_auth_sensitive_header() {
|
fn test_basic_auth_sensitive_header() {
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
|
|||||||
Reference in New Issue
Block a user