ServeDir doesn't serve files without extentions if pre-compression is enabled
Closed this issue · 0 comments
SvizelPritula commented
Bug Report
Version
tower-http v0.5.2
Platform
Linux turing-machine 6.8.0-41-generic #41-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug 2 20:41:06 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
Description
When using ServeDir::precompressed_gzip
or similar methods, ServeDir
won't serve files without a file extention if the client supports the relevant encoding.
Consider the following axum
server:
use axum::Router;
use std::net::SocketAddr;
use tower_http::services::ServeDir;
#[tokio::main]
async fn main() {
let app = Router::new().fallback_service(ServeDir::new("assets/").precompressed_gzip());
let addr = SocketAddr::from(([127, 0, 0, 1], 8000));
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
axum::serve(listener, app).await.unwrap();
}
I created the assets/hello
file and tried to access it using curl:
$ curl -i http://localhost:8000/hello
HTTP/1.1 200 OK
content-type: application/octet-stream
accept-ranges: bytes
last-modified: Thu, 29 Aug 2024 14:51:50 GMT
content-length: 14
date: Thu, 29 Aug 2024 15:04:58 GMT
Hello, world!
$ curl -i -H "Accept-Encoding: gzip" http://localhost:8000/hello
HTTP/1.1 404 Not Found
content-length: 0
date: Thu, 29 Aug 2024 15:05:06 GMT
This happens whether assets/hello.gz
exists or not.
Speculation
There seems to be a bug in the tower_http::services::fs::serve_dir::open_file::preferred_encoding
method.
I tried adding this test:
#[test]
fn preferred_encoding_without_extension() {
let mut path = PathBuf::from("hello");
preferred_encoding(&mut path, &[(Encoding::Gzip, QValue::one())]);
assert_eq!(path, PathBuf::from("hello.gz"));
}
This test fails with the following panic:
thread 'services::fs::serve_dir::open_file::tests::preferred_encoding_without_extension' panicked at tower-http/src/services/fs/serve_dir/open_file.rs:342:9:
assertion `left == right` failed
left: "hello..gz"
right: "hello.gz"