diff options
author | Alexey Sharov <www.pismeco@gmail.com> | 2018-10-01 19:39:39 +0800 |
---|---|---|
committer | Anton Evangelatov <anton.evangelatov@gmail.com> | 2018-10-01 19:39:39 +0800 |
commit | dc5d643bb59812cda578fac941c2f1da316bc9d7 (patch) | |
tree | 7405f387672f0548eb4734a93581780c96cee7a9 /swarm/api/http | |
parent | b69942befeb9f1af55cad0f91953bdaea2ea3efb (diff) | |
download | dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.tar dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.tar.gz dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.tar.bz2 dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.tar.lz dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.tar.xz dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.tar.zst dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.zip |
cmd/swarm, swarm: cross-platform Content-Type detection (#17782)
- Mime types generator (Standard "mime" package rely on system-settings, see mime.osInitMime)
- Changed swarm/api.Upload:
- simplify I/O throttling by semaphore primitive and use file name where possible
- f.Close() must be called in Defer - otherwise panic or future added early return will cause leak of file descriptors
- one error was suppressed
Diffstat (limited to 'swarm/api/http')
-rw-r--r-- | swarm/api/http/server.go | 26 | ||||
-rw-r--r-- | swarm/api/http/server_test.go | 47 |
2 files changed, 57 insertions, 16 deletions
diff --git a/swarm/api/http/server.go b/swarm/api/http/server.go index 87ef05baa..5ec69373d 100644 --- a/swarm/api/http/server.go +++ b/swarm/api/http/server.go @@ -201,6 +201,13 @@ func (s *Server) HandleBzzGet(w http.ResponseWriter, r *http.Request) { defer reader.Close() w.Header().Set("Content-Type", "application/x-tar") + + fileName := uri.Addr + if found := path.Base(uri.Path); found != "" && found != "." && found != "/" { + fileName = found + } + w.Header().Set("Content-Disposition", fmt.Sprintf("inline; filename=\"%s.tar\"", fileName)) + w.WriteHeader(http.StatusOK) io.Copy(w, reader) return @@ -616,7 +623,7 @@ func (s *Server) HandleGetResource(w http.ResponseWriter, r *http.Request) { // All ok, serve the retrieved update log.Debug("Found update", "view", view.Hex(), "ruid", ruid) - w.Header().Set("Content-Type", "application/octet-stream") + w.Header().Set("Content-Type", api.MimeOctetStream) http.ServeContent(w, r, "", time.Now(), bytes.NewReader(data)) } @@ -690,11 +697,9 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *http.Request) { case uri.Raw(): // allow the request to overwrite the content type using a query // parameter - contentType := "application/octet-stream" if typ := r.URL.Query().Get("content_type"); typ != "" { - contentType = typ + w.Header().Set("Content-Type", typ) } - w.Header().Set("Content-Type", contentType) http.ServeContent(w, r, "", time.Now(), reader) case uri.Hash(): w.Header().Set("Content-Type", "text/plain") @@ -850,8 +855,17 @@ func (s *Server) HandleGetFile(w http.ResponseWriter, r *http.Request) { return } - w.Header().Set("Content-Type", contentType) - http.ServeContent(w, r, "", time.Now(), newBufferedReadSeeker(reader, getFileBufferSize)) + if contentType != "" { + w.Header().Set("Content-Type", contentType) + } + + fileName := uri.Addr + if found := path.Base(uri.Path); found != "" && found != "." && found != "/" { + fileName = found + } + w.Header().Set("Content-Disposition", fmt.Sprintf("inline; filename=\"%s\"", fileName)) + + http.ServeContent(w, r, fileName, time.Now(), newBufferedReadSeeker(reader, getFileBufferSize)) } // The size of buffer used for bufio.Reader on LazyChunkReader passed to diff --git a/swarm/api/http/server_test.go b/swarm/api/http/server_test.go index 8ba4e55c3..817519a30 100644 --- a/swarm/api/http/server_test.go +++ b/swarm/api/http/server_test.go @@ -32,6 +32,7 @@ import ( "net/http" "net/url" "os" + "path" "strconv" "strings" "testing" @@ -764,6 +765,16 @@ func testBzzTar(encrypted bool, t *testing.T) { } defer resp2.Body.Close() + if h := resp2.Header.Get("Content-Type"); h != "application/x-tar" { + t.Fatalf("Content-Type header expected: application/x-tar, got: %s", h) + } + + expectedFileName := string(swarmHash) + ".tar" + expectedContentDisposition := fmt.Sprintf("inline; filename=\"%s\"", expectedFileName) + if h := resp2.Header.Get("Content-Disposition"); h != expectedContentDisposition { + t.Fatalf("Content-Disposition header expected: %s, got: %s", expectedContentDisposition, h) + } + file, err := ioutil.TempFile("", "swarm-downloaded-tarball") if err != nil { t.Fatal(err) @@ -1099,7 +1110,7 @@ func TestModify(t *testing.T) { res, body := httpDo(testCase.method, testCase.uri, reqBody, testCase.headers, testCase.verbose, t) if res.StatusCode != testCase.expectedStatusCode { - t.Fatalf("expected status code %d but got %d", testCase.expectedStatusCode, res.StatusCode) + t.Fatalf("expected status code %d but got %d, %s", testCase.expectedStatusCode, res.StatusCode, body) } if testCase.assertResponseBody != "" && !strings.Contains(body, testCase.assertResponseBody) { t.Log(body) @@ -1210,19 +1221,25 @@ func TestBzzGetFileWithResolver(t *testing.T) { hash := common.HexToHash(string(swarmHash)) resolver.hash = &hash for _, v := range []struct { - addr string - path string - expectedStatusCode int + addr string + path string + expectedStatusCode int + expectedContentType string + expectedFileName string }{ { - addr: string(swarmHash), - path: fileNames[0], - expectedStatusCode: http.StatusOK, + addr: string(swarmHash), + path: fileNames[0], + expectedStatusCode: http.StatusOK, + expectedContentType: "text/plain", + expectedFileName: path.Base(fileNames[0]), }, { - addr: "somebogusensname", - path: fileNames[0], - expectedStatusCode: http.StatusOK, + addr: "somebogusensname", + path: fileNames[0], + expectedStatusCode: http.StatusOK, + expectedContentType: "text/plain", + expectedFileName: path.Base(fileNames[0]), }, } { req, err := http.NewRequest("GET", fmt.Sprintf(srv.URL+"/bzz:/%s/%s", v.addr, v.path), nil) @@ -1237,6 +1254,16 @@ func TestBzzGetFileWithResolver(t *testing.T) { if serverResponse.StatusCode != v.expectedStatusCode { t.Fatalf("expected %d, got %d", v.expectedStatusCode, serverResponse.StatusCode) } + + if h := serverResponse.Header.Get("Content-Type"); h != v.expectedContentType { + t.Fatalf("Content-Type header expected: %s, got %s", v.expectedContentType, h) + } + + expectedContentDisposition := fmt.Sprintf("inline; filename=\"%s\"", v.expectedFileName) + if h := serverResponse.Header.Get("Content-Disposition"); h != expectedContentDisposition { + t.Fatalf("Content-Disposition header expected: %s, got: %s", expectedContentDisposition, h) + } + } } |