Fixing a CORS bug
Dependencies
Change contents
- replacement in ui/src/routes/logout/+page.server.ts at line 7
throw redirect(302, `/`);redirect(302, `/`); - replacement in ui/src/routes/helpers.ts at line 13
export const server = browser ? import.meta.env.VITE_SERVER : import.meta.env.VITE_LOCAL_SERVER;export const server = import.meta.env.VITE_SERVER - edit in ui/src/routes/[user]/[repo]/tree/[[pos]]/+page.ts at line 11
console.log(resp); - replacement in ui/src/routes/[user]/[repo]/admin/+page.ts at line 5
const resp = await fetch(`${server}/api/admin/${params.user}/${params.repo}`);const url = `${server}/api/admin/${params.user}/${params.repo}`console.log("URL", url)const resp = await fetch(url); - replacement in ui/src/routes/[user]/[repo]/admin/+page.server.ts at line 50
throw redirect(302, `/${params.user}/${params.repo}/admin`);redirect(302, `/${params.user}/${params.repo}/admin`); - replacement in ui/src/routes/[user]/[repo]/+page.ts at line 6
throw redirect(302, `${ui_server}/${params.user}/${params.repo}/tree`);redirect(302, `${ui_server}/${params.user}/${params.repo}/tree`); - replacement in ui/src/routes/[user]/+page.ts at line 3
import { errorMsg, server, ui_server } from '../helpers';import { errorMsg, server } from '../helpers'; - replacement in ui/src/routes/[user]/+page.ts at line 16
console.log('redirect', `${ui_server}/settings`);throw redirect(302, `${ui_server}/settings`);console.log('redirect', `/settings`);redirect(302, `/settings`); - replacement in ui/src/routes/+page.ts at line 5
export const load: PageLoad = async ({ fetch }) => {export const load: PageLoad = async ({ request, fetch }) => { - replacement in ui/src/routes/+page.ts at line 10
throw redirect(302, `${ui_server}/${y.login}`);redirect(302, `${ui_server}/settings`); - file addition: hooks.server.ts[2.2255]
import type { HandleFetch } from '@sveltejs/kit';export const handleFetch: HandleFetch = async ({ event, request, fetch }) => {if (request.url.startsWith(import.meta.env.VITE_SERVER)) {// clone the original request, but change the URLrequest = new Request(request.url.replace(import.meta.env.VITE_SERVER, import.meta.env.VITE_LOCAL_SERVER),request);}console.log("request", request.url)const cookie = event.request.headers.get('cookie');console.log(cookie, request.headers.get('cookie'));if (cookie) {request.headers.set('cookie', cookie);}return fetch(request);}; - replacement in api/src/proxy.rs at line 1
use axum::{extract::State, http};use crate::Config;use axum::extract::State;use axum::response::IntoResponse; - replacement in api/src/proxy.rs at line 10
pub struct BodyBuilder {pub http: http::response::Builder,pub html: bool,fn cached(cache: &std::sync::RwLock<std::collections::HashMap<String, crate::config::Cached>>,t: Option<&str>,path: &str,) -> Option<axum::response::Response> {if let Ok(c) = cache.read() {if let Some(cached) = c.get(path) {debug!("cached {:?}", path);let mut resp = hyper::Response::new(cached.body.clone().into());let h = resp.headers_mut();h.insert(hyper::header::STRICT_TRANSPORT_SECURITY,HSTS.try_into().unwrap(),);if let Some(ref c) = cached.content_type {h.insert(CONTENT_TYPE, c.clone());}h.insert(hyper::header::CONTENT_LENGTH,cached.body.len().to_string().parse().unwrap(),);return Some(resp);}}None - edit in api/src/proxy.rs at line 36
type Body = http_body_util::Full<bytes::Bytes>;impl BodyBuilder {fn body(self, body: bytes::Bytes) -> Result<hyper::Response<Body>, http::Error> {let html =self.html|| (self.http.headers_ref().map(|m| {m.get(CONTENT_TYPE).and_then(|x| x.to_str().ok()) == Some("text/html")}) == Some(true)); - replacement in api/src/proxy.rs at line 37
let data = if html {minify_html::minify(&body, &minify_html::Cfg::default()).into()} else {body};Ok(self.http.body(data.into())?)}#[axum::debug_handler]pub async fn node_proxy_cached(State(config): State<Config>,req: axum::extract::Request,) -> axum::response::Response {node_proxy(config, true, false, req).await.unwrap() - replacement in api/src/proxy.rs at line 46
pub async fn node_proxy_resp(State(config): State<crate::Config>,pub async fn node_proxy_strong_cached(State(config): State<Config>, - replacement in api/src/proxy.rs at line 49
) -> hyper::Response<Body> {node_proxy(&config, req).await.unwrap()) -> axum::response::Response {node_proxy(config, true, true, req).await.unwrap() - replacement in api/src/proxy.rs at line 53
pub async fn node_proxy(config: &crate::config::Config,#[axum::debug_handler]pub async fn node_proxy_not_cached(State(config): State<Config>, - replacement in api/src/proxy.rs at line 57
) -> Result<hyper::Response<Body>, axum::http::Error> {match node_proxy_(config, req).await {) -> axum::response::Response {node_proxy(config, false, false, req).await.unwrap()}async fn node_proxy(config: Config,cache: bool,forever: bool,mut req: axum::extract::Request,) -> Result<axum::response::Response, hyper::http::Error> {let ref last_server_modif: chrono::DateTime<chrono::Utc> = config.version_time.into();if let Some(modif) = req.headers().get(http::header::IF_MODIFIED_SINCE) {debug!("req last_modif: {:?}", modif);if let Ok(parsed) = chrono::NaiveDateTime::parse_from_str(std::str::from_utf8(modif.as_bytes()).unwrap_or(""),crate::config::RFC1123,) {let parsed = parsed.and_local_timezone(chrono::Utc).unwrap();debug!("parsed: {:?} {:?}", parsed, last_server_modif);if &parsed >= last_server_modif {return Ok(http::StatusCode::NOT_MODIFIED.into_response());}}}let mut path = if cache {let path = req.uri().path();if let Some(mut r) = cached(&config.cache, None, &path) {let ref l = config.version_time_str;debug!("cached {:?}", l);let h = r.headers_mut();h.insert(hyper::header::LAST_MODIFIED, l.parse().unwrap());h.insert(hyper::header::CACHE_CONTROL,if forever {"public, max-age=31536000".parse().unwrap()} else {"public".parse().unwrap()},);h.remove(hyper::header::VARY);return Ok(r);}Some(path.to_string())} else {None};req.headers_mut().remove(ACCEPT_ENCODING);debug!("node_proxy {:?}", path);for h in req.headers() {debug!("{:?}", h);}match node_proxy_(&config, req).await { - replacement in api/src/proxy.rs at line 111
let (mut parts, body) = resp.into_parts();let (parts, body) = resp.into_parts(); - replacement in api/src/proxy.rs at line 113
parts.headers.insert(debug!("body {:?}", body.len());if !parts.status.is_success() {// Ne pas mettre en cache dans ce cas.path = None;}/*parts.headers.insert( - replacement in api/src/proxy.rs at line 121
););*/ - edit in api/src/proxy.rs at line 132
};if let Some(path) = path {config.cache.write().unwrap().insert(path,crate::config::Cached {content_type: parts.headers.get(CONTENT_TYPE).cloned(),body: data.clone(),},); - edit in api/src/proxy.rs at line 145
debug!("response len {:?}", len); - replacement in api/src/proxy.rs at line 150
trace!("{:?} {:?}", k, v);if let Some(k) = k {h.insert(k, v);}h.insert(k.unwrap(), v); - edit in api/src/proxy.rs at line 156
if cache {let ref l = config.version_time_str;debug!("cache, last_modified {:?}", l);h.insert(hyper::header::LAST_MODIFIED, l.parse().unwrap());if forever {h.insert(hyper::header::CACHE_CONTROL,"public, max-age=31536000".parse().unwrap(),);} else {h.insert(hyper::header::CACHE_CONTROL, "public".parse().unwrap());}h.remove(hyper::header::VARY);} else {debug!("not cache")} - replacement in api/src/proxy.rs at line 175
error!("proxy error {:?}", e);let resp = http::response::Response::builder().status(http::StatusCode::INTERNAL_SERVER_ERROR).header(http::header::STRICT_TRANSPORT_SECURITY, HSTS);Ok(BodyBuilder {http: resp,html: false,}.body("".into())?)error!("grain error {:?}", e);Ok(hyper::Response::builder().status(hyper::StatusCode::INTERNAL_SERVER_ERROR).header(hyper::header::STRICT_TRANSPORT_SECURITY, HSTS).body("".into())?) - replacement in api/src/proxy.rs at line 185
config: &crate::config::Config,req: axum::extract::Request,) -> Result<hyper::Response<hyper::body::Incoming>, crate::Error> {config: &Config,req: hyper::Request<axum::body::Body>,) -> Result<hyper::Response<axum::body::Body>, crate::Error> { - edit in api/src/proxy.rs at line 201
debug!("node_proxy_ localhost:5173"); - replacement in api/src/proxy.rs at line 220
for (k, v) in req.headers() {req_ = req_.header(k, v)}if cfg!(debug_assertions) {req_ = req_.header(HOST, "localhost:5173");} else {req_ = req_.header(HOST, "nest.pijul.org");for (h, v) in req.headers() {if h == HOST {req_ = req_.header(HOST, config.host.clone());} else {req_ = req_.header(h, v.clone());} - replacement in api/src/proxy.rs at line 228
let req_ = req_.body(body)?;Ok(sender.send_request(req_).await?)let bytes = axum::body::to_bytes(body, usize::MAX).await.unwrap();let req_: http::Request<axum::body::Body> = req_.body(bytes.into())?;debug!("node_proxy_ {:?}", req_);let mut resp = sender.send_request(req_).await?;let body = resp.body_mut().collect().await.unwrap().to_bytes();Ok(resp.map(|_| body.into())) - replacement in api/src/main.rs at line 64
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {format!("{}=debug,tower_http=debug,axum::rejection=trace",env!("CARGO_CRATE_NAME")).into()}),tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| "nest=debug,tower_http=debug,axum::rejection=trace".into()), - replacement in api/src/main.rs at line 74
.allow_origin("http://localhost:5173".parse::<http::HeaderValue>().unwrap(),).allow_origin([config_file.origin.parse::<http::HeaderValue>().unwrap(),]) - replacement in api/src/main.rs at line 78
/*let cors = CorsLayer::new().allow_origin(tower_http::cors::AllowOrigin::any());*/ - replacement in api/src/main.rs at line 93
.route("/static/{*wildcard}", any(proxy::node_proxy_resp)).route("/_app/immutable/{*wildcard}", any(proxy::node_proxy_resp)).route("/static/{*wildcard}", any(proxy::node_proxy_cached)).route("/_app/immutable/{*wildcard}", any(proxy::node_proxy_cached)) - edit in api/src/main.rs at line 109
.route("/logout", any(logout)) - replacement in api/src/main.rs at line 118
.fallback(proxy::node_proxy_resp).fallback(proxy::node_proxy_not_cached) - replacement in api/src/main.rs at line 129
tracing::debug_span!("request", %method, %uri, matched_path)let headers = req.headers();let h = format!("{:?}", headers);tracing::debug_span!("request", %method, %uri, matched_path, %h) - replacement in api/src/main.rs at line 166
tracing::debug!("listening on {}", https_addr);let https_worker = tokio::spawn(axum_server::bind_rustls(https_addr, tls_config).serve(app.clone().into_make_service_with_connect_info::<SocketAddr>(),),);let app_ = app.clone();let (https_worker, http_worker) = if let Some(tls_config) = tls_config {(tokio::spawn(axum_server::bind_rustls(https_addr, tls_config).serve(app.into_make_service_with_connect_info::<SocketAddr>()),),tokio::spawn(async move {redirect_http_to_https(config_file.http.http_port,config_file.http.https_port,app_,).await;Ok::<_, Error>(())}),)} else {let listener = tokio::net::TcpListener::bind(http_addr).await.unwrap();let listener2 = tokio::net::TcpListener::bind(https_addr).await.unwrap();tracing::debug!("listening on {}", listener.local_addr().unwrap());use axum::handler::HandlerWithoutStateExt;(tokio::spawn(async move {axum::serve(listener,app.into_make_service_with_connect_info::<SocketAddr>(),).await}),tokio::spawn(async move {axum::serve(listener2,app_.into_make_service_with_connect_info::<SocketAddr>(),).await?;Ok::<_, Error>(())}),)}; - edit in api/src/main.rs at line 208
let http_worker = tokio::spawn(redirect_http_to_https(config_file.http.http_port,config_file.http.https_port,app,)); - edit in api/src/main.rs at line 228
)}#[debug_handler]async fn logout(State(config): State<Config>, jar: SignedCookieJar) -> (SignedCookieJar, Redirect) {(jar.remove(axum_extra::extract::cookie::Cookie::from("session_id")),Redirect::to("/"), - replacement in api/src/main.rs at line 249
Ok(proxy::node_proxy(&config, req).await?.into_response())Ok(proxy::node_proxy_(&config, req).await?.into_response()) - edit in api/src/main.rs at line 462
debug!("get_user_login: id {:?}", id); - edit in api/src/main.rs at line 472
} else {debug!("get_user_login: no id"); - replacement in api/src/email.rs at line 39
rusoto_ses::SesClient::new_with(client, config_email, rusoto_core::Region::EuWest1)rusoto_ses::SesClient::new_with(client, config_email, config.aws_ses_zone.clone()) - edit in api/src/config_file.rs at line 6
pub region: String, - edit in api/src/config_file.rs at line 36
pub hostname: String, - edit in api/src/config.rs at line 14
pub const RFC1123: &str = "%a, %d %b %Y %H:%M:%S GMT"; - edit in api/src/config.rs at line 42
pub aws_ses_zone: rusoto_core::Region, - replacement in api/src/config.rs at line 131
pub async fn make_tls() -> Result<axum_server::tls_rustls::RustlsConfig, TlsError> {let key = std::env::var("tls_key").unwrap().into_bytes();let certs = std::env::var("tls_cert").unwrap().into_bytes();Ok(axum_server::tls_rustls::RustlsConfig::from_pem(certs, key).await.unwrap())pub async fn make_tls() -> Result<Option<axum_server::tls_rustls::RustlsConfig>, TlsError> {if let (Ok(key), Ok(cert)) = (std::env::var("tls_key"), std::env::var("tls_cert")) {Ok(Some(axum_server::tls_rustls::RustlsConfig::from_pem(cert.into_bytes(), key.into_bytes()).await.unwrap(),))} else {Ok(None)} - replacement in api/src/config.rs at line 212
hostname: config_file.host.clone(),host: {let mut h = config_file.host.clone();if config_file.http.https_port != 443 {h.push_str(&format!(":{}", config_file.http.https_port));}h},aws_ses_zone: config_file.email.region.parse().unwrap(),hostname: config_file.hostname.clone(),host: config_file.host.clone(), - replacement in api/src/auth.rs at line 26
#[derive(Debug, Serialize, Deserialize)]#[derive(Serialize, Deserialize)] - edit in api/src/auth.rs at line 68
debug!("{:?}", payload); - replacement in api/src/auth.rs at line 215
.set(u::password.eq(make_password!(recover.pass))).filter(u::email_is_invalid.is_null()).set((u::password.eq(make_password!(recover.pass)),u::email_is_invalid.eq(None::<bool>),)) - replacement in api/src/auth.rs at line 383
config.host, tokenconfig.hostname, token - replacement in api/src/auth.rs at line 409
", config.host, token),", config.hostname, token), - replacement in Cargo.lock at line 853
"bincode 2.0.1","bincode 1.3.3", - edit in Cargo.lock at line 1931
name = "getrandom"version = "0.4.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"dependencies = ["cfg-if","libc","r-efi","wasip2","wasip3",][[package]] - edit in Cargo.lock at line 2448
name = "id-arena"version = "2.3.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"[[package]] - edit in Cargo.lock at line 2633
[[package]]name = "leb128fmt"version = "0.1.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - edit in Cargo.lock at line 4119
name = "prettyplease"version = "0.2.37"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"dependencies = ["proc-macro2","syn 2.0.111",][[package]] - edit in Cargo.lock at line 5814
name = "unicode-xid"version = "0.2.6"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"[[package]] - replacement in Cargo.lock at line 5873
version = "1.18.1"version = "1.21.0" - replacement in Cargo.lock at line 5875
checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" - replacement in Cargo.lock at line 5877
"getrandom 0.3.4","getrandom 0.4.1", - replacement in Cargo.lock at line 5879
"serde","serde_core", - replacement in Cargo.lock at line 5962
"wit-bindgen","wit-bindgen 0.46.0",][[package]]name = "wasip3"version = "0.4.0+wasi-0.3.0-rc-2026-01-06"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"dependencies = ["wit-bindgen 0.51.0", - edit in Cargo.lock at line 6036
][[package]]name = "wasm-encoder"version = "0.244.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"dependencies = ["leb128fmt","wasmparser",][[package]]name = "wasm-metadata"version = "0.244.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"dependencies = ["anyhow","indexmap","wasm-encoder","wasmparser",][[package]]name = "wasmparser"version = "0.244.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"dependencies = ["bitflags 2.10.0","hashbrown 0.15.5","indexmap","semver", - edit in Cargo.lock at line 6461
[[package]]name = "wit-bindgen"version = "0.51.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"dependencies = ["wit-bindgen-rust-macro",][[package]]name = "wit-bindgen-core"version = "0.51.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"dependencies = ["anyhow","heck 0.5.0","wit-parser",][[package]]name = "wit-bindgen-rust"version = "0.51.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"dependencies = ["anyhow","heck 0.5.0","indexmap","prettyplease","syn 2.0.111","wasm-metadata","wit-bindgen-core","wit-component",][[package]]name = "wit-bindgen-rust-macro"version = "0.51.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"dependencies = ["anyhow","prettyplease","proc-macro2","quote","syn 2.0.111","wit-bindgen-core","wit-bindgen-rust",][[package]]name = "wit-component"version = "0.244.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"dependencies = ["anyhow","bitflags 2.10.0","indexmap","log","serde","serde_derive","serde_json","wasm-encoder","wasm-metadata","wasmparser","wit-parser",] - edit in Cargo.lock at line 6533
name = "wit-parser"version = "0.244.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"dependencies = ["anyhow","id-arena","indexmap","log","semver","serde","serde_derive","serde_json","unicode-xid","wasmparser",][[package]]