From 320f2e0efa6bc2bb856683e5aba608fc11bbca61 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Fri, 30 Sep 2016 20:22:06 -0700 Subject: [PATCH] Document Request. --- lib/src/lib.rs | 4 +- lib/src/request/request.rs | 82 +++++++++++++++++++++++++++++++++++--- 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 3f41b1a8..ea9fcf8e 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -9,8 +9,8 @@ //! There's an [overview](https://rocket.rs/overview) of Rocket on the main site //! as well as a [full, detailed guide](https://rocket.rs/guide). If you'd like //! pointers on getting started, see the -//! [quickstart](https://rocket.rs/guide/quickstart) or [getting started -//! chapter](https://rocket.rs/guide/getting_started) of the guide. +//! [quickstart](https://rocket.rs/guide/quickstart) or [getting +//! started](https://rocket.rs/guide/getting_started) chapters of the guide. //! //! You may also be interested in looking at the [contrib API //! documentation](../rocket_contrib), which contains JSON and templating diff --git a/lib/src/request/request.rs b/lib/src/request/request.rs index 19b51f9a..aaafafd6 100644 --- a/lib/src/request/request.rs +++ b/lib/src/request/request.rs @@ -19,9 +19,27 @@ use router::Route; // Hyper stuff. use request::{Cookies, HyperCookie, HyperHeaders, HyperRequest}; +/// The type for all incoming web requests. +/// +/// This should be used sparingly in Rocket applications. In particular, it +/// should likely only be used when writing +/// [FromRequest](trait.FromRequest.html) implementations. It contains all of +/// the information for a given web request. This includes the HTTP method, URI, +/// cookies, headers, and more. pub struct Request<'a> { + /// The HTTP method associated with the request. pub method: Method, + /// The URI associated with the request. pub uri: URIBuf, // FIXME: Should be URI (without Hyper). + ///
+ /// + /// Unstable + /// (#17): + /// The underlying HTTP library/types are likely to change before v1.0. + /// + ///
+ /// + /// The data in the request. pub data: Vec, // FIXME: Don't read this! (bad Hyper.) cookies: Cookies, headers: HyperHeaders, // This sucks. @@ -29,7 +47,22 @@ pub struct Request<'a> { } impl<'a> Request<'a> { - // FIXME: Don't do the from_param parsing here. I think. Not sure. Decide. + /// Retrieves and parses into `T` the `n`th dynamic parameter from the + /// request. Returns `Error::NoKey` if `n` is greater than the number of + /// params. Returns `Error::BadParse` if the parameter type `T` can't be + /// parsed from the parameter. + /// + /// # Example + /// + /// To retrieve parameter `n` as some type `T` that implements + /// [FromParam](trait.FromParam.html) inside a + /// [FromRequest](trait.FromRequest.html) implementation: + /// + /// ```rust,ignore + /// fn from_request(request: &'r Request<'c>) -> .. { + /// let my_param: T = request.get_param(n); + /// } + /// ``` pub fn get_param>(&self, n: usize) -> Result { let params = self.params.borrow(); if params.is_none() || n >= params.as_ref().unwrap().len() { @@ -40,11 +73,21 @@ impl<'a> Request<'a> { } } + /// Returns a borrow to the cookies sent with this request. Note that + /// `Cookie` implements internal mutability, so this method allows you to + /// get _and_ set cookies in the given Request. pub fn cookies<'r>(&'r self) -> &'r Cookies { &self.cookies } - /// i is the index of the first segment to consider + /// Retrieves and parses into `T` all of the path segments in the request + /// URI beginning and including the 0-indexed `i`. `T` must implement + /// [FromSegments](trait.FromSegments.html), which is used to parse the + /// segments. + /// + /// For example, if the request URI is `"/hello/there/i/am/here"`, then + /// `request.get_segments::(1)` will attempt to parse the segments + /// `"there/i/am/here"` as type `T`. pub fn get_segments<'r: 'a, T: FromSegments<'a>>(&'r self, i: usize) -> Result { @@ -61,6 +104,8 @@ impl<'a> Request<'a> { } } + // FIXME: Implement a testing framework for Rocket. + #[doc(hidden)] pub fn mock(method: Method, uri: &str) -> Request { Request { params: RefCell::new(None), @@ -72,13 +117,32 @@ impl<'a> Request<'a> { } } - // FIXME: Get rid of Hyper. - #[inline(always)] + ///
+ /// + /// Unstable + /// (#17): + /// The underlying HTTP library/types are likely to change before v1.0. + /// + ///
+ /// + /// Returns the headers in this request. pub fn headers(&self) -> &HyperHeaders { + // FIXME: Get rid of Hyper. &self.headers } - // FIXME: This should be an Option. Not all requests have content types. + ///
+ /// + /// Unstable + /// (#17): + /// The underlying HTTP library/types are likely to change before v1.0. + /// + ///
+ /// + /// Returns the Content-Type from the request. Althought you can retrieve + /// the content-type from the headers directly, this method is considered to + /// be more stable. If no Content-Type was specified in the request, a + /// Content-Type of [any](struct.ContentType.html#method.any) is returned. pub fn content_type(&self) -> ContentType { let hyp_ct = self.headers().get::(); hyp_ct.map_or(ContentType::any(), |ct| ContentType::from(&ct.0)) @@ -97,21 +161,27 @@ impl<'a> Request<'a> { }) } + /// Retrieves the URI from the request. Rocket only allows absolute URIs, so + /// the URI will be absolute. pub fn uri(&'a self) -> URI<'a> { self.uri.as_uri() } // FIXME: Don't need a refcell for this. + #[doc(hidden)] pub fn set_params(&'a self, route: &Route) { *self.params.borrow_mut() = Some(route.get_params(self.uri.as_uri())) } + #[doc(hidden)] #[cfg(test)] pub fn set_content_type(&mut self, ct: ContentType) { let hyper_ct = header::ContentType(ct.into()); self.headers.set::(hyper_ct) } + /// Create a Rocket Request from a Hyper Request. + #[doc(hidden)] pub fn from_hyp<'h, 'k>(hyper_req: HyperRequest<'h, 'k>) -> Result, String> { let (_, h_method, h_headers, h_uri, _, mut h_body) = hyper_req.deconstruct(); @@ -150,6 +220,8 @@ impl<'a> Request<'a> { } impl<'r> fmt::Display for Request<'r> { + /// Pretty prints a Request. This is primarily used by Rocket's logging + /// infrastructure. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{} {}", Green.paint(&self.method), Blue.paint(&self.uri)) }