diff --git a/Cargo.lock b/Cargo.lock index 63b5a0e..33b8b83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1182,6 +1182,7 @@ dependencies = [ name = "middleman" version = "0.1.0" dependencies = [ + "base64", "minio", "rocket", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 82f4398..8b7ebef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,5 +7,6 @@ edition = "2021" rocket = {path = "../Rocket/core/lib"} tokio = { version = "1.40.0", features = ["full"] } tracing = "0.1.40" -tracing-subscriber = "0.3.18" +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } minio = {git="https://github.com/minio/minio-rs.git", rev = "c28f576"} +base64 = "0.22.1" diff --git a/browser/background.js b/browser/background.js index f31e1a8..32d8344 100644 --- a/browser/background.js +++ b/browser/background.js @@ -1,13 +1,39 @@ -function handle(requestDetails) { - let b64 = btoa(requestDetails.url) - if (!requestDetails.url.startsWith("http://localhost")) { - console.log(`Loading: ${requestDetails.url} || ${b64}`); +function handle_header(req) { + // Headers + // let x = req.requestHeaders; + // if (!x) { + x = new Headers() + // } + x.append("og", old) + + console.log(x) + + // appending header of the original url so that relative urls can be built into + // absolute urls + // TODO This doesn't work yet + return { + requestHeaders: x, + } +} + +let old = "" + +function url_redirect (req) { + let b64 = btoa(req.url) + if (!req.url.startsWith("http://localhost")) { + old = req.url + // console.debug(`Loading: ${req.url} || ${b64}`); return { redirectUrl: `http://localhost:4433/s3/${b64}` } } } -browser.webRequest.onBeforeRequest.addListener( - handle, { urls: [""] }, ["blocking"] +browser.webRequest.onBeforeSendHeaders.addListener( + handle_header, { urls: [""] }, ["blocking", "requestHeaders"] ); + +browser.webRequest.onBeforeRequest.addListener( + url_redirect, { urls: [""] }, ["blocking"] +) + diff --git a/src/main.rs b/src/main.rs index 3a82b06..fce629b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ -use rocket::{fairing::{Fairing, Info, Kind}, fs::FileServer, get, http::Header, routes, Request, Response, State}; +use rocket::{fairing::{Fairing, Info, Kind}, fs::FileServer, futures::io::Cursor, get, http::{ContentType, CookieJar, Header, HeaderMap, Status}, outcome::Outcome, request::{self, FromRequest}, response::content, routes, Error, Request, Response, State}; use s3::S3; -use tracing::{info, Level}; +use tracing::{debug, info, trace, Level}; +use tracing_subscriber::EnvFilter; mod s3; @@ -16,7 +17,7 @@ async fn main() { tracing_subscriber::fmt() .with_line_number(false) .without_time() - .with_max_level(Level::INFO) + .with_env_filter(EnvFilter::from_default_env()) .init(); let config = Config { @@ -27,46 +28,79 @@ async fn main() { }; let s3 = S3::connect(&config).await.expect("Failed to connect to minio, aborting."); - let cors = CORS; + // let cors = CORS; let _ = rocket::build() .mount("/", FileServer::new("www/")) .mount("/", routes![get_s3_content]) .manage(s3) - .attach(cors) + // .attach(cors) .launch() .await; info!("Bye"); } +struct Og { + og: Option +} +#[rocket::async_trait] +impl<'r> FromRequest<'r> for Og{ + type Error = Error; + + async fn from_request(req: &'r Request<'_>) -> request::Outcome { + if let Some(h) = req.headers().get("og-domain").next() { + debug!(h); + return Outcome::Success(Og { og: Some(h.to_string()) }); + } + Outcome::Success(Og { og: None }) + } +} + + #[get("/s3/")] -async fn get_s3_content(path: &str, db: &State) -> Option { +async fn get_s3_content(path: &str, db: &State, og: Og) -> (Status, (ContentType, String)) { + use base64::prelude::*; + info!("{:?}", og.og); + if let Some(resp) = db.get(&path).await { - return Some(resp) + let content_type = if let Ok(url) = BASE64_URL_SAFE.decode(path) { + let url = url.into_iter().map(|f| f as char).collect::(); + if let Some(filetype) = url.split('.').collect::>().last() { + ContentType::from_extension(&filetype).unwrap_or(ContentType::HTML) + } else { + ContentType::HTML + } + } else { + ContentType::Any + }; + trace!("{:?}", content_type); + + return (Status::Ok, (content_type, resp)) } // instead of some/none I would rather this be 200/404 - None + // TODO should tell surreal to get this url next. + (Status::NotFound, (ContentType::Text, "Resource not found in offline cache".to_string())) } // CORS, to allow other sites to request this from their front-end -pub struct CORS; +// pub struct CORS; -#[rocket::async_trait] -impl Fairing for CORS { - fn info(&self) -> Info { - Info { - name: "Add CORS headers to responses", - kind: Kind::Response - } - } +// #[rocket::async_trait] +// impl Fairing for CORS { +// fn info(&self) -> Info { +// Info { +// name: "Add CORS headers to responses", +// kind: Kind::Response +// } +// } - async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) { - response.set_header(Header::new("Access-Control-Allow-Origin", "*")); - response.set_header(Header::new("Access-Control-Allow-Methods", "POST, GET, PATCH, OPTIONS")); - response.set_header(Header::new("Access-Control-Allow-Headers", "*")); - response.set_header(Header::new("Access-Control-Allow-Credentials", "true")); - // TODO set this automatically like how Rocket/core/lib/src/fs/server.rs does (bottom of file) - response.set_header(Header::new("Content-Type", "text/html")); - } -} +// async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) { +// response.set_header(Header::new("Access-Control-Allow-Origin", "*")); +// response.set_header(Header::new("Access-Control-Allow-Methods", "POST, GET, PATCH, OPTIONS")); +// response.set_header(Header::new("Access-Control-Allow-Headers", "*")); +// response.set_header(Header::new("Access-Control-Allow-Credentials", "true")); +// // TODO set this automatically like how Rocket/core/lib/src/fs/server.rs does (bottom of file) +// response.set_header(Header::new("Content-Type", "text/html")); +// } +// }