refactor: reply allowed methods for `OPTIONS` file requests (#278)
since previously it was only allowed for directory requests
now sws will reply as follows:
$ curl -I -X OPTIONS http://localhost:8787/assets/main.js
HTTP/1.1 204 No Content
allow: OPTIONS, HEAD, GET
accept-ranges: bytes
vary: accept-encoding
cache-control: public, max-age=31536000
access-control-allow-origin: *
date: Mon, 30 Oct 2023 21:16:59 GMT
Diff
src/static_files.rs | 91 ++++++++++++++++++++++++++----------------------------
1 file changed, 44 insertions(+), 47 deletions(-)
@@ -87,7 +87,6 @@ pub async fn handle<'a>(opts: &HandleOpts<'a>) -> Result<(Response<Body>, bool),
}
let headers_opt = opts.headers;
let compression_static_opt = opts.compression_static;
let mut file_path = sanitize_path(opts.base_path, uri_path)?;
let FileMetadata {
@@ -98,7 +97,7 @@ pub async fn handle<'a>(opts: &HandleOpts<'a>) -> Result<(Response<Body>, bool),
} = composed_file_metadata(
&mut file_path,
headers_opt,
compression_static_opt,
opts.compression_static,
opts.index_files,
)
.await?;
@@ -111,57 +110,55 @@ pub async fn handle<'a>(opts: &HandleOpts<'a>) -> Result<(Response<Body>, bool),
let is_precompressed = precompressed_variant.is_some();
if is_dir {
if opts.redirect_trailing_slash && !uri_path.ends_with('/') {
let uri = [uri_path, "/"].concat();
let loc = match HeaderValue::from_str(uri.as_str()) {
Ok(val) => val,
Err(err) => {
tracing::error!("invalid header value from current uri: {:?}", err);
return Err(StatusCode::INTERNAL_SERVER_ERROR);
}
};
if is_dir && opts.redirect_trailing_slash && !uri_path.ends_with('/') {
let uri = [uri_path, "/"].concat();
let loc = match HeaderValue::from_str(uri.as_str()) {
Ok(val) => val,
Err(err) => {
tracing::error!("invalid header value from current uri: {:?}", err);
return Err(StatusCode::INTERNAL_SERVER_ERROR);
}
};
let mut resp = Response::new(Body::empty());
resp.headers_mut().insert(hyper::header::LOCATION, loc);
*resp.status_mut() = StatusCode::PERMANENT_REDIRECT;
let mut resp = Response::new(Body::empty());
resp.headers_mut().insert(hyper::header::LOCATION, loc);
*resp.status_mut() = StatusCode::PERMANENT_REDIRECT;
tracing::trace!("uri doesn't end with a slash so redirecting permanently");
return Ok((resp, is_precompressed));
}
tracing::trace!("uri doesn't end with a slash so redirecting permanently");
return Ok((resp, is_precompressed));
}
if method.is_options() {
let mut resp = Response::new(Body::empty());
*resp.status_mut() = StatusCode::NO_CONTENT;
resp.headers_mut()
.typed_insert(headers::Allow::from_iter(HTTP_SUPPORTED_METHODS.clone()));
resp.headers_mut().typed_insert(AcceptRanges::bytes());
if method.is_options() {
let mut resp = Response::new(Body::empty());
*resp.status_mut() = StatusCode::NO_CONTENT;
resp.headers_mut()
.typed_insert(headers::Allow::from_iter(HTTP_SUPPORTED_METHODS.clone()));
resp.headers_mut().typed_insert(AcceptRanges::bytes());
return Ok((resp, is_precompressed));
}
return Ok((resp, is_precompressed));
}
#[cfg(feature = "directory-listing")]
if opts.dir_listing && !file_path.exists() {
let resp = directory_listing::auto_index(DirListOpts {
method,
current_path: uri_path,
uri_query: opts.uri_query,
filepath: file_path,
dir_listing_order: opts.dir_listing_order,
dir_listing_format: opts.dir_listing_format,
ignore_hidden_files: opts.ignore_hidden_files,
})
.await?;
#[cfg(feature = "directory-listing")]
if is_dir && opts.dir_listing && !file_path.exists() {
let resp = directory_listing::auto_index(DirListOpts {
method,
current_path: uri_path,
uri_query: opts.uri_query,
filepath: file_path,
dir_listing_order: opts.dir_listing_order,
dir_listing_format: opts.dir_listing_format,
ignore_hidden_files: opts.ignore_hidden_files,
})
.await?;
return Ok((resp, is_precompressed));
}
return Ok((resp, is_precompressed));
}