diff options
| author | mo khan <mo@mokhan.ca> | 2025-07-15 16:37:08 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-07-17 16:30:22 -0600 |
| commit | 45df4d0d9b577fecee798d672695fe24ff57fb1b (patch) | |
| tree | 1b99bf645035b58e0d6db08c7a83521f41f7a75b /vendor/http/src/request.rs | |
| parent | f94f79608393d4ab127db63cc41668445ef6b243 (diff) | |
feat: migrate from Cedar to SpiceDB authorization system
This is a major architectural change that replaces the Cedar policy-based
authorization system with SpiceDB's relation-based authorization.
Key changes:
- Migrate from Rust to Go implementation
- Replace Cedar policies with SpiceDB schema and relationships
- Switch from envoy `ext_authz` with Cedar to SpiceDB permission checks
- Update build system and dependencies for Go ecosystem
- Maintain Envoy integration for external authorization
This change enables more flexible permission modeling through SpiceDB's
Google Zanzibar inspired relation-based system, supporting complex
hierarchical permissions that were difficult to express in Cedar.
Breaking change: Existing Cedar policies and Rust-based configuration
will no longer work and need to be migrated to SpiceDB schema.
Diffstat (limited to 'vendor/http/src/request.rs')
| -rw-r--r-- | vendor/http/src/request.rs | 1074 |
1 files changed, 0 insertions, 1074 deletions
diff --git a/vendor/http/src/request.rs b/vendor/http/src/request.rs deleted file mode 100644 index 324b676c..00000000 --- a/vendor/http/src/request.rs +++ /dev/null @@ -1,1074 +0,0 @@ -//! HTTP request types. -//! -//! This module contains structs related to HTTP requests, notably the -//! `Request` type itself as well as a builder to create requests. Typically -//! you'll import the `http::Request` type rather than reaching into this -//! module itself. -//! -//! # Examples -//! -//! Creating a `Request` to send -//! -//! ```no_run -//! use http::{Request, Response}; -//! -//! let mut request = Request::builder() -//! .uri("https://www.rust-lang.org/") -//! .header("User-Agent", "my-awesome-agent/1.0"); -//! -//! if needs_awesome_header() { -//! request = request.header("Awesome", "yes"); -//! } -//! -//! let response = send(request.body(()).unwrap()); -//! -//! # fn needs_awesome_header() -> bool { -//! # true -//! # } -//! # -//! fn send(req: Request<()>) -> Response<()> { -//! // ... -//! # panic!() -//! } -//! ``` -//! -//! Inspecting a request to see what was sent. -//! -//! ``` -//! use http::{Request, Response, StatusCode}; -//! -//! fn respond_to(req: Request<()>) -> http::Result<Response<()>> { -//! if req.uri() != "/awesome-url" { -//! return Response::builder() -//! .status(StatusCode::NOT_FOUND) -//! .body(()) -//! } -//! -//! let has_awesome_header = req.headers().contains_key("Awesome"); -//! let body = req.body(); -//! -//! // ... -//! # panic!() -//! } -//! ``` - -use std::any::Any; -use std::convert::TryInto; -use std::fmt; - -use crate::header::{HeaderMap, HeaderName, HeaderValue}; -use crate::method::Method; -use crate::version::Version; -use crate::{Extensions, Result, Uri}; - -/// Represents an HTTP request. -/// -/// An HTTP request consists of a head and a potentially optional body. The body -/// component is generic, enabling arbitrary types to represent the HTTP body. -/// For example, the body could be `Vec<u8>`, a `Stream` of byte chunks, or a -/// value that has been deserialized. -/// -/// # Examples -/// -/// Creating a `Request` to send -/// -/// ```no_run -/// use http::{Request, Response}; -/// -/// let mut request = Request::builder() -/// .uri("https://www.rust-lang.org/") -/// .header("User-Agent", "my-awesome-agent/1.0"); -/// -/// if needs_awesome_header() { -/// request = request.header("Awesome", "yes"); -/// } -/// -/// let response = send(request.body(()).unwrap()); -/// -/// # fn needs_awesome_header() -> bool { -/// # true -/// # } -/// # -/// fn send(req: Request<()>) -> Response<()> { -/// // ... -/// # panic!() -/// } -/// ``` -/// -/// Inspecting a request to see what was sent. -/// -/// ``` -/// use http::{Request, Response, StatusCode}; -/// -/// fn respond_to(req: Request<()>) -> http::Result<Response<()>> { -/// if req.uri() != "/awesome-url" { -/// return Response::builder() -/// .status(StatusCode::NOT_FOUND) -/// .body(()) -/// } -/// -/// let has_awesome_header = req.headers().contains_key("Awesome"); -/// let body = req.body(); -/// -/// // ... -/// # panic!() -/// } -/// ``` -/// -/// Deserialize a request of bytes via json: -/// -/// ``` -/// # extern crate serde; -/// # extern crate serde_json; -/// # extern crate http; -/// use http::Request; -/// use serde::de; -/// -/// fn deserialize<T>(req: Request<Vec<u8>>) -> serde_json::Result<Request<T>> -/// where for<'de> T: de::Deserialize<'de>, -/// { -/// let (parts, body) = req.into_parts(); -/// let body = serde_json::from_slice(&body)?; -/// Ok(Request::from_parts(parts, body)) -/// } -/// # -/// # fn main() {} -/// ``` -/// -/// Or alternatively, serialize the body of a request to json -/// -/// ``` -/// # extern crate serde; -/// # extern crate serde_json; -/// # extern crate http; -/// use http::Request; -/// use serde::ser; -/// -/// fn serialize<T>(req: Request<T>) -> serde_json::Result<Request<Vec<u8>>> -/// where T: ser::Serialize, -/// { -/// let (parts, body) = req.into_parts(); -/// let body = serde_json::to_vec(&body)?; -/// Ok(Request::from_parts(parts, body)) -/// } -/// # -/// # fn main() {} -/// ``` -#[derive(Clone)] -pub struct Request<T> { - head: Parts, - body: T, -} - -/// Component parts of an HTTP `Request` -/// -/// The HTTP request head consists of a method, uri, version, and a set of -/// header fields. -#[derive(Clone)] -pub struct Parts { - /// The request's method - pub method: Method, - - /// The request's URI - pub uri: Uri, - - /// The request's version - pub version: Version, - - /// The request's headers - pub headers: HeaderMap<HeaderValue>, - - /// The request's extensions - pub extensions: Extensions, - - _priv: (), -} - -/// An HTTP request builder -/// -/// This type can be used to construct an instance or `Request` -/// through a builder-like pattern. -#[derive(Debug)] -pub struct Builder { - inner: Result<Parts>, -} - -impl Request<()> { - /// Creates a new builder-style object to manufacture a `Request` - /// - /// This method returns an instance of `Builder` which can be used to - /// create a `Request`. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let request = Request::builder() - /// .method("GET") - /// .uri("https://www.rust-lang.org/") - /// .header("X-Custom-Foo", "Bar") - /// .body(()) - /// .unwrap(); - /// ``` - #[inline] - pub fn builder() -> Builder { - Builder::new() - } - - /// Creates a new `Builder` initialized with a GET method and the given URI. - /// - /// This method returns an instance of `Builder` which can be used to - /// create a `Request`. - /// - /// # Example - /// - /// ``` - /// # use http::*; - /// - /// let request = Request::get("https://www.rust-lang.org/") - /// .body(()) - /// .unwrap(); - /// ``` - pub fn get<T>(uri: T) -> Builder - where - T: TryInto<Uri>, - <T as TryInto<Uri>>::Error: Into<crate::Error>, - { - Builder::new().method(Method::GET).uri(uri) - } - - /// Creates a new `Builder` initialized with a PUT method and the given URI. - /// - /// This method returns an instance of `Builder` which can be used to - /// create a `Request`. - /// - /// # Example - /// - /// ``` - /// # use http::*; - /// - /// let request = Request::put("https://www.rust-lang.org/") - /// .body(()) - /// .unwrap(); - /// ``` - pub fn put<T>(uri: T) -> Builder - where - T: TryInto<Uri>, - <T as TryInto<Uri>>::Error: Into<crate::Error>, - { - Builder::new().method(Method::PUT).uri(uri) - } - - /// Creates a new `Builder` initialized with a POST method and the given URI. - /// - /// This method returns an instance of `Builder` which can be used to - /// create a `Request`. - /// - /// # Example - /// - /// ``` - /// # use http::*; - /// - /// let request = Request::post("https://www.rust-lang.org/") - /// .body(()) - /// .unwrap(); - /// ``` - pub fn post<T>(uri: T) -> Builder - where - T: TryInto<Uri>, - <T as TryInto<Uri>>::Error: Into<crate::Error>, - { - Builder::new().method(Method::POST).uri(uri) - } - - /// Creates a new `Builder` initialized with a DELETE method and the given URI. - /// - /// This method returns an instance of `Builder` which can be used to - /// create a `Request`. - /// - /// # Example - /// - /// ``` - /// # use http::*; - /// - /// let request = Request::delete("https://www.rust-lang.org/") - /// .body(()) - /// .unwrap(); - /// ``` - pub fn delete<T>(uri: T) -> Builder - where - T: TryInto<Uri>, - <T as TryInto<Uri>>::Error: Into<crate::Error>, - { - Builder::new().method(Method::DELETE).uri(uri) - } - - /// Creates a new `Builder` initialized with an OPTIONS method and the given URI. - /// - /// This method returns an instance of `Builder` which can be used to - /// create a `Request`. - /// - /// # Example - /// - /// ``` - /// # use http::*; - /// - /// let request = Request::options("https://www.rust-lang.org/") - /// .body(()) - /// .unwrap(); - /// # assert_eq!(*request.method(), Method::OPTIONS); - /// ``` - pub fn options<T>(uri: T) -> Builder - where - T: TryInto<Uri>, - <T as TryInto<Uri>>::Error: Into<crate::Error>, - { - Builder::new().method(Method::OPTIONS).uri(uri) - } - - /// Creates a new `Builder` initialized with a HEAD method and the given URI. - /// - /// This method returns an instance of `Builder` which can be used to - /// create a `Request`. - /// - /// # Example - /// - /// ``` - /// # use http::*; - /// - /// let request = Request::head("https://www.rust-lang.org/") - /// .body(()) - /// .unwrap(); - /// ``` - pub fn head<T>(uri: T) -> Builder - where - T: TryInto<Uri>, - <T as TryInto<Uri>>::Error: Into<crate::Error>, - { - Builder::new().method(Method::HEAD).uri(uri) - } - - /// Creates a new `Builder` initialized with a CONNECT method and the given URI. - /// - /// This method returns an instance of `Builder` which can be used to - /// create a `Request`. - /// - /// # Example - /// - /// ``` - /// # use http::*; - /// - /// let request = Request::connect("https://www.rust-lang.org/") - /// .body(()) - /// .unwrap(); - /// ``` - pub fn connect<T>(uri: T) -> Builder - where - T: TryInto<Uri>, - <T as TryInto<Uri>>::Error: Into<crate::Error>, - { - Builder::new().method(Method::CONNECT).uri(uri) - } - - /// Creates a new `Builder` initialized with a PATCH method and the given URI. - /// - /// This method returns an instance of `Builder` which can be used to - /// create a `Request`. - /// - /// # Example - /// - /// ``` - /// # use http::*; - /// - /// let request = Request::patch("https://www.rust-lang.org/") - /// .body(()) - /// .unwrap(); - /// ``` - pub fn patch<T>(uri: T) -> Builder - where - T: TryInto<Uri>, - <T as TryInto<Uri>>::Error: Into<crate::Error>, - { - Builder::new().method(Method::PATCH).uri(uri) - } - - /// Creates a new `Builder` initialized with a TRACE method and the given URI. - /// - /// This method returns an instance of `Builder` which can be used to - /// create a `Request`. - /// - /// # Example - /// - /// ``` - /// # use http::*; - /// - /// let request = Request::trace("https://www.rust-lang.org/") - /// .body(()) - /// .unwrap(); - /// ``` - pub fn trace<T>(uri: T) -> Builder - where - T: TryInto<Uri>, - <T as TryInto<Uri>>::Error: Into<crate::Error>, - { - Builder::new().method(Method::TRACE).uri(uri) - } -} - -impl<T> Request<T> { - /// Creates a new blank `Request` with the body - /// - /// The component parts of this request will be set to their default, e.g. - /// the GET method, no headers, etc. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let request = Request::new("hello world"); - /// - /// assert_eq!(*request.method(), Method::GET); - /// assert_eq!(*request.body(), "hello world"); - /// ``` - #[inline] - pub fn new(body: T) -> Request<T> { - Request { - head: Parts::new(), - body, - } - } - - /// Creates a new `Request` with the given components parts and body. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let request = Request::new("hello world"); - /// let (mut parts, body) = request.into_parts(); - /// parts.method = Method::POST; - /// - /// let request = Request::from_parts(parts, body); - /// ``` - #[inline] - pub fn from_parts(parts: Parts, body: T) -> Request<T> { - Request { head: parts, body } - } - - /// Returns a reference to the associated HTTP method. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let request: Request<()> = Request::default(); - /// assert_eq!(*request.method(), Method::GET); - /// ``` - #[inline] - pub fn method(&self) -> &Method { - &self.head.method - } - - /// Returns a mutable reference to the associated HTTP method. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let mut request: Request<()> = Request::default(); - /// *request.method_mut() = Method::PUT; - /// assert_eq!(*request.method(), Method::PUT); - /// ``` - #[inline] - pub fn method_mut(&mut self) -> &mut Method { - &mut self.head.method - } - - /// Returns a reference to the associated URI. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let request: Request<()> = Request::default(); - /// assert_eq!(*request.uri(), *"/"); - /// ``` - #[inline] - pub fn uri(&self) -> &Uri { - &self.head.uri - } - - /// Returns a mutable reference to the associated URI. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let mut request: Request<()> = Request::default(); - /// *request.uri_mut() = "/hello".parse().unwrap(); - /// assert_eq!(*request.uri(), *"/hello"); - /// ``` - #[inline] - pub fn uri_mut(&mut self) -> &mut Uri { - &mut self.head.uri - } - - /// Returns the associated version. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let request: Request<()> = Request::default(); - /// assert_eq!(request.version(), Version::HTTP_11); - /// ``` - #[inline] - pub fn version(&self) -> Version { - self.head.version - } - - /// Returns a mutable reference to the associated version. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let mut request: Request<()> = Request::default(); - /// *request.version_mut() = Version::HTTP_2; - /// assert_eq!(request.version(), Version::HTTP_2); - /// ``` - #[inline] - pub fn version_mut(&mut self) -> &mut Version { - &mut self.head.version - } - - /// Returns a reference to the associated header field map. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let request: Request<()> = Request::default(); - /// assert!(request.headers().is_empty()); - /// ``` - #[inline] - pub fn headers(&self) -> &HeaderMap<HeaderValue> { - &self.head.headers - } - - /// Returns a mutable reference to the associated header field map. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// # use http::header::*; - /// let mut request: Request<()> = Request::default(); - /// request.headers_mut().insert(HOST, HeaderValue::from_static("world")); - /// assert!(!request.headers().is_empty()); - /// ``` - #[inline] - pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> { - &mut self.head.headers - } - - /// Returns a reference to the associated extensions. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let request: Request<()> = Request::default(); - /// assert!(request.extensions().get::<i32>().is_none()); - /// ``` - #[inline] - pub fn extensions(&self) -> &Extensions { - &self.head.extensions - } - - /// Returns a mutable reference to the associated extensions. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// # use http::header::*; - /// let mut request: Request<()> = Request::default(); - /// request.extensions_mut().insert("hello"); - /// assert_eq!(request.extensions().get(), Some(&"hello")); - /// ``` - #[inline] - pub fn extensions_mut(&mut self) -> &mut Extensions { - &mut self.head.extensions - } - - /// Returns a reference to the associated HTTP body. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let request: Request<String> = Request::default(); - /// assert!(request.body().is_empty()); - /// ``` - #[inline] - pub fn body(&self) -> &T { - &self.body - } - - /// Returns a mutable reference to the associated HTTP body. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let mut request: Request<String> = Request::default(); - /// request.body_mut().push_str("hello world"); - /// assert!(!request.body().is_empty()); - /// ``` - #[inline] - pub fn body_mut(&mut self) -> &mut T { - &mut self.body - } - - /// Consumes the request, returning just the body. - /// - /// # Examples - /// - /// ``` - /// # use http::Request; - /// let request = Request::new(10); - /// let body = request.into_body(); - /// assert_eq!(body, 10); - /// ``` - #[inline] - pub fn into_body(self) -> T { - self.body - } - - /// Consumes the request returning the head and body parts. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let request = Request::new(()); - /// let (parts, body) = request.into_parts(); - /// assert_eq!(parts.method, Method::GET); - /// ``` - #[inline] - pub fn into_parts(self) -> (Parts, T) { - (self.head, self.body) - } - - /// Consumes the request returning a new request with body mapped to the - /// return type of the passed in function. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// let request = Request::builder().body("some string").unwrap(); - /// let mapped_request: Request<&[u8]> = request.map(|b| { - /// assert_eq!(b, "some string"); - /// b.as_bytes() - /// }); - /// assert_eq!(mapped_request.body(), &"some string".as_bytes()); - /// ``` - #[inline] - pub fn map<F, U>(self, f: F) -> Request<U> - where - F: FnOnce(T) -> U, - { - Request { - body: f(self.body), - head: self.head, - } - } -} - -impl<T: Default> Default for Request<T> { - fn default() -> Request<T> { - Request::new(T::default()) - } -} - -impl<T: fmt::Debug> fmt::Debug for Request<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Request") - .field("method", self.method()) - .field("uri", self.uri()) - .field("version", &self.version()) - .field("headers", self.headers()) - // omits Extensions because not useful - .field("body", self.body()) - .finish() - } -} - -impl Parts { - /// Creates a new default instance of `Parts` - fn new() -> Parts { - Parts { - method: Method::default(), - uri: Uri::default(), - version: Version::default(), - headers: HeaderMap::default(), - extensions: Extensions::default(), - _priv: (), - } - } -} - -impl fmt::Debug for Parts { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Parts") - .field("method", &self.method) - .field("uri", &self.uri) - .field("version", &self.version) - .field("headers", &self.headers) - // omits Extensions because not useful - // omits _priv because not useful - .finish() - } -} - -impl Builder { - /// Creates a new default instance of `Builder` to construct a `Request`. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// - /// let req = request::Builder::new() - /// .method("POST") - /// .body(()) - /// .unwrap(); - /// ``` - #[inline] - pub fn new() -> Builder { - Builder::default() - } - - /// Set the HTTP method for this request. - /// - /// By default this is `GET`. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// - /// let req = Request::builder() - /// .method("POST") - /// .body(()) - /// .unwrap(); - /// ``` - pub fn method<T>(self, method: T) -> Builder - where - T: TryInto<Method>, - <T as TryInto<Method>>::Error: Into<crate::Error>, - { - self.and_then(move |mut head| { - let method = method.try_into().map_err(Into::into)?; - head.method = method; - Ok(head) - }) - } - - /// Get the HTTP Method for this request. - /// - /// By default this is `GET`. If builder has error, returns None. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// - /// let mut req = Request::builder(); - /// assert_eq!(req.method_ref(),Some(&Method::GET)); - /// - /// req = req.method("POST"); - /// assert_eq!(req.method_ref(),Some(&Method::POST)); - /// ``` - pub fn method_ref(&self) -> Option<&Method> { - self.inner.as_ref().ok().map(|h| &h.method) - } - - /// Set the URI for this request. - /// - /// By default this is `/`. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// - /// let req = Request::builder() - /// .uri("https://www.rust-lang.org/") - /// .body(()) - /// .unwrap(); - /// ``` - pub fn uri<T>(self, uri: T) -> Builder - where - T: TryInto<Uri>, - <T as TryInto<Uri>>::Error: Into<crate::Error>, - { - self.and_then(move |mut head| { - head.uri = uri.try_into().map_err(Into::into)?; - Ok(head) - }) - } - - /// Get the URI for this request - /// - /// By default this is `/`. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// - /// let mut req = Request::builder(); - /// assert_eq!(req.uri_ref().unwrap(), "/" ); - /// - /// req = req.uri("https://www.rust-lang.org/"); - /// assert_eq!(req.uri_ref().unwrap(), "https://www.rust-lang.org/" ); - /// ``` - pub fn uri_ref(&self) -> Option<&Uri> { - self.inner.as_ref().ok().map(|h| &h.uri) - } - - /// Set the HTTP version for this request. - /// - /// By default this is HTTP/1.1 - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// - /// let req = Request::builder() - /// .version(Version::HTTP_2) - /// .body(()) - /// .unwrap(); - /// ``` - pub fn version(self, version: Version) -> Builder { - self.and_then(move |mut head| { - head.version = version; - Ok(head) - }) - } - - /// Get the HTTP version for this request - /// - /// By default this is HTTP/1.1. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// - /// let mut req = Request::builder(); - /// assert_eq!(req.version_ref().unwrap(), &Version::HTTP_11 ); - /// - /// req = req.version(Version::HTTP_2); - /// assert_eq!(req.version_ref().unwrap(), &Version::HTTP_2 ); - /// ``` - pub fn version_ref(&self) -> Option<&Version> { - self.inner.as_ref().ok().map(|h| &h.version) - } - - /// Appends a header to this request builder. - /// - /// This function will append the provided key/value as a header to the - /// internal `HeaderMap` being constructed. Essentially this is equivalent - /// to calling `HeaderMap::append`. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// # use http::header::HeaderValue; - /// - /// let req = Request::builder() - /// .header("Accept", "text/html") - /// .header("X-Custom-Foo", "bar") - /// .body(()) - /// .unwrap(); - /// ``` - pub fn header<K, V>(self, key: K, value: V) -> Builder - where - K: TryInto<HeaderName>, - <K as TryInto<HeaderName>>::Error: Into<crate::Error>, - V: TryInto<HeaderValue>, - <V as TryInto<HeaderValue>>::Error: Into<crate::Error>, - { - self.and_then(move |mut head| { - let name = key.try_into().map_err(Into::into)?; - let value = value.try_into().map_err(Into::into)?; - head.headers.try_append(name, value)?; - Ok(head) - }) - } - - /// Get header on this request builder. - /// when builder has error returns None - /// - /// # Example - /// - /// ``` - /// # use http::Request; - /// let req = Request::builder() - /// .header("Accept", "text/html") - /// .header("X-Custom-Foo", "bar"); - /// let headers = req.headers_ref().unwrap(); - /// assert_eq!( headers["Accept"], "text/html" ); - /// assert_eq!( headers["X-Custom-Foo"], "bar" ); - /// ``` - pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> { - self.inner.as_ref().ok().map(|h| &h.headers) - } - - /// Get headers on this request builder. - /// - /// When builder has error returns None. - /// - /// # Example - /// - /// ``` - /// # use http::{header::HeaderValue, Request}; - /// let mut req = Request::builder(); - /// { - /// let headers = req.headers_mut().unwrap(); - /// headers.insert("Accept", HeaderValue::from_static("text/html")); - /// headers.insert("X-Custom-Foo", HeaderValue::from_static("bar")); - /// } - /// let headers = req.headers_ref().unwrap(); - /// assert_eq!( headers["Accept"], "text/html" ); - /// assert_eq!( headers["X-Custom-Foo"], "bar" ); - /// ``` - pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> { - self.inner.as_mut().ok().map(|h| &mut h.headers) - } - - /// Adds an extension to this builder - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// - /// let req = Request::builder() - /// .extension("My Extension") - /// .body(()) - /// .unwrap(); - /// - /// assert_eq!(req.extensions().get::<&'static str>(), - /// Some(&"My Extension")); - /// ``` - pub fn extension<T>(self, extension: T) -> Builder - where - T: Clone + Any + Send + Sync + 'static, - { - self.and_then(move |mut head| { - head.extensions.insert(extension); - Ok(head) - }) - } - - /// Get a reference to the extensions for this request builder. - /// - /// If the builder has an error, this returns `None`. - /// - /// # Example - /// - /// ``` - /// # use http::Request; - /// let req = Request::builder().extension("My Extension").extension(5u32); - /// let extensions = req.extensions_ref().unwrap(); - /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension")); - /// assert_eq!(extensions.get::<u32>(), Some(&5u32)); - /// ``` - pub fn extensions_ref(&self) -> Option<&Extensions> { - self.inner.as_ref().ok().map(|h| &h.extensions) - } - - /// Get a mutable reference to the extensions for this request builder. - /// - /// If the builder has an error, this returns `None`. - /// - /// # Example - /// - /// ``` - /// # use http::Request; - /// let mut req = Request::builder().extension("My Extension"); - /// let mut extensions = req.extensions_mut().unwrap(); - /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension")); - /// extensions.insert(5u32); - /// assert_eq!(extensions.get::<u32>(), Some(&5u32)); - /// ``` - pub fn extensions_mut(&mut self) -> Option<&mut Extensions> { - self.inner.as_mut().ok().map(|h| &mut h.extensions) - } - - /// "Consumes" this builder, using the provided `body` to return a - /// constructed `Request`. - /// - /// # Errors - /// - /// This function may return an error if any previously configured argument - /// failed to parse or get converted to the internal representation. For - /// example if an invalid `head` was specified via `header("Foo", - /// "Bar\r\n")` the error will be returned when this function is called - /// rather than when `header` was called. - /// - /// # Examples - /// - /// ``` - /// # use http::*; - /// - /// let request = Request::builder() - /// .body(()) - /// .unwrap(); - /// ``` - pub fn body<T>(self, body: T) -> Result<Request<T>> { - self.inner.map(move |head| Request { head, body }) - } - - // private - - fn and_then<F>(self, func: F) -> Self - where - F: FnOnce(Parts) -> Result<Parts>, - { - Builder { - inner: self.inner.and_then(func), - } - } -} - -impl Default for Builder { - #[inline] - fn default() -> Builder { - Builder { - inner: Ok(Parts::new()), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_can_map_a_body_from_one_type_to_another() { - let request = Request::builder().body("some string").unwrap(); - let mapped_request = request.map(|s| { - assert_eq!(s, "some string"); - 123u32 - }); - assert_eq!(mapped_request.body(), &123u32); - } -} |
