Skip to content

Commit 8541a80

Browse files
committed
feat: add request guard for accessing HTTP headers in routes
1 parent 3101e0f commit 8541a80

File tree

1 file changed

+74
-1
lines changed

1 file changed

+74
-1
lines changed

src/visualization/server.rs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,16 @@ use base64::Engine;
5757
use include_dir::{include_dir, Dir};
5858
use rocket::fairing::{Fairing, Info, Kind};
5959
use rocket::figment::Figment;
60-
use rocket::http::{ContentType, Header};
60+
use rocket::http::{ContentType, Header, HeaderMap};
61+
use rocket::request::FromRequest;
6162
use rocket::response::{Redirect, Responder};
6263
use rocket::{async_trait, get, options, routes, uri, Build, Rocket};
6364
use rocket::{Request, Response};
6465
use rocket_okapi::{openapi, openapi_get_routes, rapidoc::*, settings::UrlObject};
6566
use std::env;
67+
use std::fmt::Debug;
6668
use std::io::Cursor;
69+
use std::ops::Deref;
6770
use std::path::PathBuf;
6871

6972
use super::oxide_auth::OxideState;
@@ -107,6 +110,76 @@ impl<'r> Responder<'r, 'r> for StaticFileResponse {
107110
}
108111
}
109112

113+
/// Request guard for accessing HTTP headers in a route
114+
///
115+
/// This struct acts as a wrapper around Rocket's `HeaderMap`, providing a
116+
/// type-safe way to access the HTTP headers of an incoming request. It can be
117+
/// used directly as a parameter in route handlers to access all request headers.
118+
///
119+
/// # Usage in Routes
120+
///
121+
/// ```
122+
/// use rocket::get;
123+
/// use rust_photoacoustic::visualization::server::Headers;
124+
/// #[get("/example")]
125+
/// fn example_route(headers: Headers<'_>) -> String {
126+
/// // Check if a specific header exists
127+
/// let has_auth = headers.contains("Authorization");
128+
///
129+
/// // Get a specific header value
130+
/// let user_agent = headers.get_one("User-Agent").unwrap_or("Unknown");
131+
///
132+
/// format!("Has Auth: {}, User-Agent: {}", has_auth, user_agent)
133+
/// }
134+
/// ```
135+
///
136+
/// # Implementation Details
137+
///
138+
/// This struct implements Rocket's `FromRequest` trait, allowing it to be used
139+
/// as a request guard in route handlers. When a route with this parameter is invoked,
140+
/// Rocket will automatically extract the request headers and make them available
141+
/// through this struct.
142+
pub struct Headers<'r>(pub &'r HeaderMap<'r>);
143+
144+
impl<'r> Deref for Headers<'r> {
145+
type Target = HeaderMap<'r>;
146+
147+
fn deref(&self) -> &Self::Target {
148+
self.0
149+
}
150+
}
151+
152+
#[rocket::async_trait]
153+
impl<'r> FromRequest<'r> for Headers<'r> {
154+
type Error = ();
155+
156+
/// Extracts the HTTP headers from the request
157+
///
158+
/// This implementation always succeeds and provides access to the request's
159+
/// headers through the `Headers` struct.
160+
///
161+
/// # Parameters
162+
///
163+
/// * `req` - The incoming HTTP request
164+
///
165+
/// # Returns
166+
///
167+
/// A successful outcome containing the headers from the request
168+
async fn from_request(req: &'r Request<'_>) -> rocket::request::Outcome<Self, Self::Error> {
169+
rocket::request::Outcome::Success(Headers(req.headers()))
170+
}
171+
}
172+
173+
impl<'r> Debug for Headers<'r> {
174+
/// Formats the Headers for debug output
175+
///
176+
/// This implementation allows the Headers struct to be used with
177+
/// debug formatting macros like `println!("{:?}", headers)`.
178+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
179+
f.debug_tuple("Headers").field(self.0).finish()
180+
}
181+
}
182+
110183
/// Cross-Origin Resource Sharing (CORS) fairing for Rocket
111184
///
112185
/// This fairing adds CORS headers to all responses from the server,

0 commit comments

Comments
 (0)