Skip to content

Commit

Permalink
Merge pull request #7677 from ipfs/feat/content-disposition-attachment
Browse files Browse the repository at this point in the history
feat(gateway): Content-Disposition improvements
  • Loading branch information
aschmahmann authored Oct 2, 2020
2 parents 8e6358a + 19ec5f4 commit 9b1171d
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
10 changes: 9 additions & 1 deletion core/corehttp/gateway_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ const (
ipnsPathPrefix = "/ipns/"
)

var onlyAscii = regexp.MustCompile("[[:^ascii:]]")

// gatewayHandler is a HTTP handler that serves IPFS objects (accessible by default at /ipfs/<path>)
// (it serves requests like GET /ipfs/QmVRzPKPzNtSrEzBFm2UZfxmPAgnaLke4DMcerbsGGSaFe/link)
type gatewayHandler struct {
Expand Down Expand Up @@ -261,7 +263,13 @@ 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"
}
utf8Name := url.PathEscape(urlFilename)
asciiName := url.PathEscape(onlyAscii.ReplaceAllLiteralString(urlFilename, "_"))
w.Header().Set("Content-Disposition", fmt.Sprintf("%s; filename=\"%s\"; filename*=UTF-8''%s", disposition, asciiName, utf8Name))
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
11 changes: 8 additions & 3 deletions test/sharness/t0110-gateway.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ 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" "
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 succeeds with proper header" "
curl -fo actual -D actual_headers 'http://127.0.0.1:$port/ipfs/$HASH?filename=testтест.pdf' &&
grep -F 'Content-Disposition: inline; filename=\"test____.pdf\"; filename*=UTF-8'\'\''test%D1%82%D0%B5%D1%81%D1%82.pdf' 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тест.mp4&download=true' &&
grep -F 'Content-Disposition: attachment; filename=\"test____.mp4\"; filename*=UTF-8'\'\''test%D1%82%D0%B5%D1%81%D1%82.mp4' actual_headers
"

# https://github.com/ipfs/go-ipfs/issues/4025#issuecomment-342250616
Expand Down

0 comments on commit 9b1171d

Please sign in to comment.