Skip to content

Commit 3edd5e2

Browse files
authored
Merge pull request #5 from nuclearcat/add-caching-headers
feat: Implement basic HTTP caching with ETag and Last-Modified
2 parents 87792e2 + 910d6f1 commit 3edd5e2

2 files changed

Lines changed: 40 additions & 2 deletions

File tree

.github/workflows/docker.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,5 @@ jobs:
1919
# run: |
2020
# docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/nuclearcat/kernelci-storage:latest --push .
2121
run: |
22-
docker buildx build --platform linux/amd64 -t ghcr.io/nuclearcat/kernelci-storage:latest --push .
23-
22+
docker buildx build --platform linux/amd64 -t ghcr.io/kernelci/kernelci-storage:latest --push .
2423

src/main.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,44 @@ async fn ax_get_file(
571571
);
572572

573573
headers.insert(header::ACCEPT_RANGES, "bytes".parse().unwrap());
574+
// add e-tag header from received_file.headers
575+
if let Some(etag) = upstream_headers.get("ETag") {
576+
headers.insert(header::ETAG, etag.clone());
577+
}
578+
// add last-modified header
579+
if let Some(last_modified) = upstream_headers.get("Last-Modified") {
580+
headers.insert(header::LAST_MODIFIED, last_modified.clone());
581+
}
582+
583+
// TODO: rxheaders.get is case sensitive or not?
584+
// Does request have If-None-Match header?
585+
if let Some(if_none_match) = rxheaders.get("If-None-Match") {
586+
// §13.1.2, last paragraph, RFC 9110
587+
if method != axum::http::Method::GET && method != axum::http::Method::HEAD {
588+
return (StatusCode::PRECONDITION_FAILED, "Method Not Allowed").into_response();
589+
}
590+
if let Some(etag) = upstream_headers.get("ETag") {
591+
if if_none_match == etag {
592+
println!(
593+
"{:?} 304 0 {} {} {} {}",
594+
remote_addr, human_time, method, filepath, user_agent_str
595+
);
596+
return (StatusCode::NOT_MODIFIED, headers, Body::empty()).into_response();
597+
}
598+
}
599+
// Does request have If-Modified-Since header?
600+
} else if let Some(if_modified_since) = rxheaders.get("If-Modified-Since") {
601+
if let Some(last_modified) = upstream_headers.get("Last-Modified") {
602+
// TODO: Validate properly last_modified
603+
if if_modified_since == last_modified {
604+
println!(
605+
"{:?} 304 0 {} {} {} {}",
606+
remote_addr, human_time, method, filepath, user_agent_str
607+
);
608+
return (StatusCode::NOT_MODIFIED, headers, Body::empty()).into_response();
609+
}
610+
}
611+
}
574612

575613
/* Usually HEAD is used to check if the file exists and range is supported */
576614
if method == axum::http::Method::HEAD {
@@ -581,6 +619,7 @@ async fn ax_get_file(
581619
);
582620
return (headers, Body::empty()).into_response();
583621
}
622+
584623
match tokio::fs::File::open(&cached_file).await {
585624
Ok(mut file) => {
586625
let mut start = 0;

0 commit comments

Comments
 (0)