Skip to content

Commit

Permalink
Extensions use no Unsafe code. You'll have to add types to your exten…
Browse files Browse the repository at this point in the history
…sion macro invocations.
  • Loading branch information
Icelk committed Apr 1, 2022
1 parent 2fc6d4c commit 83b5d10
Show file tree
Hide file tree
Showing 6 changed files with 380 additions and 374 deletions.
64 changes: 42 additions & 22 deletions extensions/src/push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,31 @@ use crate::*;
/// [`SmartPush::default`]), not every time.
pub fn mount(extensions: &mut Extensions, manager: SmartPush) -> &mut Extensions {
let manager = Mutex::new(manager);
struct PushPost {
mutex: Mutex<SmartPush>,
}
impl extensions::PostCall for PushPost {
fn call<'a>(
&'a self,
request: &'a Request<application::Body>,
host: &'a Host,
response_pipe: &'a mut application::ResponsePipe,
identity_body: Bytes,
addr: SocketAddr,
) -> RetFutA<'a, ()> {
push(
request,
host,
response_pipe,
identity_body,
addr,
Some(&self.mutex),
)
}
}

extensions.add_post(
Box::new(move |request, host, response_pipe, bytes, addr| {
let manager = unsafe { utils::SuperUnsafePointer::new(&manager) };
push(request, host, response_pipe, bytes, addr, Some(manager))
}),
Box::new(PushPost { mutex: manager }),
Id::new(-32, "HTTP/2 push"),
);
extensions
Expand All @@ -32,13 +52,13 @@ pub fn mount(extensions: &mut Extensions, manager: SmartPush) -> &mut Extensions
/// Id::new(-32, "HTTP/2 push"),
/// );
/// ```
pub fn always(
request: RequestWrapper,
host: HostWrapper,
response_pipe: ResponsePipeWrapperMut,
pub fn always<'a>(
request: &'a Request<application::Body>,
host: &'a Host,
response_pipe: &'a mut application::ResponsePipe,
bytes: Bytes,
addr: SocketAddr,
) -> RetFut<()> {
) -> RetFutA<'a, ()> {
push(request, host, response_pipe, bytes, addr, None)
}

Expand Down Expand Up @@ -86,27 +106,27 @@ impl Default for SmartPush {
}
}

