Skip to content

Commit

Permalink
feat(gateway): ?filename with download=true
Browse files Browse the repository at this point in the history
This implements 'attachment' mode triggered then
?filename parameter is accompanied with &download=true

When Content-Disposition: attachment is detected by a modern browser
it will skip rendering and immediately open the "save as" dialog,
making this useful feature for using IPFS gateway as target of
"Download" links on various websites.

Parameter name was suggested in:
#4177 (comment)
  • Loading branch information
lidel committed Sep 16, 2020
1 parent 48b2f12 commit fd01acd
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
6 changes: 5 additions & 1 deletion core/corehttp/gateway_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 10 additions & 0 deletions docs/gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 6 additions & 1 deletion test/sharness/t0110-gateway.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down

0 comments on commit fd01acd

Please sign in to comment.