From 7992025254c70cda1b5fd084b7a8a28b1f06958f Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 19 Jul 2022 22:04:25 +0200 Subject: [PATCH] fix(gw): 404 when a valid DAG is missing link --- core/corehttp/gateway_handler.go | 6 ++++-- core/corehttp/gateway_handler_unixfs.go | 2 +- core/corehttp/gateway_test.go | 8 ++++---- test/sharness/t0110-gateway.sh | 10 +++++++++- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 238473bbbac..2a7ee155f4a 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -19,6 +19,7 @@ import ( cid "github.com/ipfs/go-cid" files "github.com/ipfs/go-ipfs-files" + ipld "github.com/ipfs/go-ipld-format" dag "github.com/ipfs/go-merkledag" mfs "github.com/ipfs/go-mfs" path "github.com/ipfs/go-path" @@ -389,8 +390,7 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request logger.Debugw("serve pretty 404 if present") return } - - webError(w, "ipfs resolve -r "+debugStr(contentPath.String()), err, http.StatusNotFound) + webError(w, "ipfs resolve -r "+debugStr(contentPath.String()), err, http.StatusBadRequest) return } @@ -782,6 +782,8 @@ func webError(w http.ResponseWriter, message string, err error, defaultCode int) webErrorWithCode(w, message, err, http.StatusNotFound) } else if err == routing.ErrNotFound { webErrorWithCode(w, message, err, http.StatusNotFound) + } else if ipld.IsNotFound(err) { + webErrorWithCode(w, message, err, http.StatusNotFound) } else if err == context.DeadlineExceeded { webErrorWithCode(w, message, err, http.StatusRequestTimeout) } else { diff --git a/core/corehttp/gateway_handler_unixfs.go b/core/corehttp/gateway_handler_unixfs.go index 0aec83a8b13..75d51d93a2d 100644 --- a/core/corehttp/gateway_handler_unixfs.go +++ b/core/corehttp/gateway_handler_unixfs.go @@ -22,7 +22,7 @@ func (i *gatewayHandler) serveUnixFS(ctx context.Context, w http.ResponseWriter, // Handling UnixFS dr, err := i.api.Unixfs().Get(ctx, resolvedPath) if err != nil { - webError(w, "ipfs cat "+html.EscapeString(contentPath.String()), err, http.StatusNotFound) + webError(w, "ipfs cat "+html.EscapeString(contentPath.String()), err, http.StatusBadRequest) return } defer dr.Close() diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index b6b504907aa..18fe6ce17e3 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -235,8 +235,8 @@ func TestGatewayGet(t *testing.T) { {"127.0.0.1:8080", "/", http.StatusNotFound, "404 page not found\n"}, {"127.0.0.1:8080", "/" + k.Cid().String(), http.StatusNotFound, "404 page not found\n"}, {"127.0.0.1:8080", k.String(), http.StatusOK, "fnord"}, - {"127.0.0.1:8080", "/ipns/nxdomain.example.com", http.StatusNotFound, "ipfs resolve -r /ipns/nxdomain.example.com: " + namesys.ErrResolveFailed.Error() + "\n"}, - {"127.0.0.1:8080", "/ipns/%0D%0A%0D%0Ahello", http.StatusNotFound, "ipfs resolve -r /ipns/\\r\\n\\r\\nhello: " + namesys.ErrResolveFailed.Error() + "\n"}, + {"127.0.0.1:8080", "/ipns/nxdomain.example.com", http.StatusBadRequest, "ipfs resolve -r /ipns/nxdomain.example.com: " + namesys.ErrResolveFailed.Error() + "\n"}, + {"127.0.0.1:8080", "/ipns/%0D%0A%0D%0Ahello", http.StatusBadRequest, "ipfs resolve -r /ipns/\\r\\n\\r\\nhello: " + namesys.ErrResolveFailed.Error() + "\n"}, {"127.0.0.1:8080", "/ipns/example.com", http.StatusOK, "fnord"}, {"example.com", "/", http.StatusOK, "fnord"}, @@ -244,8 +244,8 @@ func TestGatewayGet(t *testing.T) { {"double.example.com", "/", http.StatusOK, "fnord"}, {"triple.example.com", "/", http.StatusOK, "fnord"}, {"working.example.com", k.String(), http.StatusNotFound, "ipfs resolve -r /ipns/working.example.com" + k.String() + ": no link named \"ipfs\" under " + k.Cid().String() + "\n"}, - {"broken.example.com", "/", http.StatusNotFound, "ipfs resolve -r /ipns/broken.example.com/: " + namesys.ErrResolveFailed.Error() + "\n"}, - {"broken.example.com", k.String(), http.StatusNotFound, "ipfs resolve -r /ipns/broken.example.com" + k.String() + ": " + namesys.ErrResolveFailed.Error() + "\n"}, + {"broken.example.com", "/", http.StatusBadRequest, "ipfs resolve -r /ipns/broken.example.com/: " + namesys.ErrResolveFailed.Error() + "\n"}, + {"broken.example.com", k.String(), http.StatusBadRequest, "ipfs resolve -r /ipns/broken.example.com" + k.String() + ": " + namesys.ErrResolveFailed.Error() + "\n"}, // This test case ensures we don't treat the TLD as a file extension. {"example.man", "/", http.StatusOK, "fnord"}, } { diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh index 8cf28dbf41a..a1e8f286491 100755 --- a/test/sharness/t0110-gateway.sh +++ b/test/sharness/t0110-gateway.sh @@ -88,10 +88,14 @@ test_expect_success "GET IPFS directory with index.html and trailing slash retur test_should_contain \"hello i am a webpage\" response_with_slash " -test_expect_success "GET IPFS nonexistent file returns code expected (404)" ' +test_expect_success "GET IPFS nonexistent file returns 404 (Not Found)" ' test_curl_resp_http_code "http://127.0.0.1:$port/ipfs/$HASH2/pleaseDontAddMe" "HTTP/1.1 404 Not Found" ' +test_expect_success "GET IPFS invalid CID returns 400 (Bad Request)" ' + test_curl_resp_http_code "http://127.0.0.1:$port/ipfs/QmInvalid/pleaseDontAddMe" "HTTP/1.1 400 Bad Request" +' + # https://github.com/ipfs/go-ipfs/issues/8230 test_expect_success "GET IPFS inlined zero-length data object returns ok code (200)" ' curl -sD - "http://127.0.0.1:$port/ipfs/bafkqaaa" > empty_ok_response && @@ -105,6 +109,10 @@ test_expect_success "GET /ipfs/ipfs/{cid} returns redirect to the valid path" ' test_should_contain "" response_with_double_ipfs_ns ' +test_expect_success "GET invalid IPNS root returns 400 (Bad Request)" ' + test_curl_resp_http_code "http://127.0.0.1:$port/ipns/QmInvalid/pleaseDontAddMe" "HTTP/1.1 400 Bad Request" +' + test_expect_failure "GET IPNS path succeeds" ' ipfs name publish --allow-offline "$HASH" && PEERID=$(ipfs config Identity.PeerID) &&