fn push(
request: RequestWrapper,
host: HostWrapper,
mut response_pipe: ResponsePipeWrapperMut,
fn push<'a>(
request: &'a Request<application::Body>,
host: &'a Host,
response_pipe: &'a mut application::ResponsePipe,
bytes: Bytes,
addr: SocketAddr,
manager: Option<utils::SuperUnsafePointer<Mutex<SmartPush>>>,
) -> RetFut<()> {
manager: Option<&'a Mutex<SmartPush>>,
) -> RetFutA<'a, ()> {
use internals::*;
Box::pin(async move {
let request = unsafe { request.get_inner() };
let response_pipe = unsafe { response_pipe.get_inner() };
// let request = unsafe { request.get_inner() };
// let response_pipe = unsafe { response_pipe.get_inner() };

// If it is not HTTP/1
#[allow(irrefutable_let_patterns)]
if let ResponsePipe::Http1(_) = &response_pipe {
return;
}

if let Some(manager) = manager.as_ref() {
let manager = unsafe { manager.get() };
if let Some(manager) = manager {
// let manager = unsafe { manager.get() };
let mut lock = manager.lock().await;
if !lock.accept(addr) {
return;
Expand Down Expand Up @@ -136,7 +156,7 @@ fn push(
.map_or(false, |s| s.eq_ignore_ascii_case(HTML_START)) =>
{
let mut urls = url_crawl::get_urls(string);
let host = unsafe { host.get_inner() };
// let host = unsafe { host.get_inner() };

urls.retain(|url| {
let uri: Option<Uri> = url.parse().ok();
Expand Down Expand Up @@ -219,8 +239,8 @@ fn push(
// Else, do nothing
_ => {}
}
if let Some(manager) = manager.as_ref() {
let manager = unsafe { manager.get() };
if let Some(manager) = manager {
// let manager = unsafe { manager.get() };
let mut lock = manager.lock().await;
lock.register(addr);
}
Expand Down
125 changes: 53 additions & 72 deletions src/cors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,55 +247,46 @@ impl Extensions {
/// This is added when calling [`Extensions::new`].
pub fn with_disallow_cors(&mut self) -> &mut Self {
self.add_prime(
Box::new(|request, _, _| {
box_fut!({
let request = unsafe { request.get_inner() };

let missmatch = request
.headers()
.get("origin")
.and_then(|origin| origin.to_str().ok())
.map_or(false, |origin| {
!Cors::is_part_of_origin(origin, request.uri())
});
if missmatch {
Some(Uri::from_static("/./cors_fail"))
} else {
None
}
})
prime!(request, _, _, {
let missmatch = request
.headers()
.get("origin")
.and_then(|origin| origin.to_str().ok())
.map_or(false, |origin| {
!Cors::is_part_of_origin(origin, request.uri())
});
if missmatch {
Some(Uri::from_static("/./cors_fail"))
} else {
None
}
}),
Id::new(16_777_216, "Reroute all CORS requests to /./cors_fail"),
);

self.add_prepare_single(
"/./cors_fail",
Box::new(|_, _, _, _| {
ready({
let response = Response::builder()
.status(StatusCode::FORBIDDEN)
.body(Bytes::from_static(b"CORS request denied"))
.expect("we know this is a good request.");
FatResponse::new(response, comprash::ServerCachePreference::Full)
})
prepare!(_, _, _, _, {
let response = Response::builder()
.status(StatusCode::FORBIDDEN)
.body(Bytes::from_static(b"CORS request denied"))
.expect("we know this is a good request.");
FatResponse::new(response, comprash::ServerCachePreference::Full)
}),
);
self.add_prime(
Box::new(move |request, _, _| {
let request = unsafe { request.get_inner() };
ready(
if request.method() == Method::OPTIONS
&& request.headers().get("origin").is_some()
&& request
.headers()
.get("access-control-request-method")
.is_some()
{
Some(Uri::from_static("/./cors_fail"))
} else {
None
},
)
prime!(request, _, _, {
if request.method() == Method::OPTIONS
&& request.headers().get("origin").is_some()
&& request
.headers()
.get("access-control-request-method")
.is_some()
{
Some(Uri::from_static("/./cors_fail"))
} else {
None
}
}),
Id::new(16_777_215, "Provides CORS preflight request support"),
);
Expand All @@ -313,15 +304,13 @@ impl Extensions {
// This priority have to be higher than the one in the [`Self::add_disallow_cors`]'s prime
// extension.
self.add_prime(
Box::new(move |request, _, _| {
let request = unsafe { request.get_inner() };

prime!(request, _, _, move |cors_settings: Arc<Cors>| {
let allow = cors_settings.check_cors_request(request);
ready(if allow.is_some() {
if allow.is_some() {
None
} else {
Some(Uri::from_static("/./cors_fail"))
})
}
}),
Id::new(
16_777_216,
Expand All @@ -331,9 +320,9 @@ impl Extensions {

// Low priority so it runs last.
self.add_package(
Box::new(move |mut response, request, _| {
let (response, request) = unsafe { (response.get_inner(), request.get_inner()) };

package!(response, request, _, move |package_cors_settings: Arc<
Cors,
>| {
if let Some(origin) = request.headers().get("origin") {
let allowed = package_cors_settings.check_cors_request(request).is_some();
if allowed {
Expand All @@ -344,7 +333,6 @@ impl Extensions {
);
}
}
ready(())
}),
Id::new(
-1024,
Expand All @@ -354,18 +342,17 @@ impl Extensions {

self.add_prepare_single(
"/./cors_options",
Box::new(move |mut request, _, _, _| {
let request = unsafe { request.get_inner() };
prepare!(request, _, _, _, move |options_cors_settings: Arc<Cors>| {
let allowed = options_cors_settings.check_cors_request(request);

if allowed.is_none() {
return ready({
return {
let response = Response::builder()
.status(StatusCode::FORBIDDEN)
.body(Bytes::from_static(b"CORS request denied"))
.expect("we know this is a good request.");
FatResponse::new(response, comprash::ServerCachePreference::Full)
});
};
}

let mut builder = Response::builder().status(StatusCode::NO_CONTENT);
Expand Down Expand Up @@ -418,30 +405,24 @@ impl Extensions {
))
.expect("this is a good response.")
});
ready(FatResponse::new(
response,
comprash::ServerCachePreference::None,
))
FatResponse::new(response, comprash::ServerCachePreference::None)
}),
);

// This priority has to be above all the above, else it won't be able to get the options.
self.add_prime(
Box::new(move |request, _, _| {
let request = unsafe { request.get_inner() };
ready(
if request.method() == Method::OPTIONS
&& request.headers().get("origin").is_some()
&& request
.headers()
.get("access-control-request-method")
.is_some()
{
Some(Uri::from_static("/./cors_options"))
} else {
None
},
)
prime!(request, _, _, {
if request.method() == Method::OPTIONS
&& request.headers().get("origin").is_some()
&& request
.headers()
.get("access-control-request-method")
.is_some()
{
Some(Uri::from_static("/./cors_options"))
} else {
None
}
}),
Id::new(16_777_215, "Provides CORS preflight request support"),
);
Expand Down
2 changes: 1 addition & 1 deletion src/csp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ impl Extensions {
/// [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy).
pub fn with_csp(&mut self, csp: Arc<Csp>) -> &mut Self {
self.add_package(
package!(response, request, _host, move |csp| {
package!(response, request, _host, move |csp: Arc<Csp>| {
if let Some(rule) = csp.get(request.uri().path()) {
let nonce = response.headers().get("csp-nonce");
let some_nonce = nonce.is_some();
Expand Down
Loading

0 comments on commit 83b5d10

Please sign in to comment.