Skip to main content

Request

Struct Request 

Source
pub struct Request {
    pub method: Method,
    pub uri: Uri,
    pub version: Version,
    pub headers: HeaderMap,
    pub path_params: HashMap<String, String>,
    pub query_params: HashMap<String, String>,
    pub is_secure: bool,
    pub remote_addr: Option<SocketAddr>,
    pub extensions: Extensions,
    /* private fields */
}
Expand description

HTTP Request representation

Fields§

§method: Method§uri: Uri§version: Version§headers: HeaderMap§path_params: HashMap<String, String>§query_params: HashMap<String, String>§is_secure: bool

Indicates if this request came over HTTPS

§remote_addr: Option<SocketAddr>

Remote address of the client (if available)

§extensions: Extensions

Extensions for storing arbitrary typed data

Implementations§

Source§

impl Request

Source

pub fn body(&self) -> &Bytes

Get a reference to the request body

This is a non-consuming accessor that can be called multiple times. Useful for testing and inspection purposes.

§Examples
use reinhardt_http::Request;
use hyper::Method;
use bytes::Bytes;

let body = Bytes::from("test body");
let request = Request::builder()
    .method(Method::POST)
    .uri("/")
    .body(body.clone())
    .build()
    .unwrap();

assert_eq!(request.body(), &body);
Source

pub fn json<T>(&self) -> Result<T, Error>

Parse the request body as JSON

§Examples
use reinhardt_http::Request;
use hyper::Method;
use bytes::Bytes;
use serde::Deserialize;

#[derive(Deserialize, Debug, PartialEq)]
struct User {
    name: String,
    age: u32,
}

let json_body = r#"{"name": "Alice", "age": 30}"#;
let mut headers = hyper::HeaderMap::new();
headers.insert(hyper::header::CONTENT_TYPE, "application/json".parse().unwrap());
let request = Request::builder()
    .method(Method::POST)
    .uri("/api/users")
    .headers(headers)
    .body(Bytes::from(json_body))
    .build()
    .unwrap();

let user: User = request.json().unwrap();
assert_eq!(user.name, "Alice");
assert_eq!(user.age, 30);
Source

pub fn with_parsers(self, parsers: Vec<Box<dyn Parser>>) -> Request

Set parsers for request body parsing

§Examples
use reinhardt_http::Request;
use hyper::Method;

let request = Request::builder()
    .method(Method::POST)
    .uri("/")
    .build()
    .unwrap();

let request = request.with_parsers(vec![]);
assert_eq!(request.method, Method::POST);
Source

pub fn read_body(&self) -> Result<Bytes, Error>

Read and consume the request body This marks the body as consumed and subsequent parse attempts will fail

§Examples
use reinhardt_http::Request;
use hyper::Method;
use bytes::Bytes;

let request = Request::builder()
    .method(Method::POST)
    .uri("/")
    .body(Bytes::from("request body"))
    .build()
    .unwrap();

let body = request.read_body().unwrap();
assert_eq!(body, Bytes::from("request body"));

assert!(request.read_body().is_err());
Source

pub async fn post(&self) -> Result<HashMap<String, Vec<String>>, Error>

Get POST data (form-encoded data) Returns data only if using FormParser or MultiPartParser

§Examples
use reinhardt_http::Request;
use hyper::Method;

async fn example() {
    let request = Request::builder()
        .method(Method::POST)
        .uri("/")
        .build()
        .unwrap();

    // Without parsers, returns empty HashMap
    let post_data = request.post().await.unwrap();
    assert!(post_data.is_empty());
}
Source

pub async fn data(&self) -> Result<ParsedData, Error>

Get parsed data This performs lazy parsing - only parses once and caches the result

§Examples
use reinhardt_http::Request;
use hyper::Method;

async fn example() {
    let request = Request::builder()
        .method(Method::POST)
        .uri("/")
        .build()
        .unwrap();

    // Without parsers, this will fail
    assert!(request.data().await.is_err());
}
Source§

impl Request

Source

pub fn is_secure(&self) -> bool

Returns true if the request was made over HTTPS

This can be determined either by:

  1. The actual connection being TLS (is_secure flag)
  2. X-Forwarded-Proto header indicating HTTPS (only from trusted proxies)
§Examples
use reinhardt_http::{Request, TrustedProxies};
use hyper::Method;
use std::net::{SocketAddr, IpAddr, Ipv4Addr};

// Direct HTTPS connection
let request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .secure(true)
    .build()
    .unwrap();
assert!(request.is_secure());

