@@ -43,8 +43,14 @@ func (i *gatewayHandler) serveCAR(ctx context.Context, w http.ResponseWriter, r
4343 }
4444 setContentDispositionHeader (w , name , "attachment" )
4545
46- // Weak Etag W/ because we can't guarantee byte-for-byte identical responses
47- // (CAR is streamed, and in theory, blocks may arrive from datastore in non-deterministic order)
46+ // Set Cache-Control (same logic as for a regular files)
47+ addCacheControlHeaders (w , r , contentPath , rootCid )
48+
49+ // Weak Etag W/ because we can't guarantee byte-for-byte identical
50+ // responses, but still want to benefit from HTTP Caching. Two CAR
51+ // responses for the same CID and selector will be logically equivalent,
52+ // but when CAR is streamed, then in theory, blocks may arrive from
53+ // datastore in non-deterministic order.
4854 etag := `W/` + getEtag (r , rootCid )
4955 w .Header ().Set ("Etag" , etag )
5056
@@ -55,14 +61,10 @@ func (i *gatewayHandler) serveCAR(ctx context.Context, w http.ResponseWriter, r
5561 }
5662
5763 // Make it clear we don't support range-requests over a car stream
58- // Partial downloads and resumes should be handled using
59- // IPLD selectors: https://github.com/ipfs/go-ipfs/issues/8769
64+ // Partial downloads and resumes should be handled using requests for
65+ // sub-DAGs and IPLD selectors: https://github.com/ipfs/go-ipfs/issues/8769
6066 w .Header ().Set ("Accept-Ranges" , "none" )
6167
62- // Explicit Cache-Control to ensure fresh stream on retry.
63- // CAR stream could be interrupted, and client should be able to resume and get full response, not the truncated one
64- w .Header ().Set ("Cache-Control" , "no-cache, no-transform" )
65-
6668 w .Header ().Set ("Content-Type" , "application/vnd.ipld.car; version=1" )
6769 w .Header ().Set ("X-Content-Type-Options" , "nosniff" ) // no funny business in the browsers :^)
6870
0 commit comments