Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions examples/hello/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ mod fangs {
pub struct SetServer;
impl FangAction for SetServer {
fn back<'a>(&'a self, res: &'a mut Response) -> impl std::future::Future<Output = ()> + Send {
res.headers.set()
.Server("ohkami");
res.headers.set().server("ohkami");

tracing::info!("\
Called `SetServer`\n\
Expand Down
2 changes: 1 addition & 1 deletion examples/html_layout/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl Layout {

impl FangAction for Fang {
async fn back(&self, res: &mut Response) {
if res.headers.ContentType().is_some_and(|x| x.starts_with("text/html")) {
if res.headers.content_type().is_some_and(|x| x.starts_with("text/html")) {
let content = res.drop_content().into_bytes().unwrap();
let content = std::str::from_utf8(&*content).unwrap();
res.set_html(uibeam::shoot(UI! {
Expand Down
4 changes: 2 additions & 2 deletions ohkami/src/fang/builtin/basicauth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ where
const _: () = {
fn unauthorized() -> Response {
Response::Unauthorized().with_headers(|h|h
.WWWAuthenticate("Basic realm=\"Secure Area\"")
.www_authenticate("Basic realm=\"Secure Area\"")
)
}

#[inline]
fn basic_credential_of(req: &Request) -> Result<String, Response> {
(|| crate::util::base64_decode_utf8(
req.headers.Authorization()?.strip_prefix("Basic ")?
req.headers.authorization()?.strip_prefix("Basic ")?
).ok())().ok_or_else(unauthorized)
}

Expand Down
61 changes: 19 additions & 42 deletions ohkami/src/fang/builtin/cors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ use crate::{header::append, Fang, FangProc, Request, Response, Status};
/// ```
#[derive(Clone)]
pub struct Cors {
pub(crate) allow_origin: AccessControlAllowOrigin,
/* pub(crate) allow_methods: Option<String>, // owe to `Handler::default_not_found()` */
pub(crate) allow_origin: AccessControlAllowOrigin,
pub(crate) allow_credentials: bool,
pub(crate) allow_methods: Option<String>,
pub(crate) allow_headers: Option<String>,
pub(crate) expose_headers: Option<String>,
pub(crate) max_age: Option<u32>,
pub(crate) allow_headers: Option<String>,
pub(crate) expose_headers: Option<String>,
pub(crate) max_age: Option<u32>,
}

#[derive(Clone)]
Expand Down Expand Up @@ -69,22 +69,12 @@ impl Cors {
Self {
allow_origin: AccessControlAllowOrigin::from_literal(origin),
allow_credentials: false,
allow_methods: None,
allow_headers: None,
expose_headers: None,
max_age: None,
}
}

/* Always use default for now...
/// Override `Access-Control-Allow-Methods` header value, it's default to
/// all available methods on the request path.
pub fn allow_methods<const N: usize>(mut self, methods: [Method; N]) -> Self {
self.allow_methods = Some(methods.map(|m| m.as_str()).join(", "));
self
}
*/

pub fn allow_credentials(mut self, yes: bool) -> Self {
if yes {
if self.allow_origin.is_any() {
Expand Down Expand Up @@ -131,37 +121,24 @@ impl<Inner: FangProc> FangProc for CORSProc<Inner> {
async fn bite<'b>(&'b self, req: &'b mut Request) -> Response {
let mut res = self.inner.bite(req).await;

let mut h = res.headers.set();

h = h.AccessControlAllowOrigin(self.cors.allow_origin.as_str());
if self.cors.allow_origin.is_any() {
h = h.Vary("Origin");
}
if self.cors.allow_credentials {
h = h.AccessControlAllowCredentials("true");
}
if let Some(expose_headers) = &self.cors.expose_headers {
h = h.AccessControlExposeHeaders(expose_headers.to_string());
}

res.headers.set()
.access_control_allow_origin(self.cors.allow_origin.as_str())
.vary(self.cors.allow_origin.is_any().then_some("Origin".into()))
.access_control_allow_credentials(self.cors.allow_credentials.then_some("true".into()))
.access_control_expose_headers(self.cors.expose_headers.as_ref().map(|s| s.to_string().into()));
if req.method.isOPTIONS() {
if let Some(max_age) = self.cors.max_age {
h = h.AccessControlMaxAge(max_age.to_string());
}
if let Some(allow_methods) = &self.cors.allow_methods {
h = h.AccessControlAllowMethods(allow_methods.to_string());
res.headers.set()
.access_control_max_age(self.cors.max_age.map(|v| v.to_string().into()));
if let Some(allow_headers) = self.cors.allow_headers.as_ref() && !allow_headers.is_empty() {
res.headers.set()
.access_control_allow_headers(allow_headers.to_string())
.vary(append("Access-Control-Request-Headers"));
}
if let Some(allow_headers) = self.cors.allow_headers.as_deref()
.or_else(|| req.headers.AccessControlRequestHeaders())
{
h = h.AccessControlAllowHeaders(allow_headers.to_string())
.Vary(append("Access-Control-Request-Headers"));
}

/* override default `Not Implemented` response for valid preflight */
if res.status == Status::NotImplemented {
// override default `NotImplemented` response for valid preflight.
// see `Handler::default_not_found()`.
res.status = Status::OK;
h.ContentType(None).ContentLength(None);
res.headers.set().content_type(None).content_length(None);
}
}

Expand Down
19 changes: 9 additions & 10 deletions ohkami/src/fang/builtin/enamel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
/// )).howl("localhost:4040").await
/// }
/// ```
pub struct Enamel(
pub struct Enamel(// clone in `Fang::chain`
std::sync::Arc<EnamelFields>
);
#[allow(non_snake_case)]
Expand Down Expand Up @@ -124,30 +124,29 @@ const _: () = {

impl Enamel {
fn apply(&self, res: &mut crate::Response) {
let mut h = res.headers.set();
if let Some(csp) = &self.0.content_security_policy {
h = h.ContentSecurityPolicy(csp.build());
res.headers.set().content_security_policy(csp.build());
}
if let Some(csp) = &self.0.content_security_policy_report_only {
h = h.ContentSecurityPolicyReportOnly(csp.build());
res.headers.set().content_security_policy_report_only(csp.build());
}
if !self.0.cross_origin_embedder_policy.is_empty() {
h = h.CrossOriginEmbedderPolicy(self.0.cross_origin_embedder_policy);
res.headers.set().cross_origin_embedder_policy(self.0.cross_origin_embedder_policy);
}
if !self.0.corss_origin_resource_policy.is_empty() {
h = h.CrossOriginResourcePolicy(self.0.corss_origin_resource_policy);
res.headers.set().cross_origin_resource_policy(self.0.corss_origin_resource_policy);
}
if !self.0.referrer_policy.is_empty() {
h = h.ReferrerPolicy(self.0.referrer_policy);
res.headers.set().referrer_policy(self.0.referrer_policy);
}
if !self.0.strict_transport_security.is_empty() {
h = h.StrictTransportSecurity(self.0.strict_transport_security);
res.headers.set().strict_transport_security(self.0.strict_transport_security);
}
if !self.0.x_content_type_options.is_empty() {
h = h.XContentTypeOptions(self.0.x_content_type_options);
res.headers.set().x_content_type_options(self.0.x_content_type_options);
}
if !self.0.x_frame_options.is_empty() {
h.XFrameOptions(self.0.x_frame_options);
res.headers.set().x_frame_options(self.0.x_frame_options);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions ohkami/src/fang/builtin/jwt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl<Payload> Jwt<Payload> {

/// Customize get-token process in JWT verifying.
///
/// *default*: `req.headers.Authorization()?.strip_prefix("Bearer ")`
/// *default*: `req.headers.authorization()?.strip_prefix("Bearer ")`
pub fn get_token_by(
mut self,
get_token: fn(&Request)->Option<&str>,
Expand All @@ -198,7 +198,7 @@ impl<Payload> Jwt<Payload> {
fn new(alg: VerifyingAlgorithm, secret: impl Into<Cow<'static, str>>) -> Self {
#[inline(always)]
fn get_token(req: &Request) -> Option<&str> {
req.headers.Authorization()?.strip_prefix("Bearer ")
req.headers.authorization()?.strip_prefix("Bearer ")
}

Self {
Expand Down
18 changes: 10 additions & 8 deletions ohkami/src/fang/handler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,25 +84,27 @@ impl Handler {
}
}

pub(crate) fn default_options_with(mut available_methods: Vec<&'static str>) -> Self {
pub(crate) fn default_options_with(available_methods: Vec<&'static str>) -> Self {
let available_methods: &'static [&'static str] = {
if available_methods.contains(&"GET") {
available_methods.push("HEAD")
let mut methods = available_methods;
if methods.contains(&"GET") {
methods.push("HEAD")
}
available_methods.push("OPTIONS");
available_methods
methods.push("OPTIONS");
methods
}.leak();

let available_methods_str: &'static str =
available_methods.join(", ").leak();

/* see `fang::Cors` for more detail about what to do here */
Handler::new(move |req| {
Box::pin(async move {
#[cfg(debug_assertions)] {
assert_eq!(req.method, crate::Method::OPTIONS);
}

match req.headers.AccessControlRequestMethod() {
match req.headers.access_control_request_method() {
Some(method) => {
/*
Ohkami, by default, does nothing more than setting
Expand All @@ -116,7 +118,7 @@ impl Handler {
} else {
crate::Response::BadRequest()
}).with_headers(|h| h
.AccessControlAllowMethods(available_methods_str)
.access_control_allow_methods(available_methods_str)
)
}
None => {
Expand All @@ -127,7 +129,7 @@ impl Handler {
```
crate::Response::NoContent()
.with_headers(|h| h
.Allow(available_methods_str)
.allow(available_methods_str)
)
```
*/
Expand Down
5 changes: 2 additions & 3 deletions ohkami/src/header/append.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::borrow::Cow;

pub struct Append(pub(crate) Cow<'static, str>);

/// Passed to `{Request/Response}.headers.set().Name( 〜 )` and
/// Passed to `{Request/Response}.headers.set().{name}( 〜 )` and
/// append `value` to the header.
///
/// Here appended values are combined by `,`.
Expand All @@ -18,8 +18,7 @@ pub struct Append(pub(crate) Cow<'static, str>);
/// struct AppendServer(&'static str);
/// impl FangAction for AppendServer {
/// async fn back<'b>(&'b self, res: &'b mut Response) {
/// res.headers.set()
/// .Server(append(self.0));
/// res.headers.set().server(append(self.0));
/// }
/// }
///
Expand Down
Loading