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}