monoio_http_client/
request.rs1use bytes::Bytes;
2use http::{header::HeaderName, request::Builder, HeaderValue, Method, Uri};
3use monoio_http::common::body::{FixedBody, HttpBody};
4
5use crate::{
6 client::{
7 connector::PooledConnector, key::Key, pool::PooledConnection,
8 unified::UnifiedTransportConnector, Client,
9 },
10 response::ClientResponse,
11 unified::UnifiedTransportConnection,
12 Connector,
13};
14
15pub struct ClientRequest<C = UnifiedTransportConnector> {
16 client: Client<C>,
17 builder: Builder,
18}
19
20impl<C> ClientRequest<C> {
21 pub fn new(client: Client<C>) -> Self {
22 Self {
23 client,
24 builder: Builder::new(),
25 }
26 }
27
28 pub fn method<T>(mut self, method: T) -> Self
29 where
30 Method: TryFrom<T>,
31 <Method as TryFrom<T>>::Error: Into<http::Error>,
32 {
33 self.builder = self.builder.method(method);
34 self
35 }
36
37 pub fn uri<T>(mut self, uri: T) -> Self
38 where
39 Uri: TryFrom<T>,
40 <Uri as TryFrom<T>>::Error: Into<http::Error>,
41 {
42 self.builder = self.builder.uri(uri);
43 self
44 }
45
46 pub fn header<K, V>(mut self, key: K, value: V) -> Self
47 where
48 HeaderName: TryFrom<K>,
49 <HeaderName as TryFrom<K>>::Error: Into<http::Error>,
50 HeaderValue: TryFrom<V>,
51 <HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
52 {
53 self.builder = self.builder.header(key, value);
54 self
55 }
56
57 fn build_request(builder: Builder, body: HttpBody) -> crate::Result<http::Request<HttpBody>> {
58 let mut req = builder.version(http::Version::HTTP_11).body(body)?;
59 if let Some(host) = req.uri().host() {
60 let host = HeaderValue::try_from(host).map_err(http::Error::from)?;
61 let headers = req.headers_mut();
62 if !headers.contains_key(http::header::HOST) {
63 headers.insert(http::header::HOST, host);
64 }
65 }
66 Ok(req)
67 }
68}
69
70impl<C> ClientRequest<C>
71where
72 PooledConnector<C, Key, UnifiedTransportConnection>: Connector<
73 Key,
74 Connection = PooledConnection<Key, UnifiedTransportConnection>,
75 Error = crate::Error,
76 >,
77{
78 pub async fn send(self) -> crate::Result<ClientResponse> {
79 let request = Self::build_request(self.builder, HttpBody::fixed_body(None))?;
80 let resp = self.client.send_request(request).await?;
81 Ok(ClientResponse::new(resp))
82 }
83
84 pub async fn send_body(self, data: Bytes) -> crate::Result<ClientResponse> {
85 let request = Self::build_request(self.builder, HttpBody::fixed_body(Some(data)))?;
86 let resp = self.client.send_request(request).await?;
87 Ok(ClientResponse::new(resp))
88 }
89
90 pub async fn send_json<T: serde::Serialize>(self, data: &T) -> crate::Result<ClientResponse> {
91 let body: Bytes = serde_json::to_vec(data)?.into();
92 let builder = self.builder.header(
93 http::header::CONTENT_TYPE,
94 HeaderValue::from_static("application/json"),
95 );
96 let request = Self::build_request(builder, HttpBody::fixed_body(Some(body)))?;
97 let resp = self.client.send_request(request).await?;
98 Ok(ClientResponse::new(resp))
99 }
100}