From 47e7f693ebc22f9f7b5e1876fd16b31c46a83307 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 4 Oct 2018 15:36:29 -0700 Subject: [PATCH 1/3] don't use the domain name as a filename in /ipns/a.com fixes #5369 License: MIT Signed-off-by: Steven Allen --- core/corehttp/gateway_handler.go | 10 +++++++++- core/corehttp/gateway_test.go | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 9e0b8e1ec..bba9dde90 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -266,7 +266,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr w.Header().Set("Content-Disposition", fmt.Sprintf("inline; filename*=UTF-8''%s", url.PathEscape(urlFilename))) name = urlFilename } else { - name = gopath.Base(urlPath) + name = getFilename(urlPath) } i.serveFile(w, r, name, modtime, dr) return @@ -624,3 +624,11 @@ func webErrorWithCode(w http.ResponseWriter, message string, err error, code int func internalWebError(w http.ResponseWriter, err error) { webErrorWithCode(w, "internalWebError", err, http.StatusInternalServerError) } + +func getFilename(s string) string { + if (strings.HasPrefix(s, ipfsPathPrefix) || strings.HasPrefix(s, ipnsPathPrefix)) && strings.Count(gopath.Clean(s), "/") <= 2 { + // Don't want to treat ipfs.io in /ipns/ipfs.io as a filename. + return "" + } + return gopath.Base(s) +} diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 83e2ea5e8..106f4c214 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -153,6 +153,7 @@ func TestGatewayGet(t *testing.T) { ns["/ipns/double.example.com"] = path.FromString("/ipns/working.example.com") ns["/ipns/triple.example.com"] = path.FromString("/ipns/double.example.com") ns["/ipns/broken.example.com"] = path.FromString("/ipns/" + k) + ns["/ipns/example.man"] = path.FromString("/ipfs/" + k) t.Log(ts.URL) for _, test := range []struct { @@ -175,6 +176,7 @@ func TestGatewayGet(t *testing.T) { {"working.example.com", "/ipfs/" + k, http.StatusNotFound, "ipfs resolve -r /ipns/working.example.com/ipfs/" + k + ": no link by that name\n"}, {"broken.example.com", "/", http.StatusNotFound, "ipfs resolve -r /ipns/broken.example.com/: " + namesys.ErrResolveFailed.Error() + "\n"}, {"broken.example.com", "/ipfs/" + k, http.StatusNotFound, "ipfs resolve -r /ipns/broken.example.com/ipfs/" + k + ": " + namesys.ErrResolveFailed.Error() + "\n"}, + {"example.man", "/", http.StatusOK, "fnord"}, } { var c http.Client r, err := http.NewRequest("GET", ts.URL+test.path, nil) @@ -190,6 +192,10 @@ func TestGatewayGet(t *testing.T) { continue } defer resp.Body.Close() + contentType := resp.Header.Get("Content-Type") + if contentType != "text/plain; charset=utf-8" { + t.Errorf("expected content type to be text/plain, got %s", contentType) + } if resp.StatusCode != test.status { t.Errorf("got %d, expected %d from %s", resp.StatusCode, test.status, urlstr) continue From afd81fd5dd973a065b7002fb4176f507a2c728df Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 4 Oct 2018 21:42:07 -0700 Subject: [PATCH 2/3] gateway test: document why .man License: MIT Signed-off-by: Steven Allen --- core/corehttp/gateway_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 106f4c214..bfd7b506b 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -153,6 +153,11 @@ func TestGatewayGet(t *testing.T) { ns["/ipns/double.example.com"] = path.FromString("/ipns/working.example.com") ns["/ipns/triple.example.com"] = path.FromString("/ipns/double.example.com") ns["/ipns/broken.example.com"] = path.FromString("/ipns/" + k) + // We picked .man because: + // 1. It's a valid TLD. + // 2. Go treats it as the file extension for "man" files (even though + // nobody actually *uses* this extension, AFAIK). + // 3. Go accepts "fnord" (the test value) as a valid man file. ns["/ipns/example.man"] = path.FromString("/ipfs/" + k) t.Log(ts.URL) @@ -176,6 +181,7 @@ func TestGatewayGet(t *testing.T) { {"working.example.com", "/ipfs/" + k, http.StatusNotFound, "ipfs resolve -r /ipns/working.example.com/ipfs/" + k + ": no link by that name\n"}, {"broken.example.com", "/", http.StatusNotFound, "ipfs resolve -r /ipns/broken.example.com/: " + namesys.ErrResolveFailed.Error() + "\n"}, {"broken.example.com", "/ipfs/" + k, http.StatusNotFound, "ipfs resolve -r /ipns/broken.example.com/ipfs/" + k + ": " + namesys.ErrResolveFailed.Error() + "\n"}, + // This test case ensures we don't treat the TLD as a file extension. {"example.man", "/", http.StatusOK, "fnord"}, } { var c http.Client From f498459ad2934a46578e97f4d96bd92d68eed5a2 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 5 Oct 2018 11:24:36 -0700 Subject: [PATCH 3/3] gateway_test: comment on platform dependence License: MIT Signed-off-by: Steven Allen --- core/corehttp/gateway_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index bfd7b506b..ce178ffed 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -157,7 +157,9 @@ func TestGatewayGet(t *testing.T) { // 1. It's a valid TLD. // 2. Go treats it as the file extension for "man" files (even though // nobody actually *uses* this extension, AFAIK). - // 3. Go accepts "fnord" (the test value) as a valid man file. + // + // Unfortunately, this may not work on all platforms as file type + // detection is platform dependent. ns["/ipns/example.man"] = path.FromString("/ipfs/" + k) t.Log(ts.URL)