1use std::{net, rc::Rc, time::Duration};
2
3use bytes::Bytes;
4use futures_core::Stream;
5use serde::Serialize;
6
7use actix_http::{
8 body::MessageBody,
9 error::HttpError,
10 header::{HeaderMap, TryIntoHeaderPair},
11 Method, RequestHead, Uri,
12};
13
14use crate::{
15 client::ClientConfig,
16 sender::{RequestSender, SendClientRequest},
17 BoxError,
18};
19
20#[derive(Clone)]
24pub struct FrozenClientRequest {
25 pub(crate) head: Rc<RequestHead>,
26 pub(crate) addr: Option<net::SocketAddr>,
27 pub(crate) response_decompress: bool,
28 pub(crate) timeout: Option<Duration>,
29 pub(crate) config: ClientConfig,
30}
31
32impl FrozenClientRequest {
33 pub fn get_uri(&self) -> &Uri {
35 &self.head.uri
36 }
37
38 pub fn get_method(&self) -> &Method {
40 &self.head.method
41 }
42
43 pub fn headers(&self) -> &HeaderMap {
45 &self.head.headers
46 }
47
48 pub fn send_body<B>(&self, body: B) -> SendClientRequest
50 where
51 B: MessageBody + 'static,
52 {
53 RequestSender::Rc(self.head.clone(), None).send_body(
54 self.addr,
55 self.response_decompress,
56 self.timeout,
57 &self.config,
58 body,
59 )
60 }
61
62 pub fn send_json<T: Serialize>(&self, value: &T) -> SendClientRequest {
64 RequestSender::Rc(self.head.clone(), None).send_json(
65 self.addr,
66 self.response_decompress,
67 self.timeout,
68 &self.config,
69 value,
70 )
71 }
72
73 pub fn send_form<T: Serialize>(&self, value: &T) -> SendClientRequest {
75 RequestSender::Rc(self.head.clone(), None).send_form(
76 self.addr,
77 self.response_decompress,
78 self.timeout,
79 &self.config,
80 value,
81 )
82 }
83
84 pub fn send_stream<S, E>(&self, stream: S) -> SendClientRequest
86 where
87 S: Stream<Item = Result<Bytes, E>> + 'static,
88 E: Into<BoxError> + 'static,
89 {
90 RequestSender::Rc(self.head.clone(), None).send_stream(
91 self.addr,
92 self.response_decompress,
93 self.timeout,
94 &self.config,
95 stream,
96 )
97 }
98
99 pub fn send(&self) -> SendClientRequest {
101 RequestSender::Rc(self.head.clone(), None).send(
102 self.addr,
103 self.response_decompress,
104 self.timeout,
105 &self.config,
106 )
107 }
108
109 pub fn extra_headers(&self, extra_headers: HeaderMap) -> FrozenSendBuilder {
111 FrozenSendBuilder::new(self.clone(), extra_headers)
112 }
113
114 pub fn extra_header(&self, header: impl TryIntoHeaderPair) -> FrozenSendBuilder {
116 self.extra_headers(HeaderMap::new()).extra_header(header)
117 }
118}
119
120pub struct FrozenSendBuilder {
122 req: FrozenClientRequest,
123 extra_headers: HeaderMap,
124 err: Option<HttpError>,
125}
126
127impl FrozenSendBuilder {
128 pub(crate) fn new(req: FrozenClientRequest, extra_headers: HeaderMap) -> Self {
129 Self {
130 req,
131 extra_headers,
132 err: None,
133 }
134 }
135
136 pub fn extra_header(mut self, header: impl TryIntoHeaderPair) -> Self {
138 match header.try_into_pair() {
139 Ok((key, value)) => {
140 self.extra_headers.insert(key, value);
141 }
142
143 Err(err) => self.err = Some(err.into()),
144 }
145
146 self
147 }
148
149 pub fn send_body(self, body: impl MessageBody + 'static) -> SendClientRequest {
151 if let Some(e) = self.err {
152 return e.into();
153 }
154
155 RequestSender::Rc(self.req.head, Some(self.extra_headers)).send_body(
156 self.req.addr,
157 self.req.response_decompress,
158 self.req.timeout,
159 &self.req.config,
160 body,
161 )
162 }
163
164 pub fn send_json(self, value: impl Serialize) -> SendClientRequest {
166 if let Some(err) = self.err {
167 return err.into();
168 }
169
170 RequestSender::Rc(self.req.head, Some(self.extra_headers)).send_json(
171 self.req.addr,
172 self.req.response_decompress,
173 self.req.timeout,
174 &self.req.config,
175 value,
176 )
177 }
178
179 pub fn send_form(self, value: impl Serialize) -> SendClientRequest {
181 if let Some(e) = self.err {
182 return e.into();
183 }
184
185 RequestSender::Rc(self.req.head, Some(self.extra_headers)).send_form(
186 self.req.addr,
187 self.req.response_decompress,
188 self.req.timeout,
189 &self.req.config,
190 value,
191 )
192 }
193
194 pub fn send_stream<S, E>(self, stream: S) -> SendClientRequest
196 where
197 S: Stream<Item = Result<Bytes, E>> + 'static,
198 E: Into<BoxError> + 'static,
199 {
200 if let Some(e) = self.err {
201 return e.into();
202 }
203
204 RequestSender::Rc(self.req.head, Some(self.extra_headers)).send_stream(
205 self.req.addr,
206 self.req.response_decompress,
207 self.req.timeout,
208 &self.req.config,
209 stream,
210 )
211 }
212
213 pub fn send(self) -> SendClientRequest {
215 if let Some(e) = self.err {
216 return e.into();
217 }
218
219 RequestSender::Rc(self.req.head, Some(self.extra_headers)).send(
220 self.req.addr,
221 self.req.response_decompress,
222 self.req.timeout,
223 &self.req.config,
224 )
225 }
226}