Skip to content

Commit

Permalink
feat(gateway): add DisableHTMLErrors option
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Sep 21, 2023
1 parent 0d10169 commit 3acb593
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ The following emojis are used to highlight certain changes:
### Added

* ✨ The `routing/http` implements Delegated Peer Routing introduced in [IPIP-417](https://github.com/ipfs/specs/pull/417).
* An option `DisableHTMLErrors` has been added to `gateway.Config`. When this option
is `true`, pretty HTML error pages for web browsers are disabled. Instead, a
`text/plain` page with the raw error message as the body is returned.

### Changed

Expand Down
2 changes: 1 addition & 1 deletion gateway/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func webError(w http.ResponseWriter, r *http.Request, c *Config, err error, defa
code = gwErr.StatusCode
}

acceptsHTML := strings.Contains(r.Header.Get("Accept"), "text/html")
acceptsHTML := !c.DisableHTMLErrors && strings.Contains(r.Header.Get("Accept"), "text/html")
if acceptsHTML {
w.Header().Set("Content-Type", "text/html")
w.WriteHeader(code)
Expand Down
34 changes: 34 additions & 0 deletions gateway/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,38 @@ func TestWebError(t *testing.T) {
webError(w, r, config, err, http.StatusInternalServerError)
require.Equal(t, http.StatusTeapot, w.Result().StatusCode)
})

t.Run("Error is sent as HTML when 'Accept' header contains 'text/html'", func(t *testing.T) {
t.Parallel()

w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/blah", nil)
r.Header.Set("Accept", "something/else, text/html")
webError(w, r, config, NewErrorStatusCodeFromStatus(http.StatusTeapot), http.StatusInternalServerError)
require.Equal(t, http.StatusTeapot, w.Result().StatusCode)
require.Contains(t, w.Result().Header.Get("Content-Type"), "text/html")
})

t.Run("Error is sent as plain text when 'Accept' header does not contain 'text/html'", func(t *testing.T) {
t.Parallel()

w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/blah", nil)
r.Header.Set("Accept", "application/json")
webError(w, r, config, NewErrorStatusCodeFromStatus(http.StatusTeapot), http.StatusInternalServerError)
require.Equal(t, http.StatusTeapot, w.Result().StatusCode)
require.Contains(t, w.Result().Header.Get("Content-Type"), "text/plain")
})

t.Run("Error is sent as plain text when 'Accept' header contains 'text/html' and config.DisableHTMLErrors is true", func(t *testing.T) {
t.Parallel()

config := &Config{Headers: map[string][]string{}, DisableHTMLErrors: true}
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/blah", nil)
r.Header.Set("Accept", "something/else, text/html")
webError(w, r, config, NewErrorStatusCodeFromStatus(http.StatusTeapot), http.StatusInternalServerError)
require.Equal(t, http.StatusTeapot, w.Result().StatusCode)
require.Contains(t, w.Result().Header.Get("Content-Type"), "text/plain")
})
}
5 changes: 5 additions & 0 deletions gateway/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ type Config struct {
// overridden per FQDN in PublicGateways. To be used with WithHostname.
NoDNSLink bool

// DisableHTMLErrors disables pretty HTML pages when an error occurs. Instead, a `text/plain`
// page will be sent with the raw error message. This can be useful if this gateway
// is being proxied by other service, which wants to use the error message.
DisableHTMLErrors bool

// PublicGateways configures the behavior of known public gateways. Each key is
// a fully qualified domain name (FQDN). To be used with WithHostname.
PublicGateways map[string]*PublicGateway
Expand Down

0 comments on commit 3acb593

Please sign in to comment.