// Behind trusted reverse proxy
let proxy_ip = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1));
let mut headers = hyper::HeaderMap::new();
headers.insert("x-forwarded-proto", "https".parse().unwrap());
let request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .headers(headers)
    .remote_addr(SocketAddr::new(proxy_ip, 8080))
    .build()
    .unwrap();
request.set_trusted_proxies(TrustedProxies::new(vec![proxy_ip]));
assert!(request.is_secure());
Source

pub fn scheme(&self) -> &str

Returns the scheme of the request (http or https)

§Examples
use reinhardt_http::Request;
use hyper::{Method, Uri, Version, HeaderMap};
use bytes::Bytes;

let request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .secure(true)
    .build()
    .unwrap();
assert_eq!(request.scheme(), "https");

let request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .build()
    .unwrap();
assert_eq!(request.scheme(), "http");
Source

pub fn build_absolute_uri(&self, path: Option<&str>) -> String

Build an absolute URI for the request

Example: “https://example.com:8000/path?query=value

§Examples
use reinhardt_http::Request;
use hyper::{Method, Uri, Version, HeaderMap};
use bytes::Bytes;

let mut headers = hyper::HeaderMap::new();
headers.insert("host", "example.com".parse().unwrap());

let request = Request::builder()
    .method(Method::GET)
    .uri("/api/users")
    .headers(headers)
    .secure(true)
    .build()
    .unwrap();

let uri = request.build_absolute_uri(None);
assert_eq!(uri, "https://example.com/api/users");

let uri = request.build_absolute_uri(Some("/other/path"));
assert_eq!(uri, "https://example.com/other/path");
Source§

impl Request

Source

pub fn path(&self) -> &str

Get the request path

§Examples
use reinhardt_http::Request;
use hyper::Method;

let request = Request::builder()
    .method(Method::GET)
    .uri("/api/users")
    .build()
    .unwrap();

assert_eq!(request.path(), "/api/users");
Source

pub fn decoded_query_params(&self) -> HashMap<String, String>

Get URL-decoded query parameters

Returns a new HashMap with all query parameter keys and values URL-decoded. This is useful when query parameters contain special characters or Unicode.

§Examples
use reinhardt_http::Request;
use hyper::Method;

let request = Request::builder()
    .method(Method::GET)
    .uri("/test?name=John%20Doe")
    .build()
    .unwrap();

let decoded = request.decoded_query_params();
assert_eq!(decoded.get("name"), Some(&"John Doe".to_string()));
Source

pub fn set_path_param( &mut self, key: impl Into<String>, value: impl Into<String>, )

Set a path parameter (used by routers for path variable extraction)

This method is typically called by routers when extracting path parameters from URL patterns like /users/{id}/.

§Examples
use reinhardt_http::Request;
use hyper::{Method, Uri, Version, HeaderMap};
use bytes::Bytes;

let mut request = Request::builder()
    .method(Method::GET)
    .uri("/users/123")
    .build()
    .unwrap();

request.set_path_param("id", "123");
assert_eq!(request.path_params.get("id"), Some(&"123".to_string()));
Source

pub fn get_accepted_languages(&self) -> Vec<(String, f32)>

Parse Accept-Language header and return ordered list of language codes

Returns languages sorted by quality value (q parameter), highest first. Example: “en-US,en;q=0.9,ja;q=0.8” -> [“en-US”, “en”, “ja”]

§Examples
use reinhardt_http::Request;
use hyper::{Method, Uri, Version, HeaderMap};
use bytes::Bytes;

let mut headers = HeaderMap::new();
headers.insert("accept-language", "en-US,en;q=0.9,ja;q=0.8".parse().unwrap());

let request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .headers(headers)
    .build()
    .unwrap();

let languages = request.get_accepted_languages();
assert_eq!(languages[0].0, "en-US");
assert_eq!(languages[0].1, 1.0);
assert_eq!(languages[1].0, "en");
assert_eq!(languages[1].1, 0.9);
Source

pub fn get_preferred_language(&self) -> Option<String>

Get the most preferred language from Accept-Language header

§Examples
use reinhardt_http::Request;
use hyper::{Method, Uri, Version, HeaderMap};
use bytes::Bytes;

let mut headers = HeaderMap::new();
headers.insert("accept-language", "ja;q=0.8,en-US,en;q=0.9".parse().unwrap());

let request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .headers(headers)
    .build()
    .unwrap();

assert_eq!(request.get_preferred_language(), Some("en-US".to_string()));

Get language from cookie

Looks for a language cookie (typically named “reinhardt_language” or similar)

§Examples
use reinhardt_http::Request;
use hyper::{Method, Uri, Version, HeaderMap};
use bytes::Bytes;

let mut headers = HeaderMap::new();
headers.insert("cookie", "session_id=abc123; language=ja; theme=dark".parse().unwrap());

