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}