http/request.rs
1//! HTTP request types.
2//!
3//! This module contains structs related to HTTP requests, notably the
4//! `Request` type itself as well as a builder to create requests. Typically
5//! you'll import the `http::Request` type rather than reaching into this
6//! module itself.
7//!
8//! # Examples
9//!
10//! Creating a `Request` to send
11//!
12//! ```no_run
13//! use http::{Request, Response};
14//!
15//! let mut request = Request::builder()
16//! .uri("https://www.rust-lang.org/")
17//! .header("User-Agent", "my-awesome-agent/1.0");
18//!
19//! if needs_awesome_header() {
20//! request = request.header("Awesome", "yes");
21//! }
22//!
23//! let response = send(request.body(()).unwrap());
24//!
25//! # fn needs_awesome_header() -> bool {
26//! # true
27//! # }
28//! #
29//! fn send(req: Request<()>) -> Response<()> {
30//! // ...
31//! # panic!()
32//! }
33//! ```
34//!
35//! Inspecting a request to see what was sent.
36//!
37//! ```
38//! use http::{Request, Response, StatusCode};
39//!
40//! fn respond_to(req: Request<()>) -> http::Result<Response<()>> {
41//! if req.uri() != "/awesome-url" {
42//! return Response::builder()
43//! .status(StatusCode::NOT_FOUND)
44//! .body(())
45//! }
46//!
47//! let has_awesome_header = req.headers().contains_key("Awesome");
48//! let body = req.body();
49//!
50//! // ...
51//! # panic!()
52//! }
53//! ```
54
55use std::any::Any;
56use std::convert::TryInto;
57use std::fmt;
58
59use crate::header::{HeaderMap, HeaderName, HeaderValue};
60use crate::method::Method;
61use crate::version::Version;
62use crate::{Extensions, Result, Uri};
63
64/// Represents an HTTP request.
65///
66/// An HTTP request consists of a head and a potentially optional body. The body
67/// component is generic, enabling arbitrary types to represent the HTTP body.
68/// For example, the body could be `Vec<u8>`, a `Stream` of byte chunks, or a
69/// value that has been deserialized.
70///
71/// # Examples
72///
73/// Creating a `Request` to send
74///
75/// ```no_run
76/// use http::{Request, Response};
77///
78/// let mut request = Request::builder()
79/// .uri("https://www.rust-lang.org/")
80/// .header("User-Agent", "my-awesome-agent/1.0");
81///
82/// if needs_awesome_header() {
83/// request = request.header("Awesome", "yes");
84/// }
85///
86/// let response = send(request.body(()).unwrap());
87///
88/// # fn needs_awesome_header() -> bool {
89/// # true
90/// # }
91/// #
92/// fn send(req: Request<()>) -> Response<()> {
93/// // ...
94/// # panic!()
95/// }
96/// ```
97///
98/// Inspecting a request to see what was sent.
99///
100/// ```
101/// use http::{Request, Response, StatusCode};
102///
103/// fn respond_to(req: Request<()>) -> http::Result<Response<()>> {
104/// if req.uri() != "/awesome-url" {
105/// return Response::builder()
106/// .status(StatusCode::NOT_FOUND)
107/// .body(())
108/// }
109///
110/// let has_awesome_header = req.headers().contains_key("Awesome");
111/// let body = req.body();
112///
113/// // ...
114/// # panic!()
115/// }
116/// ```
117///
118/// Deserialize a request of bytes via json:
119///
120/// ```
121/// use http::Request;
122/// use serde::de;
123///
124/// fn deserialize<T>(req: Request<Vec<u8>>) -> serde_json::Result<Request<T>>
125/// where for<'de> T: de::Deserialize<'de>,
126/// {
127/// let (parts, body) = req.into_parts();
128/// let body = serde_json::from_slice(&body)?;
129/// Ok(Request::from_parts(parts, body))
130/// }
131/// #
132/// # fn main() {}
133/// ```
134///
135/// Or alternatively, serialize the body of a request to json
136///
137/// ```
138/// use http::Request;
139/// use serde::ser;
140///
141/// fn serialize<T>(req: Request<T>) -> serde_json::Result<Request<Vec<u8>>>
142/// where T: ser::Serialize,
143/// {
144/// let (parts, body) = req.into_parts();
145/// let body = serde_json::to_vec(&body)?;
146/// Ok(Request::from_parts(parts, body))
147/// }
148/// #
149/// # fn main() {}
150/// ```
151#[derive(Clone)]
152pub struct Request<T> {
153 head: Parts,
154 body: T,
155}
156
157/// Component parts of an HTTP `Request`
158///
159/// The HTTP request head consists of a method, uri, version, and a set of
160/// header fields.
161#[derive(Clone)]
162pub struct Parts {
163 /// The request's method
164 pub method: Method,
165
166 /// The request's URI
167 pub uri: Uri,
168
169 /// The request's version
170 pub version: Version,
171
172 /// The request's headers
173 pub headers: HeaderMap<HeaderValue>,
174
175 /// The request's extensions
176 pub extensions: Extensions,
177
178 _priv: (),
179}
180
181/// An HTTP request builder
182///
183/// This type can be used to construct an instance or `Request`
184/// through a builder-like pattern.
185#[derive(Debug)]
186pub struct Builder {
187 inner: Result<Parts>,
188}
189
190impl Request<()> {
191 /// Creates a new builder-style object to manufacture a `Request`
192 ///
193 /// This method returns an instance of `Builder` which can be used to
194 /// create a `Request`.
195 ///
196 /// # Examples
197 ///
198 /// ```
199 /// # use http::*;
200 /// let request = Request::builder()
201 /// .method("GET")
202 /// .uri("https://www.rust-lang.org/")
203 /// .header("X-Custom-Foo", "Bar")
204 /// .body(())
205 /// .unwrap();
206 /// ```
207 #[inline]
208 pub fn builder() -> Builder {
209 Builder::new()
210 }
211
212 /// Creates a new `Builder` initialized with a GET method and the given URI.
213 ///
214 /// This method returns an instance of `Builder` which can be used to
215 /// create a `Request`.
216 ///
217 /// # Example
218 ///
219 /// ```
220 /// # use http::*;
221 ///
222 /// let request = Request::get("https://www.rust-lang.org/")
223 /// .body(())
224 /// .unwrap();
225 /// ```
226 pub fn get<T>(uri: T) -> Builder
227 where
228 T: TryInto<Uri>,
229 <T as TryInto<Uri>>::Error: Into<crate::Error>,
230 {
231 Builder::new().method(Method::GET).uri(uri)
232 }
233
234 /// Creates a new `Builder` initialized with a PUT method and the given URI.
235 ///
236 /// This method returns an instance of `Builder` which can be used to
237 /// create a `Request`.
238 ///
239 /// # Example
240 ///
241 /// ```
242 /// # use http::*;
243 ///
244 /// let request = Request::put("https://www.rust-lang.org/")
245 /// .body(())
246 /// .unwrap();
247 /// ```
248 pub fn put<T>(uri: T) -> Builder
249 where
250 T: TryInto<Uri>,
251 <T as TryInto<Uri>>::Error: Into<crate::Error>,
252 {
253 Builder::new().method(Method::PUT).uri(uri)
254 }
255
256 /// Creates a new `Builder` initialized with a POST method and the given URI.
257 ///
258 /// This method returns an instance of `Builder` which can be used to
259 /// create a `Request`.
260 ///
261 /// # Example
262 ///
263 /// ```
264 /// # use http::*;
265 ///
266 /// let request = Request::post("https://www.rust-lang.org/")
267 /// .body(())
268 /// .unwrap();
269 /// ```
270 pub fn post<T>(uri: T) -> Builder
271 where
272 T: TryInto<Uri>,
273 <T as TryInto<Uri>>::Error: Into<crate::Error>,
274 {
275 Builder::new().method(Method::POST).uri(uri)
276 }
277
278 /// Creates a new `Builder` initialized with a DELETE method and the given URI.
279 ///
280 /// This method returns an instance of `Builder` which can be used to
281 /// create a `Request`.
282 ///
283 /// # Example
284 ///
285 /// ```
286 /// # use http::*;
287 ///
288 /// let request = Request::delete("https://www.rust-lang.org/")
289 /// .body(())
290 /// .unwrap();
291 /// ```
292 pub fn delete<T>(uri: T) -> Builder
293 where
294 T: TryInto<Uri>,
295 <T as TryInto<Uri>>::Error: Into<crate::Error>,
296 {
297 Builder::new().method(Method::DELETE).uri(uri)
298 }
299
300 /// Creates a new `Builder` initialized with an OPTIONS method and the given URI.
301 ///
302 /// This method returns an instance of `Builder` which can be used to
303 /// create a `Request`.
304 ///
305 /// # Example
306 ///
307 /// ```
308 /// # use http::*;
309 ///
310 /// let request = Request::options("https://www.rust-lang.org/")
311 /// .body(())
312 /// .unwrap();
313 /// # assert_eq!(*request.method(), Method::OPTIONS);
314 /// ```
315 pub fn options<T>(uri: T) -> Builder
316 where
317 T: TryInto<Uri>,
318 <T as TryInto<Uri>>::Error: Into<crate::Error>,
319 {
320 Builder::new().method(Method::OPTIONS).uri(uri)
321 }
322
323 /// Creates a new `Builder` initialized with a HEAD method and the given URI.
324 ///
325 /// This method returns an instance of `Builder` which can be used to
326 /// create a `Request`.
327 ///
328 /// # Example
329 ///
330 /// ```
331 /// # use http::*;
332 ///
333 /// let request = Request::head("https://www.rust-lang.org/")
334 /// .body(())
335 /// .unwrap();
336 /// ```
337 pub fn head<T>(uri: T) -> Builder
338 where
339 T: TryInto<Uri>,
340 <T as TryInto<Uri>>::Error: Into<crate::Error>,
341 {
342 Builder::new().method(Method::HEAD).uri(uri)
343 }
344
345 /// Creates a new `Builder` initialized with a CONNECT method and the given URI.
346 ///
347 /// This method returns an instance of `Builder` which can be used to
348 /// create a `Request`.
349 ///
350 /// # Example
351 ///
352 /// ```
353 /// # use http::*;
354 ///
355 /// let request = Request::connect("https://www.rust-lang.org/")
356 /// .body(())
357 /// .unwrap();
358 /// ```
359 pub fn connect<T>(uri: T) -> Builder
360 where
361 T: TryInto<Uri>,
362 <T as TryInto<Uri>>::Error: Into<crate::Error>,
363 {
364 Builder::new().method(Method::CONNECT).uri(uri)
365 }
366
367 /// Creates a new `Builder` initialized with a PATCH method and the given URI.
368 ///
369 /// This method returns an instance of `Builder` which can be used to
370 /// create a `Request`.
371 ///
372 /// # Example
373 ///
374 /// ```
375 /// # use http::*;
376 ///
377 /// let request = Request::patch("https://www.rust-lang.org/")
378 /// .body(())
379 /// .unwrap();
380 /// ```
381 pub fn patch<T>(uri: T) -> Builder
382 where
383 T: TryInto<Uri>,
384 <T as TryInto<Uri>>::Error: Into<crate::Error>,
385 {
386 Builder::new().method(Method::PATCH).uri(uri)
387 }
388
389 /// Creates a new `Builder` initialized with a TRACE method and the given URI.
390 ///
391 /// This method returns an instance of `Builder` which can be used to
392 /// create a `Request`.
393 ///
394 /// # Example
395 ///
396 /// ```
397 /// # use http::*;
398 ///
399 /// let request = Request::trace("https://www.rust-lang.org/")
400 /// .body(())
401 /// .unwrap();
402 /// ```
403 pub fn trace<T>(uri: T) -> Builder
404 where
405 T: TryInto<Uri>,
406 <T as TryInto<Uri>>::Error: Into<crate::Error>,
407 {
408 Builder::new().method(Method::TRACE).uri(uri)
409 }
410}
411
412impl<T> Request<T> {
413 /// Creates a new blank `Request` with the body
414 ///
415 /// The component parts of this request will be set to their default, e.g.
416 /// the GET method, no headers, etc.
417 ///
418 /// # Examples
419 ///
420 /// ```
421 /// # use http::*;
422 /// let request = Request::new("hello world");
423 ///
424 /// assert_eq!(*request.method(), Method::GET);
425 /// assert_eq!(*request.body(), "hello world");
426 /// ```
427 #[inline]
428 pub fn new(body: T) -> Request<T> {
429 Request {
430 head: Parts::new(),
431 body,
432 }
433 }
434
435 /// Creates a new `Request` with the given components parts and body.
436 ///
437 /// # Examples
438 ///
439 /// ```
440 /// # use http::*;
441 /// let request = Request::new("hello world");
442 /// let (mut parts, body) = request.into_parts();
443 /// parts.method = Method::POST;
444 ///
445 /// let request = Request::from_parts(parts, body);
446 /// ```
447 #[inline]
448 pub fn from_parts(parts: Parts, body: T) -> Request<T> {
449 Request { head: parts, body }
450 }
451
452 /// Returns a reference to the associated HTTP method.
453 ///
454 /// # Examples
455 ///
456 /// ```
457 /// # use http::*;
458 /// let request: Request<()> = Request::default();
459 /// assert_eq!(*request.method(), Method::GET);
460 /// ```
461 #[inline]
462 pub fn method(&self) -> &Method {
463 &self.head.method
464 }
465
466 /// Returns a mutable reference to the associated HTTP method.
467 ///
468 /// # Examples
469 ///
470 /// ```
471 /// # use http::*;
472 /// let mut request: Request<()> = Request::default();
473 /// *request.method_mut() = Method::PUT;
474 /// assert_eq!(*request.method(), Method::PUT);
475 /// ```
476 #[inline]
477 pub fn method_mut(&mut self) -> &mut Method {
478 &mut self.head.method
479 }
480
481 /// Returns a reference to the associated URI.
482 ///
483 /// # Examples
484 ///
485 /// ```
486 /// # use http::*;
487 /// let request: Request<()> = Request::default();
488 /// assert_eq!(*request.uri(), *"/");
489 /// ```
490 #[inline]
491 pub fn uri(&self) -> &Uri {
492 &self.head.uri
493 }
494
495 /// Returns a mutable reference to the associated URI.
496 ///
497 /// # Examples
498 ///
499 /// ```
500 /// # use http::*;
501 /// let mut request: Request<()> = Request::default();
502 /// *request.uri_mut() = "/hello".parse().unwrap();
503 /// assert_eq!(*request.uri(), *"/hello");
504 /// ```
505 #[inline]
506 pub fn uri_mut(&mut self) -> &mut Uri {
507 &mut self.head.uri
508 }
509
510 /// Returns the associated version.
511 ///
512 /// # Examples
513 ///
514 /// ```
515 /// # use http::*;
516 /// let request: Request<()> = Request::default();
517 /// assert_eq!(request.version(), Version::HTTP_11);
518 /// ```
519 #[inline]
520 pub fn version(&self) -> Version {
521 self.head.version
522 }
523
524 /// Returns a mutable reference to the associated version.
525 ///
526 /// # Examples
527 ///
528 /// ```
529 /// # use http::*;
530 /// let mut request: Request<()> = Request::default();
531 /// *request.version_mut() = Version::HTTP_2;
532 /// assert_eq!(request.version(), Version::HTTP_2);
533 /// ```
534 #[inline]
535 pub fn version_mut(&mut self) -> &mut Version {
536 &mut self.head.version
537 }
538
539 /// Returns a reference to the associated header field map.
540 ///
541 /// # Examples
542 ///
543 /// ```
544 /// # use http::*;
545 /// let request: Request<()> = Request::default();
546 /// assert!(request.headers().is_empty());
547 /// ```
548 #[inline]
549 pub fn headers(&self) -> &HeaderMap<HeaderValue> {
550 &self.head.headers
551 }
552
553 /// Returns a mutable reference to the associated header field map.
554 ///
555 /// # Examples
556 ///
557 /// ```
558 /// # use http::*;
559 /// # use http::header::*;
560 /// let mut request: Request<()> = Request::default();
561 /// request.headers_mut().insert(HOST, HeaderValue::from_static("world"));
562 /// assert!(!request.headers().is_empty());
563 /// ```
564 #[inline]
565 pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
566 &mut self.head.headers
567 }
568
569 /// Returns a reference to the associated extensions.
570 ///
571 /// # Examples
572 ///
573 /// ```
574 /// # use http::*;
575 /// let request: Request<()> = Request::default();
576 /// assert!(request.extensions().get::<i32>().is_none());
577 /// ```
578 #[inline]
579 pub fn extensions(&self) -> &Extensions {
580 &self.head.extensions
581 }
582
583 /// Returns a mutable reference to the associated extensions.
584 ///
585 /// # Examples
586 ///
587 /// ```
588 /// # use http::*;
589 /// # use http::header::*;
590 /// let mut request: Request<()> = Request::default();
591 /// request.extensions_mut().insert("hello");
592 /// assert_eq!(request.extensions().get(), Some(&"hello"));
593 /// ```
594 #[inline]
595 pub fn extensions_mut(&mut self) -> &mut Extensions {
596 &mut self.head.extensions
597 }
598
599 /// Returns a reference to the associated HTTP body.
600 ///
601 /// # Examples
602 ///
603 /// ```
604 /// # use http::*;
605 /// let request: Request<String> = Request::default();
606 /// assert!(request.body().is_empty());
607 /// ```
608 #[inline]
609 pub fn body(&self) -> &T {
610 &self.body
611 }
612
613 /// Returns a mutable reference to the associated HTTP body.
614 ///
615 /// # Examples
616 ///
617 /// ```
618 /// # use http::*;
619 /// let mut request: Request<String> = Request::default();
620 /// request.body_mut().push_str("hello world");
621 /// assert!(!request.body().is_empty());
622 /// ```
623 #[inline]
624 pub fn body_mut(&mut self) -> &mut T {
625 &mut self.body
626 }
627
628 /// Consumes the request, returning just the body.
629 ///
630 /// # Examples
631 ///
632 /// ```
633 /// # use http::Request;
634 /// let request = Request::new(10);
635 /// let body = request.into_body();
636 /// assert_eq!(body, 10);
637 /// ```
638 #[inline]
639 pub fn into_body(self) -> T {
640 self.body
641 }
642
643 /// Consumes the request returning the head and body parts.
644 ///
645 /// # Examples
646 ///
647 /// ```
648 /// # use http::*;
649 /// let request = Request::new(());
650 /// let (parts, body) = request.into_parts();
651 /// assert_eq!(parts.method, Method::GET);
652 /// ```
653 #[inline]
654 pub fn into_parts(self) -> (Parts, T) {
655 (self.head, self.body)
656 }
657
658 /// Consumes the request returning a new request with body mapped to the
659 /// return type of the passed in function.
660 ///
661 /// # Examples
662 ///
663 /// ```
664 /// # use http::*;
665 /// let request = Request::builder().body("some string").unwrap();
666 /// let mapped_request: Request<&[u8]> = request.map(|b| {
667 /// assert_eq!(b, "some string");
668 /// b.as_bytes()
669 /// });
670 /// assert_eq!(mapped_request.body(), &"some string".as_bytes());
671 /// ```
672 #[inline]
673 pub fn map<F, U>(self, f: F) -> Request<U>
674 where
675 F: FnOnce(T) -> U,
676 {
677 Request {
678 body: f(self.body),
679 head: self.head,
680 }
681 }
682}
683
684impl<T: Default> Default for Request<T> {
685 fn default() -> Request<T> {
686 Request::new(T::default())
687 }
688}
689
690impl<T: fmt::Debug> fmt::Debug for Request<T> {
691 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
692 f.debug_struct("Request")
693 .field("method", self.method())
694 .field("uri", self.uri())
695 .field("version", &self.version())
696 .field("headers", self.headers())
697 // omits Extensions because not useful
698 .field("body", self.body())
699 .finish()
700 }
701}
702
703impl Parts {
704 /// Creates a new default instance of `Parts`
705 fn new() -> Parts {
706 Parts {
707 method: Method::default(),
708 uri: Uri::default(),
709 version: Version::default(),
710 headers: HeaderMap::default(),
711 extensions: Extensions::default(),
712 _priv: (),
713 }
714 }
715}
716
717impl fmt::Debug for Parts {
718 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
719 f.debug_struct("Parts")
720 .field("method", &self.method)
721 .field("uri", &self.uri)
722 .field("version", &self.version)
723 .field("headers", &self.headers)
724 // omits Extensions because not useful
725 // omits _priv because not useful
726 .finish()
727 }
728}
729
730impl Builder {
731 /// Creates a new default instance of `Builder` to construct a `Request`.
732 ///
733 /// # Examples
734 ///
735 /// ```
736 /// # use http::*;
737 ///
738 /// let req = request::Builder::new()
739 /// .method("POST")
740 /// .body(())
741 /// .unwrap();
742 /// ```
743 #[inline]
744 pub fn new() -> Builder {
745 Builder::default()
746 }
747
748 /// Set the HTTP method for this request.
749 ///
750 /// By default this is `GET`.
751 ///
752 /// # Examples
753 ///
754 /// ```
755 /// # use http::*;
756 ///
757 /// let req = Request::builder()
758 /// .method("POST")
759 /// .body(())
760 /// .unwrap();
761 /// ```
762 pub fn method<T>(self, method: T) -> Builder
763 where
764 T: TryInto<Method>,
765 <T as TryInto<Method>>::Error: Into<crate::Error>,
766 {
767 self.and_then(move |mut head| {
768 let method = method.try_into().map_err(Into::into)?;
769 head.method = method;
770 Ok(head)
771 })
772 }
773
774 /// Get the HTTP Method for this request.
775 ///
776 /// By default this is `GET`. If builder has error, returns None.
777 ///
778 /// # Examples
779 ///
780 /// ```
781 /// # use http::*;
782 ///
783 /// let mut req = Request::builder();
784 /// assert_eq!(req.method_ref(),Some(&Method::GET));
785 ///
786 /// req = req.method("POST");
787 /// assert_eq!(req.method_ref(),Some(&Method::POST));
788 /// ```
789 pub fn method_ref(&self) -> Option<&Method> {
790 self.inner.as_ref().ok().map(|h| &h.method)
791 }
792
793 /// Set the URI for this request.
794 ///
795 /// By default this is `/`.
796 ///
797 /// # Examples
798 ///
799 /// ```
800 /// # use http::*;
801 ///
802 /// let req = Request::builder()
803 /// .uri("https://www.rust-lang.org/")
804 /// .body(())
805 /// .unwrap();
806 /// ```
807 pub fn uri<T>(self, uri: T) -> Builder
808 where
809 T: TryInto<Uri>,
810 <T as TryInto<Uri>>::Error: Into<crate::Error>,
811 {
812 self.and_then(move |mut head| {
813 head.uri = uri.try_into().map_err(Into::into)?;
814 Ok(head)
815 })
816 }
817
818 /// Get the URI for this request
819 ///
820 /// By default this is `/`.
821 ///
822 /// # Examples
823 ///
824 /// ```
825 /// # use http::*;
826 ///
827 /// let mut req = Request::builder();
828 /// assert_eq!(req.uri_ref().unwrap(), "/" );
829 ///
830 /// req = req.uri("https://www.rust-lang.org/");
831 /// assert_eq!(req.uri_ref().unwrap(), "https://www.rust-lang.org/" );
832 /// ```
833 pub fn uri_ref(&self) -> Option<&Uri> {
834 self.inner.as_ref().ok().map(|h| &h.uri)
835 }
836
837 /// Set the HTTP version for this request.
838 ///
839 /// By default this is HTTP/1.1
840 ///
841 /// # Examples
842 ///
843 /// ```
844 /// # use http::*;
845 ///
846 /// let req = Request::builder()
847 /// .version(Version::HTTP_2)
848 /// .body(())
849 /// .unwrap();
850 /// ```
851 pub fn version(self, version: Version) -> Builder {
852 self.and_then(move |mut head| {
853 head.version = version;
854 Ok(head)
855 })
856 }
857
858 /// Get the HTTP version for this request
859 ///
860 /// By default this is HTTP/1.1.
861 ///
862 /// # Examples
863 ///
864 /// ```
865 /// # use http::*;
866 ///
867 /// let mut req = Request::builder();
868 /// assert_eq!(req.version_ref().unwrap(), &Version::HTTP_11 );
869 ///
870 /// req = req.version(Version::HTTP_2);
871 /// assert_eq!(req.version_ref().unwrap(), &Version::HTTP_2 );
872 /// ```
873 pub fn version_ref(&self) -> Option<&Version> {
874 self.inner.as_ref().ok().map(|h| &h.version)
875 }
876
877 /// Appends a header to this request builder.
878 ///
879 /// This function will append the provided key/value as a header to the
880 /// internal `HeaderMap` being constructed. Essentially this is equivalent
881 /// to calling `HeaderMap::append`.
882 ///
883 /// # Examples
884 ///
885 /// ```
886 /// # use http::*;
887 /// # use http::header::HeaderValue;
888 ///
889 /// let req = Request::builder()
890 /// .header("Accept", "text/html")
891 /// .header("X-Custom-Foo", "bar")
892 /// .body(())
893 /// .unwrap();
894 /// ```
895 pub fn header<K, V>(self, key: K, value: V) -> Builder
896 where
897 K: TryInto<HeaderName>,
898 <K as TryInto<HeaderName>>::Error: Into<crate::Error>,
899 V: TryInto<HeaderValue>,
900 <V as TryInto<HeaderValue>>::Error: Into<crate::Error>,
901 {
902 self.and_then(move |mut head| {
903 let name = key.try_into().map_err(Into::into)?;
904 let value = value.try_into().map_err(Into::into)?;
905 head.headers.try_append(name, value)?;
906 Ok(head)
907 })
908 }
909
910 /// Get header on this request builder.
911 /// when builder has error returns None
912 ///
913 /// # Example
914 ///
915 /// ```
916 /// # use http::Request;
917 /// let req = Request::builder()
918 /// .header("Accept", "text/html")
919 /// .header("X-Custom-Foo", "bar");
920 /// let headers = req.headers_ref().unwrap();
921 /// assert_eq!( headers["Accept"], "text/html" );
922 /// assert_eq!( headers["X-Custom-Foo"], "bar" );
923 /// ```
924 pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> {
925 self.inner.as_ref().ok().map(|h| &h.headers)
926 }
927
928 /// Get headers on this request builder.
929 ///
930 /// When builder has error returns None.
931 ///
932 /// # Example
933 ///
934 /// ```
935 /// # use http::{header::HeaderValue, Request};
936 /// let mut req = Request::builder();
937 /// {
938 /// let headers = req.headers_mut().unwrap();
939 /// headers.insert("Accept", HeaderValue::from_static("text/html"));
940 /// headers.insert("X-Custom-Foo", HeaderValue::from_static("bar"));
941 /// }
942 /// let headers = req.headers_ref().unwrap();
943 /// assert_eq!( headers["Accept"], "text/html" );
944 /// assert_eq!( headers["X-Custom-Foo"], "bar" );
945 /// ```
946 pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> {
947 self.inner.as_mut().ok().map(|h| &mut h.headers)
948 }
949
950 /// Adds an extension to this builder
951 ///
952 /// # Examples
953 ///
954 /// ```
955 /// # use http::*;
956 ///
957 /// let req = Request::builder()
958 /// .extension("My Extension")
959 /// .body(())
960 /// .unwrap();
961 ///
962 /// assert_eq!(req.extensions().get::<&'static str>(),
963 /// Some(&"My Extension"));
964 /// ```
965 pub fn extension<T>(self, extension: T) -> Builder
966 where
967 T: Clone + Any + Send + Sync + 'static,
968 {
969 self.and_then(move |mut head| {
970 head.extensions.insert(extension);
971 Ok(head)
972 })
973 }
974
975 /// Get a reference to the extensions for this request builder.
976 ///
977 /// If the builder has an error, this returns `None`.
978 ///
979 /// # Example
980 ///
981 /// ```
982 /// # use http::Request;
983 /// let req = Request::builder().extension("My Extension").extension(5u32);
984 /// let extensions = req.extensions_ref().unwrap();
985 /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension"));
986 /// assert_eq!(extensions.get::<u32>(), Some(&5u32));
987 /// ```
988 pub fn extensions_ref(&self) -> Option<&Extensions> {
989 self.inner.as_ref().ok().map(|h| &h.extensions)
990 }
991
992 /// Get a mutable reference to the extensions for this request builder.
993 ///
994 /// If the builder has an error, this returns `None`.
995 ///
996 /// # Example
997 ///
998 /// ```
999 /// # use http::Request;
1000 /// let mut req = Request::builder().extension("My Extension");
1001 /// let mut extensions = req.extensions_mut().unwrap();
1002 /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension"));
1003 /// extensions.insert(5u32);
1004 /// assert_eq!(extensions.get::<u32>(), Some(&5u32));
1005 /// ```
1006 pub fn extensions_mut(&mut self) -> Option<&mut Extensions> {
1007 self.inner.as_mut().ok().map(|h| &mut h.extensions)
1008 }
1009
1010 /// "Consumes" this builder, using the provided `body` to return a
1011 /// constructed `Request`.
1012 ///
1013 /// # Errors
1014 ///
1015 /// This function may return an error if any previously configured argument
1016 /// failed to parse or get converted to the internal representation. For
1017 /// example if an invalid `head` was specified via `header("Foo",
1018 /// "Bar\r\n")` the error will be returned when this function is called
1019 /// rather than when `header` was called.
1020 ///
1021 /// # Examples
1022 ///
1023 /// ```
1024 /// # use http::*;
1025 ///
1026 /// let request = Request::builder()
1027 /// .body(())
1028 /// .unwrap();
1029 /// ```
1030 pub fn body<T>(self, body: T) -> Result<Request<T>> {
1031 self.inner.map(move |head| Request { head, body })
1032 }
1033
1034 // private
1035
1036 fn and_then<F>(self, func: F) -> Self
1037 where
1038 F: FnOnce(Parts) -> Result<Parts>,
1039 {
1040 Builder {
1041 inner: self.inner.and_then(func),
1042 }
1043 }
1044}
1045
1046impl Default for Builder {
1047 #[inline]
1048 fn default() -> Builder {
1049 Builder {
1050 inner: Ok(Parts::new()),
1051 }
1052 }
1053}
1054
1055#[cfg(test)]
1056mod tests {
1057 use super::*;
1058
1059 #[test]
1060 fn it_can_map_a_body_from_one_type_to_another() {
1061 let request = Request::builder().body("some string").unwrap();
1062 let mapped_request = request.map(|s| {
1063 assert_eq!(s, "some string");
1064 123u32
1065 });
1066 assert_eq!(mapped_request.body(), &123u32);
1067 }
1068}