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