diff --git a/CHANGELOG.md b/CHANGELOG.md index 29356a8a1..fcb13469c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ The following emojis are used to highlight certain changes: ### Fixed +- `boxo/gateway` now correctly returns 404 Status Not Found instead of 500 when the requested content cannot be found due to offline exchange, gateway running in no-fetch (non-recursive) mode, or a similar restriction that only serves a specific set of CIDs. - `bitswap/client` fix memory leak in BlockPresenceManager due to unlimited map growth. ### Security diff --git a/gateway/errors.go b/gateway/errors.go index c245ae4c1..5ea15ff18 100644 --- a/gateway/errors.go +++ b/gateway/errors.go @@ -13,6 +13,7 @@ import ( "github.com/ipfs/boxo/path" "github.com/ipfs/boxo/path/resolver" "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/schema" ) @@ -185,10 +186,10 @@ func webError(w http.ResponseWriter, r *http.Request, c *Config, err error, defa switch { case errors.Is(err, &cid.ErrInvalidCid{}): code = http.StatusBadRequest - case isErrNotFound(err): - code = http.StatusNotFound case isErrContentBlocked(err): code = http.StatusGone + case isErrNotFound(err): + code = http.StatusNotFound case errors.Is(err, context.DeadlineExceeded): code = http.StatusGatewayTimeout } @@ -226,6 +227,10 @@ func isErrNotFound(err error) bool { return true } + if ipld.IsNotFound(err) { + return true + } + // Checks if err is of a type that does not implement the .Is interface and // cannot be directly compared to. Therefore, errors.Is cannot be used. for { diff --git a/gateway/gateway_test.go b/gateway/gateway_test.go index 5c309a571..3c1ab3f72 100644 --- a/gateway/gateway_test.go +++ b/gateway/gateway_test.go @@ -924,7 +924,7 @@ func TestErrorBubblingFromBackend(t *testing.T) { }) } - testError("500 Not Found from IPLD", &ipld.ErrNotFound{}, http.StatusInternalServerError) + testError("404 Not Found from IPLD", &ipld.ErrNotFound{}, http.StatusNotFound) testError("404 Not Found from path resolver", &resolver.ErrNoLink{}, http.StatusNotFound) testError("502 Bad Gateway", ErrBadGateway, http.StatusBadGateway) testError("504 Gateway Timeout", ErrGatewayTimeout, http.StatusGatewayTimeout)