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: boolIndicates if this request came over HTTPS
remote_addr: Option<SocketAddr>Remote address of the client (if available)
extensions: ExtensionsExtensions for storing arbitrary typed data
Implementations§
Source§impl Request
impl Request
Sourcepub fn body(&self) -> &Bytes
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);Sourcepub fn json<T>(&self) -> Result<T, Error>where
T: DeserializeOwned,
pub fn json<T>(&self) -> Result<T, Error>where
T: DeserializeOwned,
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);Sourcepub fn with_parsers(self, parsers: Vec<Box<dyn Parser>>) -> Request
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);Sourcepub fn read_body(&self) -> Result<Bytes, Error>
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());Sourcepub async fn post(&self) -> Result<HashMap<String, Vec<String>>, Error>
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());
}Sourcepub async fn data(&self) -> Result<ParsedData, Error>
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
impl Request
Sourcepub fn is_secure(&self) -> bool
pub fn is_secure(&self) -> bool
Returns true if the request was made over HTTPS
This can be determined either by:
- The actual connection being TLS (is_secure flag)
- 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());Sourcepub fn scheme(&self) -> &str
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");Sourcepub fn build_absolute_uri(&self, path: Option<&str>) -> String
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
impl Request
Sourcepub fn path(&self) -> &str
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");Sourcepub fn decoded_query_params(&self) -> HashMap<String, String>
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()));Sourcepub fn set_path_param(
&mut self,
key: impl Into<String>,
value: impl Into<String>,
)
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()));Sourcepub fn get_accepted_languages(&self) -> Vec<(String, f32)>
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);Sourcepub fn get_preferred_language(&self) -> Option<String>
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
impl Request
Sourcepub fn builder() -> RequestBuilder
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);Sourcepub fn set_di_context<T>(&mut self, ctx: T)
pub fn set_di_context<T>(&mut self, ctx: T)
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);Sourcepub fn get_di_context<T>(&self) -> Option<Arc<T>>
pub fn get_di_context<T>(&self) -> Option<Arc<T>>
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());Sourcepub fn extract_bearer_token(&self) -> Option<String>
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);Sourcepub fn get_header(&self, name: &str) -> Option<String>
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);Sourcepub fn get_client_ip(&self) -> Option<IpAddr>
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))));Sourcepub fn set_trusted_proxies(&self, proxies: TrustedProxies)
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.
Sourcepub fn validate_content_type(&self, expected: &str) -> Result<(), Error>
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());Sourcepub fn query_as<T>(&self) -> Result<T, Error>where
T: DeserializeOwned,
pub fn query_as<T>(&self) -> Result<T, Error>where
T: DeserializeOwned,
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§
Auto Trait Implementations§
impl !Freeze for Request
impl !RefUnwindSafe for Request
impl Send for Request
impl Sync for Request
impl Unpin for Request
impl UnsafeUnpin for Request
impl !UnwindSafe for Request
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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