diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index b9e7f144b9d..0c708f87be4 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -261,7 +261,11 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request urlFilename := r.URL.Query().Get("filename") var name string if urlFilename != "" { - w.Header().Set("Content-Disposition", fmt.Sprintf("inline; filename*=UTF-8''%s", url.PathEscape(urlFilename))) + disposition := "inline" + if r.URL.Query().Get("download") == "true" { + disposition = "attachment" + } + w.Header().Set("Content-Disposition", fmt.Sprintf("%s; filename*=UTF-8''%s", disposition, url.PathEscape(urlFilename))) name = urlFilename } else { name = getFilename(urlPath) diff --git a/docs/gateway.md b/docs/gateway.md index 2344ee55ea8..dab41e09171 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -49,6 +49,16 @@ your query string to explicitly specify the filename. For example: > https://ipfs.io/ipfs/QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG?filename=hello_world.txt +When you try to save above page, you browser will use passed `filename` instead of a CID. + +## Downloads + +It is possible to skip browser rendering of supported filetypes (plain text, +images, audio, video, PDF) and trigger immediate "save as" dialog by appending +`&download=true`: + +> https://ipfs.io/ipfs/QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG?filename=hello_world.txt&download=true + ## MIME-Types TODO diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh index 2a1f58c71a4..3880880c274 100755 --- a/test/sharness/t0110-gateway.sh +++ b/test/sharness/t0110-gateway.sh @@ -31,11 +31,16 @@ test_expect_success "GET IPFS path succeeds" ' curl -sfo actual "http://127.0.0.1:$port/ipfs/$HASH" ' -test_expect_success "GET IPFS path with explicit filename succeeds with proper header" " +test_expect_success "GET IPFS path with explicit ?filename succeeds with proper header" " curl -fo actual -D actual_headers 'http://127.0.0.1:$port/ipfs/$HASH?filename=testтест' && grep -F \"Content-Disposition: inline; filename*=UTF-8''test%D1%82%D0%B5%D1%81%D1%82\" actual_headers " +test_expect_success "GET IPFS path with explicit ?filename and download=true succeeds with proper header" " + curl -fo actual -D actual_headers 'http://127.0.0.1:$port/ipfs/$HASH?filename=testтест&download=true' && + grep -F \"Content-Disposition: attachment; filename*=UTF-8''test%D1%82%D0%B5%D1%81%D1%82\" actual_headers +" + # https://github.com/ipfs/go-ipfs/issues/4025#issuecomment-342250616 test_expect_success "GET for Service Worker registration outside of an IPFS content root errors" " curl -H 'Service-Worker: script' -svX GET 'http://127.0.0.1:$port/ipfs/$HASH?filename=sw.js' > curl_sw_out 2>&1 &&