diff --git a/src/dav/mod.rs b/src/dav/mod.rs
index 6ac25d9..02712ac 100644
--- a/src/dav/mod.rs
+++ b/src/dav/mod.rs
@@ -9,7 +9,7 @@ use self::path::*;
use self::types::*;
use self::util::*;
use self::xml::*;
-use crate::consts::{CSS_CONTENT_TYPE, DAV_XML_CONTENT_TYPE, HTML_CONTENT_TYPE};
+use crate::consts::{DAV_XML_CONTENT_TYPE, HTML_CONTENT_TYPE};
use crate::dandi::*;
use axum::{
body::Body,
@@ -19,6 +19,7 @@ use axum::{
RequestExt,
};
use futures_util::TryStreamExt;
+use std::convert::Infallible;
use thiserror::Error;
const WEBDAV_RESPONSE_HEADERS: [(&str, &str); 2] = [
@@ -27,8 +28,6 @@ const WEBDAV_RESPONSE_HEADERS: [(&str, &str); 2] = [
("DAV", "1, 3"),
];
-static STYLESHEET: &str = include_str!("static/styles.css");
-
pub(crate) struct DandiDav {
client: Client,
templater: Templater,
@@ -47,35 +46,35 @@ impl DandiDav {
pub(crate) async fn handle_request(
&self,
req: Request
,
- ) -> Result, DavError> {
+ ) -> Result, Infallible> {
+ let resp = self.inner_handle_request(req).await;
+ Ok((WEBDAV_RESPONSE_HEADERS, resp).into_response())
+ }
+
+ async fn inner_handle_request(&self, req: Request) -> Result, DavError> {
let uri_path = req.uri().path();
// Performing this assignment outside the `match` magically makes this
// compile on pre-1.74 Rusts:
let m = req.method();
- let resp = match m {
- &Method::GET if uri_path == "/.static/styles.css" => {
- // Don't add WebDAV headers
- return Ok(([(CONTENT_TYPE, CSS_CONTENT_TYPE)], STYLESHEET).into_response());
- }
+ match m {
&Method::GET => {
let Some(path) = DavPath::parse_uri_path(uri_path) else {
return Ok(not_found());
};
- self.get(&path, uri_path).await?
+ self.get(&path, uri_path).await
}
- &Method::OPTIONS => StatusCode::NO_CONTENT.into_response(),
+ &Method::OPTIONS => Ok(StatusCode::NO_CONTENT.into_response()),
m if m.as_str().eq_ignore_ascii_case("PROPFIND") => {
let Some(path) = DavPath::parse_uri_path(uri_path) else {
return Ok(not_found());
};
match req.extract::<(FiniteDepth, PropFind), _>().await {
- Ok((depth, pf)) => self.propfind(&path, depth, pf).await?,
- Err(r) => r,
+ Ok((depth, pf)) => self.propfind(&path, depth, pf).await,
+ Err(r) => Ok(r),
}
}
- _ => StatusCode::METHOD_NOT_ALLOWED.into_response(),
- };
- Ok((WEBDAV_RESPONSE_HEADERS, resp).into_response())
+ _ => Ok(StatusCode::METHOD_NOT_ALLOWED.into_response()),
+ }
}
async fn get(&self, path: &DavPath, uri_path: &str) -> Result, DavError> {
@@ -363,5 +362,5 @@ impl IntoResponse for DavError {
}
fn not_found() -> Response {
- (StatusCode::NOT_FOUND, WEBDAV_RESPONSE_HEADERS, "404\n").into_response()
+ (StatusCode::NOT_FOUND, "404\n").into_response()
}
diff --git a/src/main.rs b/src/main.rs
index 68bfa31..3beb24b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,26 +3,27 @@ mod dandi;
mod dav;
mod paths;
mod s3;
-use crate::consts::DEFAULT_API_URL;
+use crate::consts::{CSS_CONTENT_TYPE, DEFAULT_API_URL};
use crate::dandi::Client;
use crate::dav::{DandiDav, Templater};
use anyhow::Context;
use axum::{
body::Body,
extract::Request,
- http::{response::Response, Method},
+ http::{header::CONTENT_TYPE, response::Response, Method},
middleware::{self, Next},
- response::IntoResponse,
+ routing::get,
Router,
};
use clap::Parser;
-use std::convert::Infallible;
use std::net::IpAddr;
use std::sync::Arc;
use tower::service_fn;
use tower_http::trace::TraceLayer;
use tracing_subscriber::filter::LevelFilter;
+static STYLESHEET: &str = include_str!("dav/static/styles.css");
+
/// WebDAV view to DANDI Archive
///
/// See for more information.
@@ -56,11 +57,19 @@ async fn main() -> anyhow::Result<()> {
let templater = Templater::load()?;
let dav = Arc::new(DandiDav::new(client, templater, args.title));
let app = Router::new()
+ .route(
+ "/.static/styles.css",
+ get(|| async {
+ // Note: This response should not have WebDAV headers (DAV, Allow)
+ ([(CONTENT_TYPE, CSS_CONTENT_TYPE)], STYLESHEET)
+ }),
+ )
.nest_service(
"/",
service_fn(move |req: Request| {
let dav = Arc::clone(&dav);
- async move { Ok::<_, Infallible>(dav.handle_request(req).await.into_response()) }
+ // Box the large future:
+ async move { Box::pin(dav.handle_request(req)).await }
}),
)
.layer(middleware::from_fn(handle_head))