let request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .headers(headers)
    .build()
    .unwrap();

assert_eq!(request.get_language_from_cookie("language"), Some("ja".to_string()));
assert_eq!(request.get_language_from_cookie("nonexistent"), None);
Source§

impl Request

Source

pub fn builder() -> RequestBuilder

Create a new RequestBuilder.

§Examples
use reinhardt_http::Request;
use hyper::Method;

let request = Request::builder()
    .method(Method::GET)
    .uri("/api/users")
    .build()
    .unwrap();

assert_eq!(request.method, Method::GET);
Source

pub fn set_di_context<T>(&mut self, ctx: T)
where T: Send + Sync + 'static,

Set the DI context for this request (used by routers with dependency injection)

This method stores the DI context in the request’s extensions, allowing handlers to access dependency injection services.

The context will be wrapped in an Arc internally for efficient sharing. The DI context type is generic to avoid circular dependencies.

§Examples
use reinhardt_http::Request;
use hyper::Method;

let mut request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .build()
    .unwrap();

let di_ctx = DummyDiContext;
request.set_di_context(di_ctx);
Source

pub fn get_di_context<T>(&self) -> Option<Arc<T>>
where T: Send + Sync + 'static,

Get the DI context from this request

Returns None if no DI context was set.

The DI context type is generic to avoid circular dependencies. Returns a reference to the context.

§Examples
use reinhardt_http::Request;
use hyper::Method;

let mut request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .build()
    .unwrap();

let di_ctx = DummyDiContext;
request.set_di_context(di_ctx);

let ctx = request.get_di_context::<DummyDiContext>();
assert!(ctx.is_some());
Source

pub fn extract_bearer_token(&self) -> Option<String>

Extract Bearer token from Authorization header

Extracts JWT or other bearer tokens from the Authorization header. Returns None if the header is missing or not in “Bearer <token>” format.

§Examples
use reinhardt_http::Request;
use hyper::{Method, Version, HeaderMap, header};
use bytes::Bytes;

let mut headers = HeaderMap::new();
headers.insert(
    header::AUTHORIZATION,
    "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9".parse().unwrap()
);

let request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .version(Version::HTTP_11)
    .headers(headers)
    .body(Bytes::new())
    .build()
    .unwrap();

let token = request.extract_bearer_token();
assert_eq!(token, Some("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9".to_string()));
§Missing or invalid header
use reinhardt_http::Request;
use hyper::{Method, Version, HeaderMap};
use bytes::Bytes;

let request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .version(Version::HTTP_11)
    .headers(HeaderMap::new())
    .body(Bytes::new())
    .build()
    .unwrap();

let token = request.extract_bearer_token();
assert_eq!(token, None);
Source

pub fn get_header(&self, name: &str) -> Option<String>

Get a specific header value from the request

Returns None if the header is missing or cannot be converted to a string.

§Examples
use reinhardt_http::Request;
use hyper::{Method, Version, HeaderMap, header};
use bytes::Bytes;

let mut headers = HeaderMap::new();
headers.insert(
    header::USER_AGENT,
    "Mozilla/5.0".parse().unwrap()
);

let request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .version(Version::HTTP_11)
    .headers(headers)
    .body(Bytes::new())
    .build()
    .unwrap();

let user_agent = request.get_header("user-agent");
assert_eq!(user_agent, Some("Mozilla/5.0".to_string()));
§Missing header
use reinhardt_http::Request;
use hyper::{Method, Version, HeaderMap};
use bytes::Bytes;

let request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .version(Version::HTTP_11)
    .headers(HeaderMap::new())
    .body(Bytes::new())
    .build()
    .unwrap();

let header = request.get_header("x-custom-header");
assert_eq!(header, None);
Source

pub fn get_client_ip(&self) -> Option<IpAddr>

Extract client IP address from the request

Only trusts proxy headers (X-Forwarded-For, X-Real-IP) when the request originates from a configured trusted proxy. Without trusted proxies, falls back to the actual connection address.

§Examples
use reinhardt_http::{Request, TrustedProxies};
use hyper::{Method, Version, HeaderMap, header};
use bytes::Bytes;
use std::net::{SocketAddr, IpAddr, Ipv4Addr};

let proxy_ip = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1));
let mut headers = HeaderMap::new();
headers.insert(
    header::HeaderName::from_static("x-forwarded-for"),
    "203.0.113.1, 198.51.100.1".parse().unwrap()
);

let request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .version(Version::HTTP_11)
    .headers(headers)
    .remote_addr(SocketAddr::new(proxy_ip, 8080))
    .body(Bytes::new())
    .build()
    .unwrap();

