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