diff --git a/core/corehttp/gateway_handler_block.go b/core/corehttp/gateway_handler_block.go index 8d6ce0f3686..b545d2e51de 100644 --- a/core/corehttp/gateway_handler_block.go +++ b/core/corehttp/gateway_handler_block.go @@ -31,7 +31,12 @@ func (i *gatewayHandler) serveRawBlock(ctx context.Context, w http.ResponseWrite content := bytes.NewReader(block) // Set Content-Disposition - name := blockCid.String() + ".bin" + var name string + if urlFilename := r.URL.Query().Get("filename"); urlFilename != "" { + name = urlFilename + } else { + name = blockCid.String() + ".bin" + } setContentDispositionHeader(w, name, "attachment") // Set remaining headers diff --git a/core/corehttp/gateway_handler_car.go b/core/corehttp/gateway_handler_car.go index 1958088706e..e6d2f663d78 100644 --- a/core/corehttp/gateway_handler_car.go +++ b/core/corehttp/gateway_handler_car.go @@ -35,7 +35,12 @@ func (i *gatewayHandler) serveCAR(ctx context.Context, w http.ResponseWriter, r rootCid := resolvedPath.Cid() // Set Content-Disposition - name := rootCid.String() + ".car" + var name string + if urlFilename := r.URL.Query().Get("filename"); urlFilename != "" { + name = urlFilename + } else { + name = rootCid.String() + ".car" + } setContentDispositionHeader(w, name, "attachment") // Weak Etag W/ because we can't guarantee byte-for-byte identical responses diff --git a/test/sharness/t0117-gateway-block.sh b/test/sharness/t0117-gateway-block.sh index c9e3a4713c8..46cb8af3e3c 100755 --- a/test/sharness/t0117-gateway-block.sh +++ b/test/sharness/t0117-gateway-block.sh @@ -49,6 +49,12 @@ test_expect_success "Create text fixtures" ' grep "< X-Content-Type-Options: nosniff" curl_output ' + test_expect_success "GET for application/vnd.ipld.raw with query filename includes Content-Disposition with custom filename" ' + curl -svX GET -H "Accept: application/vnd.ipld.raw" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/dir/ascii.txt?filename=foobar.bin" >/dev/null 2>curl_output_filename && + cat curl_output_filename && + grep "< Content-Disposition: attachment\; filename=\"foobar.bin\"" curl_output_filename + ' + # Cache control HTTP headers # (basic checks, detailed behavior is tested in t0116-gateway-cache.sh) diff --git a/test/sharness/t0118-gateway-car.sh b/test/sharness/t0118-gateway-car.sh index 796c3c33947..5b0306e0717 100755 --- a/test/sharness/t0118-gateway-car.sh +++ b/test/sharness/t0118-gateway-car.sh @@ -110,6 +110,12 @@ test_launch_ipfs_daemon_without_network grep "< Accept-Ranges: none" curl_output ' + test_expect_success "GET for application/vnd.ipld.car with query filename includes Content-Disposition with custom filename" ' + curl -svX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt?filename=foobar.car" > curl_output_filename 2>&1 && + cat curl_output_filename && + grep "< Content-Disposition: attachment\; filename=\"foobar.car\"" curl_output_filename + ' + # Cache control HTTP headers test_expect_success "GET response for application/vnd.ipld.car includes a weak Etag" '