diff --git a/commands/http/handler.go b/commands/http/handler.go index bf74cec9164..27b386a59d6 100644 --- a/commands/http/handler.go +++ b/commands/http/handler.go @@ -14,6 +14,7 @@ import ( cors "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/rs/cors" context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" "github.com/ipfs/go-ipfs/repo/config" + "github.com/ipfs/go-ipfs/util" cmds "github.com/ipfs/go-ipfs/commands" logging "github.com/ipfs/go-ipfs/vendor/QmQg1J6vikuXF9oDvm4wpdeAUvvkVEKW1EYDw9HhTMnP2b/go-log" @@ -61,12 +62,6 @@ const ( ACACredentials = "Access-Control-Allow-Credentials" ) -var mimeTypes = map[string]string{ - cmds.JSON: "application/json", - cmds.XML: "application/xml", - cmds.Text: "text/plain", -} - type ServerConfig struct { // Headers is an optional map of headers that is written out. Headers map[string][]string @@ -191,18 +186,18 @@ func guessMimeType(res cmds.Response) (string, error) { return "", errors.New("no encoding option set") } - if m, ok := mimeTypes[enc]; ok { + if m, ok := util.MimeTypes[enc]; ok { return m, nil } - return mimeTypes[cmds.JSON], nil + return util.MimeTypes[cmds.JSON], nil } func sendResponse(w http.ResponseWriter, r *http.Request, res cmds.Response, req cmds.Request) { h := w.Header() // Expose our agent to allow identification - h.Set("Server", "go-ipfs/" + config.CurrentVersionNumber) - + h.Set("Server", "go-ipfs/"+config.CurrentVersionNumber) + mime, err := guessMimeType(res) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) @@ -236,7 +231,9 @@ func sendResponse(w http.ResponseWriter, r *http.Request, res cmds.Response, req if _, ok := res.Output().(io.Reader); ok { // set streams output type to text to avoid issues with browsers rendering // html pages on priveleged api ports - mime = "text/plain" + if !util.XssSafeMimeType(mime) { + mime = util.MimeTypes[cmds.Text] + } h.Set(streamHeader, "1") } diff --git a/commands/response.go b/commands/response.go index 577b86a8b4f..73b8d1958e0 100644 --- a/commands/response.go +++ b/commands/response.go @@ -38,6 +38,8 @@ type EncodingType string const ( JSON = "json" XML = "xml" + Tar = "tar" + Gzip = "gzip" Text = "text" // TODO: support more encoding types ) diff --git a/core/commands/get.go b/core/commands/get.go index e133a5f9c91..fcbaf8b316e 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -69,6 +69,12 @@ may also specify the level of compression by specifying '-l=<1-9>'. return } + // set the correct mime type for tar stream + req.SetOption(cmds.EncShort, cmds.Tar) + if cmplvl != gzip.NoCompression { + req.SetOption(cmds.EncShort, cmds.Gzip) + } + archive, _, _ := req.Option("archive").Bool() reader, err := uarchive.DagArchive(ctx, dn, p.String(), node.DAG, archive, cmplvl) if err != nil { diff --git a/test/sharness/t0090-get.sh b/test/sharness/t0090-get.sh index b678b58237b..30afa4ccf3b 100755 --- a/test/sharness/t0090-get.sh +++ b/test/sharness/t0090-get.sh @@ -119,6 +119,9 @@ test_get_cmd # should work online test_launch_ipfs_daemon test_get_cmd +test_expect_success "ipfs get response has the correct content-type" ' + curl -I "http://localhost:$PORT_API/api/v0/get?arg=$HASH" | grep "^Content-Type: application/x-tar" +' test_kill_ipfs_daemon test_done