Skip to main content

rama_http_types/
request.rs

1use std::fmt;
2
3use crate::Result;
4use crate::{HeaderMap, HeaderName, HeaderValue, Method, Uri, Version, body::Body};
5use rama_core::extensions::{Extension, Extensions, ExtensionsRef};
6use rama_net::ClientIp;
7use rama_utils::macros::generate_set_and_with;
8
9/// Represents an HTTP request.
10///
11/// An HTTP request consists of a head and a potentially optional body. The body
12/// component is generic, enabling arbitrary types to represent the HTTP body.
13/// For example, the body could be `Vec<u8>`, a `Stream` of byte chunks, or a
14/// value that has been deserialized.
15///
16/// The Serde representation contains `method`, `uri`, `version`, `headers`,
17/// and `body`. Typed [`Extensions`] are process-local values and are
18/// intentionally omitted. Deserializing therefore creates empty extensions.
19///
20/// # Examples
21///
22/// Creating a `Request` to send
23///
24/// ```no_run
25/// use rama_http_types::{Request, Response};
26///
27/// let mut request = Request::builder()
28///     .uri("https://www.rust-lang.org/")
29///     .header("User-Agent", "my-awesome-agent/1.0");
30///
31/// if needs_awesome_header() {
32///     request = request.header("Awesome", "yes");
33/// }
34///
35/// let response = send(request.body(()).unwrap());
36///
37/// # fn needs_awesome_header() -> bool {
38/// #     true
39/// # }
40/// #
41/// fn send(req: Request<()>) -> Response<()> {
42///     // ...
43/// # panic!()
44/// }
45/// ```
46///
47/// Inspecting a request to see what was sent.
48///
49/// ```
50/// use rama_http_types::{Request, Response, Result, StatusCode};
51///
52/// fn respond_to(req: Request<()>) -> Result<Response<()>> {
53///     if req.uri().as_str() != "/awesome-url" {
54///         return Response::builder()
55///             .status(StatusCode::NOT_FOUND)
56///             .body(())
57///     }
58///
59///     let has_awesome_header = req.headers().contains_key("Awesome");
60///     let body = req.body();
61///
62///     // ...
63/// # panic!()
64/// }
65/// ```
66///
67/// Deserialize a request of bytes via json:
68///
69/// ```
70/// use rama_http_types::Request;
71/// use serde::de;
72///
73/// fn deserialize<T>(req: Request<Vec<u8>>) -> serde_json::Result<Request<T>>
74///     where for<'de> T: de::Deserialize<'de>,
75/// {
76///     let (parts, body) = req.into_parts();
77///     let body = serde_json::from_slice(&body)?;
78///     Ok(Request::from_parts(parts, body))
79/// }
80/// #
81/// # fn main() {}
82/// ```
83///
84/// Or alternatively, serialize the body of a request to json
85///
86/// ```
87/// use rama_http_types::Request;
88/// use serde::ser;
89///
90/// fn serialize<T>(req: Request<T>) -> serde_json::Result<Request<Vec<u8>>>
91///     where T: ser::Serialize,
92/// {
93///     let (parts, body) = req.into_parts();
94///     let body = serde_json::to_vec(&body)?;
95///     Ok(Request::from_parts(parts, body))
96/// }
97/// #
98/// # fn main() {}
99/// ```
100#[derive(Clone)]
101pub struct Request<T = Body> {
102    head: Parts,
103    body: T,
104}
105
106#[non_exhaustive]
107#[derive(Clone)]
108pub struct Parts {
109    /// The request's method
110    pub method: Method,
111
112    /// The request's URI
113    pub uri: Uri,
114
115    /// The request's version
116    pub version: Version,
117
118    /// The request's headers
119    pub headers: HeaderMap<HeaderValue>,
120
121    /// The request's extensions
122    pub extensions: Extensions,
123}
124
125#[derive(serde::Deserialize)]
126#[serde(rename = "RequestParts")]
127struct RequestPartsSerde {
128    method: Method,
129    uri: String,
130    version: Version,
131    headers: HeaderMap<HeaderValue>,
132}
133
134impl serde::Serialize for Parts {
135    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
136    where
137        S: serde::Serializer,
138    {
139        use serde::ser::SerializeStruct as _;
140
141        let mut state = serializer.serialize_struct("RequestParts", 4)?;
142        state.serialize_field("method", &self.method)?;
143        state.serialize_field("uri", &self.uri)?;
144        state.serialize_field("version", &self.version)?;
145        state.serialize_field("headers", &self.headers)?;
146        state.end()
147    }
148}
149
150impl<'de> serde::Deserialize<'de> for Parts {
151    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
152    where
153        D: serde::Deserializer<'de>,
154    {
155        let repr = RequestPartsSerde::deserialize(deserializer)?;
156        let uri =
157            deserialize_request_uri(&repr.method, &repr.uri).map_err(serde::de::Error::custom)?;
158        Ok(Self {
159            method: repr.method,
160            uri,
161            version: repr.version,
162            headers: repr.headers,
163            extensions: Extensions::new(),
164        })
165    }
166}
167
168impl<T: serde::Serialize> serde::Serialize for Request<T> {
169    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
170    where
171        S: serde::Serializer,
172    {
173        use serde::ser::SerializeStruct as _;
174
175        let mut state = serializer.serialize_struct("Request", 5)?;
176        state.serialize_field("method", &self.head.method)?;
177        state.serialize_field("uri", &self.head.uri)?;
178        state.serialize_field("version", &self.head.version)?;
179        state.serialize_field("headers", &self.head.headers)?;
180        state.serialize_field("body", &self.body)?;
181        state.end()
182    }
183}
184
185#[derive(serde::Deserialize)]
186#[serde(rename = "Request")]
187struct RequestSerde<T> {
188    method: Method,
189    uri: String,
190    version: Version,
191    headers: HeaderMap<HeaderValue>,
192    body: T,
193}
194
195impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for Request<T> {
196    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
197    where
198        D: serde::Deserializer<'de>,
199    {
200        let repr = RequestSerde::deserialize(deserializer)?;
201        let uri =
202            deserialize_request_uri(&repr.method, &repr.uri).map_err(serde::de::Error::custom)?;
203        Ok(Self {
204            head: Parts {
205                method: repr.method,
206                uri,
207                version: repr.version,
208                headers: repr.headers,
209                extensions: Extensions::new(),
210            },
211            body: repr.body,
212        })
213    }
214}
215
216fn deserialize_request_uri(method: &Method, value: &str) -> Result<Uri> {
217    if method == Method::CONNECT {
218        Uri::parse_authority_form(value).or_else(|_| Uri::parse_reference(value))
219    } else {
220        Uri::parse_reference(value)
221    }
222    .map_err(Into::into)
223}
224
225impl ExtensionsRef for Parts {
226    fn extensions(&self) -> &Extensions {
227        &self.extensions
228    }
229}
230
231impl ClientIp for Parts {
232    fn client_ip(&self) -> Option<std::net::IpAddr> {
233        rama_net::client_ip::client_ip(self)
234    }
235}
236
237/// An HTTP request builder
238///
239/// This type can be used to construct an instance of `Request`
240/// through a builder-like pattern.
241#[derive(Debug)]
242#[must_use]
243pub struct Builder {
244    inner: Result<Parts>,
245}
246
247impl Request<()> {
248    /// Creates a new builder-style object to manufacture a `Request`
249    ///
250    /// This method returns an instance of `Builder` which can be used to
251    /// create a `Request`.
252    ///
253    /// # Examples
254    ///
255    /// ```
256    /// # use rama_http_types::*;
257    /// let request = Request::builder()
258    ///     .method("GET")
259    ///     .uri("https://www.rust-lang.org/")
260    ///     .header("X-Custom-Foo", "Bar")
261    ///     .body(())
262    ///     .unwrap();
263    /// ```
264    #[inline]
265    pub fn builder() -> Builder {
266        Builder::new()
267    }
268
269    #[inline]
270    /// Same as [`Request::builder`] but with the given [`Extensions`] to start from.
271    pub fn builder_with_extensions(ext: Extensions) -> Builder {
272        Builder::new_with_extensions(ext)
273    }
274
275    /// Creates a new `Builder` initialized with a GET method and the given URI.
276    ///
277    /// This method returns an instance of `Builder` which can be used to
278    /// create a `Request`.
279    ///
280    /// # Example
281    ///
282    /// ```
283    /// # use rama_http_types::*;
284    ///
285    /// let request = Request::get("https://www.rust-lang.org/")
286    ///     .body(())
287    ///     .unwrap();
288    /// ```
289    pub fn get<T>(uri: T) -> Builder
290    where
291        T: TryInto<Uri>,
292        <T as TryInto<Uri>>::Error: Into<crate::Error>,
293    {
294        Builder::new().method(Method::GET).uri(uri)
295    }
296
297    /// Creates a new `Builder` initialized with a PUT method and the given URI.
298    ///
299    /// This method returns an instance of `Builder` which can be used to
300    /// create a `Request`.
301    ///
302    /// # Example
303    ///
304    /// ```
305    /// # use rama_http_types::*;
306    ///
307    /// let request = Request::put("https://www.rust-lang.org/")
308    ///     .body(())
309    ///     .unwrap();
310    /// ```
311    pub fn put<T>(uri: T) -> Builder
312    where
313        T: TryInto<Uri>,
314        <T as TryInto<Uri>>::Error: Into<crate::Error>,
315    {
316        Builder::new().method(Method::PUT).uri(uri)
317    }
318
319    /// Creates a new `Builder` initialized with a POST method and the given URI.
320    ///
321    /// This method returns an instance of `Builder` which can be used to
322    /// create a `Request`.
323    ///
324    /// # Example
325    ///
326    /// ```
327    /// # use rama_http_types::*;
328    ///
329    /// let request = Request::post("https://www.rust-lang.org/")
330    ///     .body(())
331    ///     .unwrap();
332    /// ```
333    pub fn post<T>(uri: T) -> Builder
334    where
335        T: TryInto<Uri>,
336        <T as TryInto<Uri>>::Error: Into<crate::Error>,
337    {
338        Builder::new().method(Method::POST).uri(uri)
339    }
340
341    /// Creates a new `Builder` initialized with a DELETE method and the given URI.
342    ///
343    /// This method returns an instance of `Builder` which can be used to
344    /// create a `Request`.
345    ///
346    /// # Example
347    ///
348    /// ```
349    /// # use rama_http_types::*;
350    ///
351    /// let request = Request::delete("https://www.rust-lang.org/")
352    ///     .body(())
353    ///     .unwrap();
354    /// ```
355    pub fn delete<T>(uri: T) -> Builder
356    where
357        T: TryInto<Uri>,
358        <T as TryInto<Uri>>::Error: Into<crate::Error>,
359    {
360        Builder::new().method(Method::DELETE).uri(uri)
361    }
362
363    /// Creates a new `Builder` initialized with an OPTIONS method and the given URI.
364    ///
365    /// This method returns an instance of `Builder` which can be used to
366    /// create a `Request`.
367    ///
368    /// # Example
369    ///
370    /// ```
371    /// # use rama_http_types::*;
372    ///
373    /// let request = Request::options("https://www.rust-lang.org/")
374    ///     .body(())
375    ///     .unwrap();
376    /// # assert_eq!(*request.method(), Method::OPTIONS);
377    /// ```
378    pub fn options<T>(uri: T) -> Builder
379    where
380        T: TryInto<Uri>,
381        <T as TryInto<Uri>>::Error: Into<crate::Error>,
382    {
383        Builder::new().method(Method::OPTIONS).uri(uri)
384    }
385
386    /// Creates a new `Builder` initialized with a HEAD method and the given URI.
387    ///
388    /// This method returns an instance of `Builder` which can be used to
389    /// create a `Request`.
390    ///
391    /// # Example
392    ///
393    /// ```
394    /// # use rama_http_types::*;
395    ///
396    /// let request = Request::head("https://www.rust-lang.org/")
397    ///     .body(())
398    ///     .unwrap();
399    /// ```
400    pub fn head<T>(uri: T) -> Builder
401    where
402        T: TryInto<Uri>,
403        <T as TryInto<Uri>>::Error: Into<crate::Error>,
404    {
405        Builder::new().method(Method::HEAD).uri(uri)
406    }
407
408    /// Creates a new `Builder` initialized with a CONNECT method and the given URI.
409    ///
410    /// This method returns an instance of `Builder` which can be used to
411    /// create a `Request`.
412    ///
413    /// # Example
414    ///
415    /// ```
416    /// # use rama_http_types::*;
417    ///
418    /// let request = Request::connect("https://www.rust-lang.org/")
419    ///     .body(())
420    ///     .unwrap();
421    /// ```
422    pub fn connect<T>(uri: T) -> Builder
423    where
424        T: TryInto<Uri>,
425        <T as TryInto<Uri>>::Error: Into<crate::Error>,
426    {
427        Builder::new().method(Method::CONNECT).uri(uri)
428    }
429
430    /// Creates a new `Builder` initialized with a PATCH method and the given URI.
431    ///
432    /// This method returns an instance of `Builder` which can be used to
433    /// create a `Request`.
434    ///
435    /// # Example
436    ///
437    /// ```
438    /// # use rama_http_types::*;
439    ///
440    /// let request = Request::patch("https://www.rust-lang.org/")
441    ///     .body(())
442    ///     .unwrap();
443    /// ```
444    pub fn patch<T>(uri: T) -> Builder
445    where
446        T: TryInto<Uri>,
447        <T as TryInto<Uri>>::Error: Into<crate::Error>,
448    {
449        Builder::new().method(Method::PATCH).uri(uri)
450    }
451
452    /// Creates a new `Builder` initialized with a TRACE method and the given URI.
453    ///
454    /// This method returns an instance of `Builder` which can be used to
455    /// create a `Request`.
456    ///
457    /// # Example
458    ///
459    /// ```
460    /// # use rama_http_types::*;
461    ///
462    /// let request = Request::trace("https://www.rust-lang.org/")
463    ///     .body(())
464    ///     .unwrap();
465    /// ```
466    pub fn trace<T>(uri: T) -> Builder
467    where
468        T: TryInto<Uri>,
469        <T as TryInto<Uri>>::Error: Into<crate::Error>,
470    {
471        Builder::new().method(Method::TRACE).uri(uri)
472    }
473
474    /// Creates a new `Builder` initialized with a QUERY method and the given URI.
475    ///
476    /// QUERY ([RFC 10008](https://www.rfc-editor.org/rfc/rfc10008)) is a safe,
477    /// idempotent method whose request content defines the query; remember to
478    /// set a `Content-Type` for the body.
479    ///
480    /// This method returns an instance of `Builder` which can be used to
481    /// create a `Request`.
482    ///
483    /// # Example
484    ///
485    /// ```
486    /// # use rama_http_types::*;
487    ///
488    /// let request = Request::query("https://www.rust-lang.org/")
489    ///     .body(())
490    ///     .unwrap();
491    /// ```
492    pub fn query<T>(uri: T) -> Builder
493    where
494        T: TryInto<Uri>,
495        <T as TryInto<Uri>>::Error: Into<crate::Error>,
496    {
497        Builder::new().method(Method::QUERY).uri(uri)
498    }
499}
500
501impl<T> Request<T> {
502    /// Creates a new blank `Request` with the body
503    ///
504    /// The component parts of this request will be set to their default, e.g.
505    /// the GET method, no headers, etc.
506    ///
507    /// # Examples
508    ///
509    /// ```
510    /// # use rama_http_types::*;
511    /// let request = Request::new("hello world");
512    ///
513    /// assert_eq!(*request.method(), Method::GET);
514    /// assert_eq!(*request.body(), "hello world");
515    /// ```
516    #[inline]
517    pub fn new(body: T) -> Self {
518        Self {
519            head: Parts::new(),
520            body,
521        }
522    }
523
524    /// Creates a new `Request` with the given components parts and body.
525    ///
526    /// # Examples
527    ///
528    /// ```
529    /// # use rama_http_types::*;
530    /// let request = Request::new("hello world");
531    /// let (mut parts, body) = request.into_parts();
532    /// parts.method = Method::POST;
533    ///
534    /// let request = Request::from_parts(parts, body);
535    /// ```
536    #[inline]
537    pub fn from_parts(parts: Parts, body: T) -> Self {
538        Self { head: parts, body }
539    }
540
541    /// Returns a reference to the associated HTTP method.
542    ///
543    /// # Examples
544    ///
545    /// ```
546    /// # use rama_http_types::*;
547    /// let request: Request<()> = Request::default();
548    /// assert_eq!(*request.method(), Method::GET);
549    /// ```
550    #[inline]
551    pub fn method(&self) -> &Method {
552        &self.head.method
553    }
554
555    /// Returns a mutable reference to the associated HTTP method.
556    ///
557    /// # Examples
558    ///
559    /// ```
560    /// # use rama_http_types::*;
561    /// let mut request: Request<()> = Request::default();
562    /// *request.method_mut() = Method::PUT;
563    /// assert_eq!(*request.method(), Method::PUT);
564    /// ```
565    #[inline]
566    pub fn method_mut(&mut self) -> &mut Method {
567        &mut self.head.method
568    }
569
570    /// Returns a reference to the associated URI.
571    ///
572    /// # Examples
573    ///
574    /// ```
575    /// # use rama_http_types::*;
576    /// let request: Request<()> = Request::default();
577    /// assert_eq!(request.uri().as_str(), "/");
578    /// ```
579    #[inline]
580    pub fn uri(&self) -> &Uri {
581        &self.head.uri
582    }
583
584    /// Get the URI as complete as possible for this request.
585    ///
586    /// Where [`uri`](Self::uri) returns the URI exactly as received (often
587    /// origin-form `/path` for HTTP/1.1), this fills in the scheme and
588    /// authority from the request's effective protocol and authority (URI →
589    /// TLS SNI → `Forwarded` → `Host` header) — a derivation
590    /// callers can treat as a technical detail.
591    #[must_use]
592    pub fn request_uri(&self) -> Uri {
593        use rama_net::{AuthorityInputExt as _, ProtocolInputExt as _};
594
595        let mut uri = self.uri().clone();
596        if let Some(authority) = self.authority() {
597            let protocol = self.protocol().unwrap_or(&rama_net::Protocol::HTTP);
598            let rama_net::address::HostWithOptPort { host, port } =
599                authority.without_default_port_for(Some(protocol));
600            uri.set_scheme(protocol.clone())
601                .set_host(host)
602                .set_port(port);
603        }
604        uri
605    }
606
607    /// Returns a mutable reference to the associated URI.
608    ///
609    /// # Examples
610    ///
611    /// ```
612    /// # use rama_http_types::*;
613    /// let mut request: Request<()> = Request::default();
614    /// *request.uri_mut() = "/hello".parse().unwrap();
615    /// assert_eq!(request.uri().as_str(), "/hello");
616    /// ```
617    #[inline]
618    pub fn uri_mut(&mut self) -> &mut Uri {
619        &mut self.head.uri
620    }
621
622    /// Returns the associated version.
623    ///
624    /// # Examples
625    ///
626    /// ```
627    /// # use rama_http_types::*;
628    /// let request: Request<()> = Request::default();
629    /// assert_eq!(request.version(), Version::HTTP_11);
630    /// ```
631    #[inline]
632    pub fn version(&self) -> Version {
633        self.head.version
634    }
635
636    /// Returns a mutable reference to the associated version.
637    ///
638    /// # Examples
639    ///
640    /// ```
641    /// # use rama_http_types::*;
642    /// let mut request: Request<()> = Request::default();
643    /// *request.version_mut() = Version::HTTP_2;
644    /// assert_eq!(request.version(), Version::HTTP_2);
645    /// ```
646    #[inline]
647    pub fn version_mut(&mut self) -> &mut Version {
648        &mut self.head.version
649    }
650
651    /// Returns a reference to the associated header field map.
652    ///
653    /// # Examples
654    ///
655    /// ```
656    /// # use rama_http_types::*;
657    /// let request: Request<()> = Request::default();
658    /// assert!(request.headers().is_empty());
659    /// ```
660    #[inline]
661    pub fn headers(&self) -> &HeaderMap<HeaderValue> {
662        &self.head.headers
663    }
664
665    /// Returns a mutable reference to the associated header field map.
666    ///
667    /// # Examples
668    ///
669    /// ```
670    /// # use rama_http_types::*;
671    /// # use rama_http_types::header::*;
672    /// let mut request: Request<()> = Request::default();
673    /// request.headers_mut().insert(HOST, HeaderValue::from_static("world"));
674    /// assert!(!request.headers().is_empty());
675    /// ```
676    #[inline]
677    pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
678        &mut self.head.headers
679    }
680
681    /// Returned a cloned of the associated HTTP header.
682    #[inline]
683    pub fn clone_parts(&self) -> Parts {
684        self.head.clone()
685    }
686
687    /// Returns a reference to the associated HTTP body.
688    ///
689    /// # Examples
690    ///
691    /// ```
692    /// # use rama_http_types::*;
693    /// let request: Request<String> = Request::default();
694    /// assert!(request.body().is_empty());
695    /// ```
696    #[inline]
697    pub fn body(&self) -> &T {
698        &self.body
699    }
700
701    /// Returns a mutable reference to the associated HTTP body.
702    ///
703    /// # Examples
704    ///
705    /// ```
706    /// # use rama_http_types::*;
707    /// let mut request: Request<String> = Request::default();
708    /// request.body_mut().push_str("hello world");
709    /// assert!(!request.body().is_empty());
710    /// ```
711    #[inline]
712    pub fn body_mut(&mut self) -> &mut T {
713        &mut self.body
714    }
715
716    /// Consumes the request, returning just the body.
717    ///
718    /// # Examples
719    ///
720    /// ```
721    /// # use rama_http_types::Request;
722    /// let request = Request::new(10);
723    /// let body = request.into_body();
724    /// assert_eq!(body, 10);
725    /// ```
726    #[inline]
727    pub fn into_body(self) -> T {
728        self.body
729    }
730
731    /// Consumes the request returning the head and body parts.
732    ///
733    /// # Examples
734    ///
735    /// ```
736    /// # use rama_http_types::*;
737    /// let request = Request::new(());
738    /// let (parts, body) = request.into_parts();
739    /// assert_eq!(parts.method, Method::GET);
740    /// ```
741    #[inline]
742    pub fn into_parts(self) -> (Parts, T) {
743        (self.head, self.body)
744    }
745
746    /// Consumes the request returning a new request with body mapped to the
747    /// return type of the passed in function.
748    ///
749    /// # Examples
750    ///
751    /// ```
752    /// # use rama_http_types::*;
753    /// let request = Request::builder().body("some string").unwrap();
754    /// let mapped_request: Request<&[u8]> = request.map(|b| {
755    ///   assert_eq!(b, "some string");
756    ///   b.as_bytes()
757    /// });
758    /// assert_eq!(mapped_request.body(), &"some string".as_bytes());
759    /// ```
760    #[inline]
761    pub fn map<F, U>(self, f: F) -> Request<U>
762    where
763        F: FnOnce(T) -> U,
764    {
765        Request {
766            body: f(self.body),
767            head: self.head,
768        }
769    }
770
771    generate_set_and_with! {
772        pub fn extensions(mut self, extensions: Extensions) -> Self {
773            self.head.extensions = extensions;
774            self
775        }
776    }
777
778    /// Replace this request's [`Extensions`] with a [`fork`][Extensions::fork] of them, returning
779    /// the original store.
780    ///
781    /// Use this to give one attempt of a multi-attempt operation — a redirect hop, a retry — its
782    /// own child store: the attempt reads everything the caller inserted, its own inserts land in
783    /// the child, and the returned parent stays untouched so the next attempt can fork from it
784    /// again.
785    ///
786    /// # Examples
787    ///
788    /// ```
789    /// # use rama_http_types::Request;
790    /// # use rama_core::extensions::{Extension, ExtensionsRef as _};
791    /// #[derive(Debug, Extension)]
792    /// struct Caller;
793    /// #[derive(Debug, Extension)]
794    /// struct Attempt;
795    ///
796    /// let mut req = Request::new(());
797    /// req.extensions().insert(Caller);
798    ///
799    /// let parent = req.fork_extensions_in_place();
800    /// req.extensions().insert(Attempt);
801    ///
802    /// assert!(req.extensions().contains::<Caller>());
803    /// assert!(!parent.contains::<Attempt>());
804    /// ```
805    #[must_use]
806    pub fn fork_extensions_in_place(&mut self) -> Extensions {
807        let child = self.head.extensions.fork();
808        core::mem::replace(&mut self.head.extensions, child)
809    }
810}
811
812impl<T: Default> Default for Request<T> {
813    fn default() -> Self {
814        Self::new(T::default())
815    }
816}
817
818impl<T: fmt::Debug> fmt::Debug for Request<T> {
819    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
820        f.debug_struct("Request")
821            .field("method", self.method())
822            .field("uri", self.uri())
823            .field("version", &self.version())
824            .field("headers", self.headers())
825            // omits Extensions because not useful
826            .field("body", self.body())
827            .finish()
828    }
829}
830
831impl<B> ExtensionsRef for Request<B> {
832    fn extensions(&self) -> &Extensions {
833        &self.head.extensions
834    }
835}
836
837impl<B> ClientIp for Request<B> {
838    fn client_ip(&self) -> Option<std::net::IpAddr> {
839        rama_net::client_ip::client_ip(self)
840    }
841}
842
843impl Parts {
844    /// Creates a new default instance of `Parts`
845    fn new() -> Self {
846        Self {
847            method: Method::default(),
848            uri: Uri::from_static("/"),
849            version: Version::default(),
850            headers: HeaderMap::default(),
851            extensions: Extensions::default(),
852        }
853    }
854}
855
856impl fmt::Debug for Parts {
857    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
858        f.debug_struct("Parts")
859            .field("method", &self.method)
860            .field("uri", &self.uri)
861            .field("version", &self.version)
862            .field("headers", &self.headers)
863            // omits Extensions because not useful
864            // omits _priv because not useful
865            .finish()
866    }
867}
868
869impl Builder {
870    /// Creates a new default instance of `Builder` to construct a `Request`.
871    ///
872    /// # Examples
873    ///
874    /// ```
875    /// # use rama_http_types::*;
876    ///
877    /// let req = request::Builder::new()
878    ///     .method("POST")
879    ///     .body(())
880    ///     .unwrap();
881    /// ```
882    #[inline]
883    pub fn new() -> Self {
884        Self::default()
885    }
886
887    #[inline]
888    /// Same as [`Self::new`] but with the given [`Extensions`] to start from.
889    pub fn new_with_extensions(ext: Extensions) -> Self {
890        Self {
891            inner: Ok(Parts {
892                method: Method::default(),
893                uri: Uri::from_static("/"),
894                version: Version::default(),
895                headers: HeaderMap::default(),
896                extensions: ext,
897            }),
898        }
899    }
900
901    /// Set the HTTP method for this request.
902    ///
903    /// By default this is `GET`.
904    ///
905    /// # Examples
906    ///
907    /// ```
908    /// # use rama_http_types::*;
909    ///
910    /// let req = Request::builder()
911    ///     .method("POST")
912    ///     .body(())
913    ///     .unwrap();
914    /// ```
915    pub fn method<T>(self, method: T) -> Self
916    where
917        T: TryInto<Method>,
918        <T as TryInto<Method>>::Error: Into<crate::Error>,
919    {
920        self.and_then(move |mut head| {
921            let method = method.try_into().map_err(Into::into)?;
922            head.method = method;
923            Ok(head)
924        })
925    }
926
927    /// Get the HTTP Method for this request.
928    ///
929    /// By default this is `GET`. If builder has error, returns None.
930    ///
931    /// # Examples
932    ///
933    /// ```
934    /// # use rama_http_types::*;
935    ///
936    /// let mut req = Request::builder();
937    /// assert_eq!(req.method_ref(),Some(&Method::GET));
938    ///
939    /// req = req.method("POST");
940    /// assert_eq!(req.method_ref(),Some(&Method::POST));
941    /// ```
942    pub fn method_ref(&self) -> Option<&Method> {
943        self.inner.as_ref().ok().map(|h| &h.method)
944    }
945
946    /// Set the URI for this request.
947    ///
948    /// By default this is `/`.
949    ///
950    /// # Examples
951    ///
952    /// ```
953    /// # use rama_http_types::*;
954    ///
955    /// let req = Request::builder()
956    ///     .uri("https://www.rust-lang.org/")
957    ///     .body(())
958    ///     .unwrap();
959    /// ```
960    pub fn uri<T>(self, uri: T) -> Self
961    where
962        T: TryInto<Uri>,
963        <T as TryInto<Uri>>::Error: Into<crate::Error>,
964    {
965        self.and_then(move |mut head| {
966            head.uri = uri.try_into().map_err(Into::into)?;
967            Ok(head)
968        })
969    }
970
971    /// Get the URI for this request
972    ///
973    /// By default this is `/`.
974    ///
975    /// # Examples
976    ///
977    /// ```
978    /// # use rama_http_types::*;
979    ///
980    /// let mut req = Request::builder();
981    /// assert_eq!(req.uri_ref().unwrap().as_str(), "/");
982    ///
983    /// req = req.uri("https://www.rust-lang.org/");
984    /// assert_eq!(req.uri_ref().unwrap().as_str(), "https://www.rust-lang.org/");
985    /// ```
986    pub fn uri_ref(&self) -> Option<&Uri> {
987        self.inner.as_ref().ok().map(|h| &h.uri)
988    }
989
990    /// Set the HTTP version for this request.
991    ///
992    /// By default this is HTTP/1.1
993    ///
994    /// # Examples
995    ///
996    /// ```
997    /// # use rama_http_types::*;
998    ///
999    /// let req = Request::builder()
1000    ///     .version(Version::HTTP_2)
1001    ///     .body(())
1002    ///     .unwrap();
1003    /// ```
1004    pub fn version(self, version: Version) -> Self {
1005        self.and_then(move |mut head| {
1006            head.version = version;
1007            Ok(head)
1008        })
1009    }
1010
1011    /// Get the HTTP version for this request
1012    ///
1013    /// By default this is HTTP/1.1.
1014    ///
1015    /// # Examples
1016    ///
1017    /// ```
1018    /// # use rama_http_types::*;
1019    ///
1020    /// let mut req = Request::builder();
1021    /// assert_eq!(req.version_ref().unwrap(), &Version::HTTP_11 );
1022    ///
1023    /// req = req.version(Version::HTTP_2);
1024    /// assert_eq!(req.version_ref().unwrap(), &Version::HTTP_2 );
1025    /// ```
1026    pub fn version_ref(&self) -> Option<&Version> {
1027        self.inner.as_ref().ok().map(|h| &h.version)
1028    }
1029
1030    /// Appends a header to this request builder.
1031    ///
1032    /// This function will append the provided key/value as a header to the
1033    /// internal `HeaderMap` being constructed. Essentially this is equivalent
1034    /// to calling `HeaderMap::append`.
1035    ///
1036    /// # Examples
1037    ///
1038    /// ```
1039    /// # use rama_http_types::*;
1040    /// # use rama_http_types::header::HeaderValue;
1041    ///
1042    /// let req = Request::builder()
1043    ///     .header("Accept", "text/html")
1044    ///     .header("X-Custom-Foo", "bar")
1045    ///     .body(())
1046    ///     .unwrap();
1047    /// ```
1048    pub fn header<K, V>(self, key: K, value: V) -> Self
1049    where
1050        K: TryInto<HeaderName>,
1051        <K as TryInto<HeaderName>>::Error: Into<crate::Error>,
1052        V: TryInto<HeaderValue>,
1053        <V as TryInto<HeaderValue>>::Error: Into<crate::Error>,
1054    {
1055        self.and_then(move |mut head| {
1056            let name = key.try_into().map_err(Into::into)?;
1057            let value = value.try_into().map_err(Into::into)?;
1058            head.headers.try_append(name, value)?;
1059            Ok(head)
1060        })
1061    }
1062
1063    /// Get header on this request builder.
1064    /// when builder has error returns None
1065    ///
1066    /// # Example
1067    ///
1068    /// ```
1069    /// # use rama_http_types::Request;
1070    /// let req = Request::builder()
1071    ///     .header("Accept", "text/html")
1072    ///     .header("X-Custom-Foo", "bar");
1073    /// let headers = req.headers_ref().unwrap();
1074    /// assert_eq!( headers["Accept"], "text/html" );
1075    /// assert_eq!( headers["X-Custom-Foo"], "bar" );
1076    /// ```
1077    pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> {
1078        self.inner.as_ref().ok().map(|h| &h.headers)
1079    }
1080
1081    /// Get headers on this request builder.
1082    ///
1083    /// When builder has error returns None.
1084    ///
1085    /// # Example
1086    ///
1087    /// ```
1088    /// # use rama_http_types::{header::HeaderValue, Request};
1089    /// let mut req = Request::builder();
1090    /// {
1091    ///   let headers = req.headers_mut().unwrap();
1092    ///   headers.insert("Accept", HeaderValue::from_static("text/html"));
1093    ///   headers.insert("X-Custom-Foo", HeaderValue::from_static("bar"));
1094    /// }
1095    /// let headers = req.headers_ref().unwrap();
1096    /// assert_eq!( headers["Accept"], "text/html" );
1097    /// assert_eq!( headers["X-Custom-Foo"], "bar" );
1098    /// ```
1099    pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> {
1100        self.inner.as_mut().ok().map(|h| &mut h.headers)
1101    }
1102
1103    /// Adds an extension to this builder
1104    ///
1105    /// # Examples
1106    ///
1107    /// ```
1108    /// # use rama_http_types::Request;
1109    /// # use rama_core::extensions::{Extension, ExtensionsRef as _};
1110    ///
1111    /// #[derive(Debug, Clone, PartialEq)]
1112    /// struct MyExtension(&'static str);
1113    /// impl Extension for MyExtension {}
1114    ///
1115    /// let req = Request::builder()
1116    ///     .extension(MyExtension("My Extension"))
1117    ///     .body(())
1118    ///     .unwrap();
1119    ///
1120    /// assert_eq!(req.extensions().get_ref::<MyExtension>(),
1121    ///            Some(&MyExtension("My Extension")));
1122    /// ```
1123    pub fn extension<T>(self, extension: T) -> Self
1124    where
1125        T: Extension,
1126    {
1127        self.and_then(move |head| {
1128            head.extensions.insert(extension);
1129            Ok(head)
1130        })
1131    }
1132
1133    /// Get a reference to the extensions for this request builder.
1134    ///
1135    /// If the builder has an error, this returns `None`.
1136    ///
1137    /// # Example
1138    ///
1139    /// ```
1140    /// # use rama_http_types::Request;
1141    /// # use rama_core::extensions::Extension;
1142    /// #[derive(Debug, Clone, PartialEq)]
1143    /// struct MyExtension(&'static str);
1144    /// impl Extension for MyExtension {}
1145    ///
1146    /// #[derive(Debug, Clone, PartialEq)]
1147    /// struct MyCount(u32);
1148    /// impl Extension for MyCount {}
1149    ///
1150    /// let req = Request::builder().extension(MyExtension("My Extension")).extension(MyCount(5));
1151    /// let extensions = req.extensions().unwrap();
1152    /// assert_eq!(extensions.get_ref::<MyExtension>(), Some(&MyExtension("My Extension")));
1153    /// assert_eq!(extensions.get_ref::<MyCount>(), Some(&MyCount(5)));
1154    /// ```
1155    pub fn extensions(&self) -> Option<&Extensions> {
1156        self.inner.as_ref().ok().map(|h| &h.extensions)
1157    }
1158
1159    /// "Consumes" this builder, using the provided `body` to return a
1160    /// constructed `Request`.
1161    ///
1162    /// # Errors
1163    ///
1164    /// This function may return an error if any previously configured argument
1165    /// failed to parse or get converted to the internal representation. For
1166    /// example if an invalid `head` was specified via `header("Foo",
1167    /// "Bar\r\n")` the error will be returned when this function is called
1168    /// rather than when `header` was called.
1169    ///
1170    /// # Examples
1171    ///
1172    /// ```
1173    /// # use rama_http_types::*;
1174    ///
1175    /// let request = Request::builder()
1176    ///     .body(())
1177    ///     .unwrap();
1178    /// ```
1179    pub fn body<T>(self, body: T) -> Result<Request<T>> {
1180        self.inner.map(move |head| Request { head, body })
1181    }
1182
1183    // private
1184
1185    fn and_then<F>(self, func: F) -> Self
1186    where
1187        F: FnOnce(Parts) -> Result<Parts>,
1188    {
1189        Self {
1190            inner: self.inner.and_then(func),
1191        }
1192    }
1193}
1194
1195impl Default for Builder {
1196    #[inline]
1197    fn default() -> Self {
1198        Self {
1199            inner: Ok(Parts::new()),
1200        }
1201    }
1202}
1203
1204/// [`HttpRequestParts`] is used in places where we don't need the [`ReqBody`] of the [`HttpRequest`]
1205///
1206/// In those places we need to support using [`HttpRequest`] and [`Parts`]. By using
1207/// this trait we can support both types behind a single generic that implements this trait.
1208///
1209/// [`ReqBody`]: crate::body::StreamingBody
1210/// [`HttpRequest`]: crate::Request
1211pub trait HttpRequestParts: ExtensionsRef {
1212    fn method(&self) -> &Method;
1213    fn uri(&self) -> &Uri;
1214    fn version(&self) -> Version;
1215    fn headers(&self) -> &HeaderMap<HeaderValue>;
1216}
1217
1218impl<T: HttpRequestParts> HttpRequestParts for &T {
1219    #[inline(always)]
1220    fn method(&self) -> &Method {
1221        (*self).method()
1222    }
1223
1224    #[inline(always)]
1225    fn uri(&self) -> &Uri {
1226        (*self).uri()
1227    }
1228
1229    #[inline(always)]
1230    fn version(&self) -> Version {
1231        (*self).version()
1232    }
1233
1234    #[inline(always)]
1235    fn headers(&self) -> &HeaderMap<HeaderValue> {
1236        (*self).headers()
1237    }
1238}
1239
1240impl<T: HttpRequestParts> HttpRequestParts for &mut T {
1241    #[inline(always)]
1242    fn method(&self) -> &Method {
1243        (**self).method()
1244    }
1245
1246    fn uri(&self) -> &Uri {
1247        (**self).uri()
1248    }
1249
1250    fn version(&self) -> Version {
1251        (**self).version()
1252    }
1253
1254    fn headers(&self) -> &HeaderMap<HeaderValue> {
1255        (**self).headers()
1256    }
1257}
1258
1259impl<Body> HttpRequestParts for Request<Body> {
1260    fn method(&self) -> &Method {
1261        self.method()
1262    }
1263
1264    fn uri(&self) -> &Uri {
1265        self.uri()
1266    }
1267
1268    fn version(&self) -> Version {
1269        self.version()
1270    }
1271
1272    fn headers(&self) -> &HeaderMap<HeaderValue> {
1273        self.headers()
1274    }
1275}
1276
1277impl HttpRequestParts for Parts {
1278    fn method(&self) -> &Method {
1279        &self.method
1280    }
1281
1282    fn uri(&self) -> &Uri {
1283        &self.uri
1284    }
1285
1286    fn version(&self) -> Version {
1287        self.version
1288    }
1289
1290    fn headers(&self) -> &HeaderMap<HeaderValue> {
1291        &self.headers
1292    }
1293}
1294
1295/// Same as [`HttpRequestParts`] but also adding mutable access
1296pub trait HttpRequestPartsMut: HttpRequestParts + ExtensionsRef {
1297    fn method_mut(&mut self) -> &mut Method;
1298    fn uri_mut(&mut self) -> &mut Uri;
1299    fn version_mut(&mut self) -> &mut Version;
1300    fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue>;
1301}
1302
1303impl<T: HttpRequestPartsMut> HttpRequestPartsMut for &mut T {
1304    fn method_mut(&mut self) -> &mut Method {
1305        (*self).method_mut()
1306    }
1307
1308    fn uri_mut(&mut self) -> &mut Uri {
1309        (*self).uri_mut()
1310    }
1311
1312    fn version_mut(&mut self) -> &mut Version {
1313        (*self).version_mut()
1314    }
1315
1316    fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
1317        (*self).headers_mut()
1318    }
1319}
1320
1321impl<Body> HttpRequestPartsMut for Request<Body> {
1322    fn method_mut(&mut self) -> &mut Method {
1323        self.method_mut()
1324    }
1325
1326    fn uri_mut(&mut self) -> &mut Uri {
1327        self.uri_mut()
1328    }
1329
1330    fn version_mut(&mut self) -> &mut Version {
1331        self.version_mut()
1332    }
1333
1334    fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
1335        self.headers_mut()
1336    }
1337}
1338
1339impl HttpRequestPartsMut for Parts {
1340    fn method_mut(&mut self) -> &mut Method {
1341        &mut self.method
1342    }
1343
1344    fn uri_mut(&mut self) -> &mut Uri {
1345        &mut self.uri
1346    }
1347
1348    fn version_mut(&mut self) -> &mut Version {
1349        &mut self.version
1350    }
1351
1352    fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
1353        &mut self.headers
1354    }
1355}
1356
1357#[cfg(test)]
1358mod tests {
1359    use super::*;
1360
1361    #[test]
1362    fn it_can_map_a_body_from_one_type_to_another() {
1363        let request = Request::builder().body("some string").unwrap();
1364        let mapped_request = request.map(|s| {
1365            assert_eq!(s, "some string");
1366            123u32
1367        });
1368        assert_eq!(mapped_request.body(), &123u32);
1369    }
1370
1371    #[test]
1372    fn fork_extensions_in_place_isolates_attempts_from_the_parent() {
1373        #[derive(Debug, Extension)]
1374        struct Caller;
1375        #[derive(Debug, Extension)]
1376        struct AttemptOne;
1377        #[derive(Debug, Extension)]
1378        struct AttemptTwo;
1379
1380        let mut request = Request::new(());
1381        request.extensions().insert(Caller);
1382
1383        let parent = request.fork_extensions_in_place();
1384        assert!(parent.self_contains::<Caller>());
1385
1386        // an attempt reads the caller's extensions but keeps its own inserts to itself
1387        assert!(request.extensions().contains::<Caller>());
1388        request.extensions().insert(AttemptOne);
1389        assert!(!parent.contains::<AttemptOne>());
1390
1391        // ... so the next attempt forks from an untouched parent
1392        request.set_extensions(parent.fork());
1393        assert!(request.extensions().contains::<Caller>());
1394        assert!(!request.extensions().contains::<AttemptOne>());
1395
1396        request.extensions().insert(AttemptTwo);
1397        assert!(!parent.contains::<AttemptTwo>());
1398    }
1399
1400    #[test]
1401    fn test_request_uri() {
1402        use crate::header::HOST;
1403        use rama_net::{
1404            address::Domain,
1405            forwarded::{Forwarded, ForwardedElement},
1406        };
1407
1408        for (request, expected_uri_str) in [
1409            (Request::builder().uri("/foo").body(()).unwrap(), "/foo"),
1410            (
1411                Request::builder()
1412                    .uri("/foo")
1413                    .header(HOST, "example.com")
1414                    .body(())
1415                    .unwrap(),
1416                "http://example.com/foo",
1417            ),
1418            (
1419                Request::builder()
1420                    .uri("/foo")
1421                    .extension(Forwarded::new(ForwardedElement::new_forwarded_host(
1422                        Domain::from_static("example.com"),
1423                    )))
1424                    .body(())
1425                    .unwrap(),
1426                "http://example.com/foo",
1427            ),
1428            (
1429                Request::builder()
1430                    .uri("http://example.com/foo")
1431                    .body(())
1432                    .unwrap(),
1433                "http://example.com/foo",
1434            ),
1435            (
1436                Request::builder()
1437                    .uri("https://example.com/foo")
1438                    .body(())
1439                    .unwrap(),
1440                "https://example.com/foo",
1441            ),
1442            (
1443                Request::builder()
1444                    .uri(Uri::parse_authority_form("WwW.ExamplE.COM").unwrap())
1445                    .body(())
1446                    .unwrap(),
1447                // native Uri preserves the empty path (no forced trailing `/`)
1448                "http://WwW.ExamplE.COM",
1449            ),
1450        ] {
1451            let s = request.request_uri().to_string();
1452            assert_eq!(s, expected_uri_str, "request: {request:?}");
1453        }
1454    }
1455}