From 289e465f0589a33c3333efe6eab26695e3a78df4 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 5 Jul 2022 01:06:01 +0200 Subject: [PATCH] fix: correct cache-control in car responses Context: https://github.com/ipfs/specs/pull/295 --- core/corehttp/gateway_handler_car.go | 18 ++++++++++-------- test/sharness/t0118-gateway-car.sh | 4 ++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/core/corehttp/gateway_handler_car.go b/core/corehttp/gateway_handler_car.go index 72231ceaf65..05c297664a5 100644 --- a/core/corehttp/gateway_handler_car.go +++ b/core/corehttp/gateway_handler_car.go @@ -43,8 +43,14 @@ func (i *gatewayHandler) serveCAR(ctx context.Context, w http.ResponseWriter, r } setContentDispositionHeader(w, name, "attachment") - // Weak Etag W/ because we can't guarantee byte-for-byte identical responses - // (CAR is streamed, and in theory, blocks may arrive from datastore in non-deterministic order) + // Set Cache-Control (same logic as for a regular files) + addCacheControlHeaders(w, r, contentPath, rootCid) + + // Weak Etag W/ because we can't guarantee byte-for-byte identical + // responses, but still want to benefit from HTTP Caching. Two CAR + // responses for the same CID and selector will be logically equivalent, + // but when CAR is streamed, then in theory, blocks may arrive from + // datastore in non-deterministic order. etag := `W/` + getEtag(r, rootCid) w.Header().Set("Etag", etag) @@ -55,14 +61,10 @@ func (i *gatewayHandler) serveCAR(ctx context.Context, w http.ResponseWriter, r } // Make it clear we don't support range-requests over a car stream - // Partial downloads and resumes should be handled using - // IPLD selectors: https://github.com/ipfs/go-ipfs/issues/8769 + // Partial downloads and resumes should be handled using requests for + // sub-DAGs and IPLD selectors: https://github.com/ipfs/go-ipfs/issues/8769 w.Header().Set("Accept-Ranges", "none") - // Explicit Cache-Control to ensure fresh stream on retry. - // CAR stream could be interrupted, and client should be able to resume and get full response, not the truncated one - w.Header().Set("Cache-Control", "no-cache, no-transform") - w.Header().Set("Content-Type", "application/vnd.ipld.car; version=1") w.Header().Set("X-Content-Type-Options", "nosniff") // no funny business in the browsers :^) diff --git a/test/sharness/t0118-gateway-car.sh b/test/sharness/t0118-gateway-car.sh index 5b0306e0717..3d8d7b08f46 100755 --- a/test/sharness/t0118-gateway-car.sh +++ b/test/sharness/t0118-gateway-car.sh @@ -128,8 +128,8 @@ test_launch_ipfs_daemon_without_network grep "< X-Ipfs-Roots" curl_output ' - test_expect_success "GET response for application/vnd.ipld.car includes expected Cache-Control" ' - grep "< Cache-Control: no-cache, no-transform" curl_output + test_expect_success "GET response for application/vnd.ipld.car includes same Cache-Control as a block or a file" ' + grep "< Cache-Control: public, max-age=29030400, immutable" curl_output ' test_kill_ipfs_daemon