// Configure trusted proxies to honor X-Forwarded-For
request.set_trusted_proxies(TrustedProxies::new(vec![proxy_ip]));

let ip = request.get_client_ip();
assert_eq!(ip, Some("203.0.113.1".parse().unwrap()));
§No trusted proxy, fallback to remote_addr
use reinhardt_http::Request;
use hyper::{Method, Version, HeaderMap};
use bytes::Bytes;
use std::net::{SocketAddr, IpAddr, Ipv4Addr};

let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
let request = Request::builder()
    .method(Method::GET)
    .uri("/")
    .version(Version::HTTP_11)
    .headers(HeaderMap::new())
    .remote_addr(addr)
    .body(Bytes::new())
    .build()
    .unwrap();

let ip = request.get_client_ip();
assert_eq!(ip, Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))));
Source

pub fn set_trusted_proxies(&self, proxies: TrustedProxies)

Set trusted proxy configuration for this request.

This is typically called by the server/middleware layer to configure which proxy IPs are trusted for header forwarding.

Source

pub fn validate_content_type(&self, expected: &str) -> Result<(), Error>

Validate Content-Type header

Checks if the Content-Type header matches the expected value. Returns an error if the header is missing or doesn’t match.

§Examples
use reinhardt_http::Request;
use hyper::{Method, Version, HeaderMap, header};
use bytes::Bytes;

let mut headers = HeaderMap::new();
headers.insert(
    header::CONTENT_TYPE,
    "application/json".parse().unwrap()
);

let request = Request::builder()
    .method(Method::POST)
    .uri("/")
    .version(Version::HTTP_11)
    .headers(headers)
    .body(Bytes::new())
    .build()
    .unwrap();

assert!(request.validate_content_type("application/json").is_ok());
§Content-Type mismatch
use reinhardt_http::Request;
use hyper::{Method, Version, HeaderMap, header};
use bytes::Bytes;

let mut headers = HeaderMap::new();
headers.insert(
    header::CONTENT_TYPE,
    "text/plain".parse().unwrap()
);

let request = Request::builder()
    .method(Method::POST)
    .uri("/")
    .version(Version::HTTP_11)
    .headers(headers)
    .body(Bytes::new())
    .build()
    .unwrap();

let result = request.validate_content_type("application/json");
assert!(result.is_err());
§Missing Content-Type header
use reinhardt_http::Request;
use hyper::{Method, Version, HeaderMap};
use bytes::Bytes;

let request = Request::builder()
    .method(Method::POST)
    .uri("/")
    .version(Version::HTTP_11)
    .headers(HeaderMap::new())
    .body(Bytes::new())
    .build()
    .unwrap();

let result = request.validate_content_type("application/json");
assert!(result.is_err());
Source

pub fn query_as<T>(&self) -> Result<T, Error>

Parse query parameters into typed struct

Deserializes query string parameters into the specified type T. Returns an error if deserialization fails.

§Examples
use reinhardt_http::Request;
use hyper::{Method, Version, HeaderMap};
use bytes::Bytes;
use serde::Deserialize;

#[derive(Deserialize, Debug, PartialEq)]
struct Pagination {
    page: u32,
    limit: u32,
}

let request = Request::builder()
    .method(Method::GET)
    .uri("/api/users?page=2&limit=10")
    .version(Version::HTTP_11)
    .headers(HeaderMap::new())
    .body(Bytes::new())
    .build()
    .unwrap();

let params: Pagination = request.query_as().unwrap();
assert_eq!(params, Pagination { page: 2, limit: 10 });
§Type mismatch error
use reinhardt_http::Request;
use hyper::{Method, Version, HeaderMap};
use bytes::Bytes;
use serde::Deserialize;

#[derive(Deserialize)]
struct Pagination {
    page: u32,
    limit: u32,
}

let request = Request::builder()
    .method(Method::GET)
    .uri("/api/users?page=invalid")
    .version(Version::HTTP_11)
    .headers(HeaderMap::new())
    .body(Bytes::new())
    .build()
    .unwrap();

let result: Result<Pagination, _> = request.query_as();
assert!(result.is_err());

Trait Implementations§

Source§

impl RequestVersionExt for Request

Source§

fn version(&self) -> Option<String>

Get the API version from request extensions
Source§

fn version_or(&self, default: &str) -> String

Get the API version or return default

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Any for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Source§

fn type_name(&self) -> &'static str

Source§

impl<T> AnySync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Chain<T> for T

Source§

fn len(&self) -> usize

The number of items that this chain link consists of.
Source§

fn append_to(self, v: &mut Vec<T>)

Append the elements in this link to the chain.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more