Skip to main content

http_request/request/request_builder/
struct.rs

1use super::*;
2
3/// Fluent builder for [`HttpRequest`].
4///
5/// Single-purpose, chainable. Each method returns `&mut Self` for fluent
6/// chaining; call [`RequestBuilder::build`] to obtain the final
7/// [`HttpRequest`].
8///
9/// # Examples
10///
11/// ```ignore
12/// use http_request::{RequestBuilder, Proxy};
13///
14/// // sync GET
15/// let mut req = RequestBuilder::new()
16///     .get("https://example.com/api")
17///     .header("Accept", "application/json")
18///     .timeout(5_000)
19///     .build();
20/// let _resp = req.send();
21///
22/// // async POST with JSON body
23/// let req = RequestBuilder::new()
24///     .post("https://example.com/api")
25///     .body_json(&serde_json::json!({"k": "v"}))
26///     .header("Content-Type", "application/json")
27///     .proxy(Proxy::https("127.0.0.1", 7890).auth("u", "p"))
28///     .build();
29/// let _resp = req.send_async().await;
30/// ```
31#[derive(Clone, Debug, Default)]
32pub struct RequestBuilder {
33    request: HttpRequest,
34}
35
36impl RequestBuilder {
37    /// Create an empty builder (defaults: GET, no headers, default config).
38    pub fn new() -> Self {
39        Self::default()
40    }
41
42    /// Shortcut for `method(Method::Get)` + `url(url)`.
43    pub fn get(&mut self, url: impl Into<String>) -> &mut Self {
44        self.request.set_method(Method::Get);
45        self.request.set_url(url);
46        self
47    }
48
49    /// Shortcut for `method(Method::Post)` + `url(url)`.
50    pub fn post(&mut self, url: impl Into<String>) -> &mut Self {
51        self.request.set_method(Method::Post);
52        self.request.set_url(url);
53        self
54    }
55
56    /// Set HTTP method explicitly (`Method::Get` / `Method::Post` / etc.).
57    pub fn method(&mut self, method: Method) -> &mut Self {
58        self.request.set_method(method);
59        self
60    }
61
62    /// Set URL.
63    pub fn url(&mut self, url: impl Into<String>) -> &mut Self {
64        self.request.set_url(url);
65        self
66    }
67
68    /// Set a single header (last write wins on duplicate keys).
69    pub fn header<K: AsRef<str>, V: AsRef<str>>(&mut self, key: K, value: V) -> &mut Self {
70        self.request.set_header(key, value);
71        self
72    }
73
74    /// Set many headers at once.
75    pub fn headers<K, V>(&mut self, headers: HashMap<K, V>) -> &mut Self
76    where
77        K: AsRef<str>,
78        V: AsRef<str>,
79    {
80        for (k, v) in headers {
81            self.request.set_header(k, v);
82        }
83        self
84    }
85
86    /// Remove a header by key.
87    pub fn remove_header<K: AsRef<str>>(&mut self, key: K) -> &mut Self {
88        self.request.remove_header(key);
89        self
90    }
91
92    /// Clear all headers.
93    pub fn clear_headers(&mut self) -> &mut Self {
94        self.request.clear_headers();
95        self
96    }
97
98    /// Set raw body bytes.
99    pub fn body<B: Into<Vec<u8>>>(&mut self, bytes: B) -> &mut Self {
100        self.request.set_body(Body::from_bytes(bytes));
101        self
102    }
103
104    /// Set UTF-8 text body (will be encoded per `Content-Type` on send).
105    pub fn body_text<T: Into<String>>(&mut self, text: T) -> &mut Self {
106        self.request
107            .set_body(Body::from_bytes(text.into().into_bytes()));
108        self
109    }
110
111    /// Set JSON body (serialised via `serde_json`).
112    pub fn body_json<V: serde::Serialize>(&mut self, value: &V) -> &mut Self {
113        if let Ok(bytes) = serde_json::to_vec(value) {
114            self.request.set_body(Body::from_bytes(bytes));
115        }
116        self
117    }
118
119    /// Set request timeout in milliseconds.
120    pub fn timeout(&mut self, ms: u64) -> &mut Self {
121        self.request.config.set_timeout(ms);
122        self
123    }
124
125    /// Set per-read buffer size.
126    pub fn buffer_size(&mut self, n: usize) -> &mut Self {
127        self.request.config.set_buffer_size(n);
128        self
129    }
130
131    /// Force HTTP/1.1.
132    pub fn http1_1_only(&mut self) -> &mut Self {
133        self.request.config.http_version = HttpVersion::Http1_1;
134        self
135    }
136
137    /// Force HTTP/2.
138    pub fn http2_only(&mut self) -> &mut Self {
139        self.request.config.http_version = HttpVersion::Http2;
140        self
141    }
142
143    /// Enable auto-follow of 3xx redirects.
144    pub fn redirect(&mut self) -> &mut Self {
145        self.request.config.set_redirect(true);
146        self
147    }
148
149    /// Disable auto-follow of 3xx redirects (default).
150    pub fn no_redirect(&mut self) -> &mut Self {
151        self.request.config.set_redirect(false);
152        self
153    }
154
155    /// Maximum number of redirects to follow (default `DEFAULT_MAX_REDIRECT_TIMES`).
156    pub fn max_redirect_times(&mut self, n: usize) -> &mut Self {
157        self.request.config.set_max_redirect_times(n);
158        self
159    }
160
161    /// Enable automatic response body decompression (gzip / deflate / br).
162    pub fn decode(&mut self) -> &mut Self {
163        self.request.config.set_decode(true);
164        self
165    }
166
167    /// Disable automatic response body decompression.
168    pub fn no_decode(&mut self) -> &mut Self {
169        self.request.config.set_decode(false);
170        self
171    }
172
173    /// Set the proxy configuration. Pass `None` (via [`Proxy::default()`) to
174    /// clear an existing proxy.
175    ///
176    /// Construct via [`Proxy::http`] / [`Proxy::https`] / [`Proxy::socks5`]
177    /// and optionally chain `.auth(user, pass)`.
178    pub fn proxy(&mut self, proxy: Proxy) -> &mut Self {
179        self.request.config.set_proxy(Some(proxy));
180        self
181    }
182
183    /// Clear the proxy (use direct connection).
184    pub fn no_proxy(&mut self) -> &mut Self {
185        self.request.config.set_proxy(None);
186        self
187    }
188
189    /// Finalise the builder and return the [`HttpRequest`].
190    pub fn build(&mut self) -> HttpRequest {
191        std::mem::take(&mut self.request)
192    }
193}