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