Skip to content

Commit

Permalink
fix(gateway): no duplicate WriteHeader calls (#515)
Browse files Browse the repository at this point in the history
* fix(gateway): do not act on template errors
* docs: changelog
* feat: write error on template execution error

Closes #487
  • Loading branch information
hacdias authored Nov 22, 2023
1 parent 438b8a6 commit d06f7ff
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 14 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ The following emojis are used to highlight certain changes:

### Fixed

* `boxo/gateway`: a panic (which is recovered) could sporadically be triggered inside a CAR request, if the right [conditions were met](https://github.com/ipfs/boxo/pull/511).
* `boxo/gateway`
* a panic (which is recovered) could sporadically be triggered inside a CAR request, if the right [conditions were met](https://github.com/ipfs/boxo/pull/511).
* no longer emits `http: superfluous response.WriteHeader` warnings when an error happens.

### Security

Expand Down
3 changes: 1 addition & 2 deletions gateway/assets/test/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,7 @@ func runTemplate(w http.ResponseWriter, filename string, data interface{}) {
}
err = tpl.Execute(w, data)
if err != nil {
http.Error(w, fmt.Sprintf("failed to execute template: %s", err), http.StatusInternalServerError)
return
_, _ = w.Write([]byte(fmt.Sprintf("error during body generation: %v", err)))
}
}

Expand Down
5 changes: 4 additions & 1 deletion gateway/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,17 @@ func webError(w http.ResponseWriter, r *http.Request, c *Config, err error, defa
if acceptsHTML {
w.Header().Set("Content-Type", "text/html")
w.WriteHeader(code)
_ = assets.ErrorTemplate.Execute(w, assets.ErrorTemplateData{
err = assets.ErrorTemplate.Execute(w, assets.ErrorTemplateData{
GlobalData: assets.GlobalData{
Menu: c.Menu,
},
StatusCode: code,
StatusText: http.StatusText(code),
Error: err.Error(),
})
if err != nil {
_, _ = w.Write([]byte(fmt.Sprintf("error during body generation: %v", err)))
}
} else {
http.Error(w, err.Error(), code)
}
Expand Down
7 changes: 4 additions & 3 deletions gateway/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -912,12 +912,13 @@ func (i *handler) handleSuperfluousNamespace(w http.ResponseWriter, r *http.Requ
// - redirects to intendedURL after a short delay

w.WriteHeader(http.StatusBadRequest)
if err := redirectTemplate.Execute(w, redirectTemplateData{
err = redirectTemplate.Execute(w, redirectTemplateData{
RedirectURL: intendedURL,
SuggestedPath: intendedPath.String(),
ErrorMsg: fmt.Sprintf("invalid path: %q should be %q", r.URL.Path, intendedPath.String()),
}); err != nil {
i.webError(w, r, fmt.Errorf("failed to redirect when fixing superfluous namespace: %w", err), http.StatusBadRequest)
})
if err != nil {
_, _ = w.Write([]byte(fmt.Sprintf("error during body generation: %v", err)))
}

return true
Expand Down
11 changes: 5 additions & 6 deletions gateway/handler_codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,20 +195,19 @@ func (i *handler) serveCodecHTML(ctx context.Context, w http.ResponseWriter, r *
w.Header().Del("Cache-Control")

cidCodec := mc.Code(resolvedPath.RootCid().Prefix().Codec)
if err := assets.DagTemplate.Execute(w, assets.DagTemplateData{
err = assets.DagTemplate.Execute(w, assets.DagTemplateData{
GlobalData: i.getTemplateGlobalData(r, contentPath),
Path: contentPath.String(),
CID: resolvedPath.RootCid().String(),
CodecName: cidCodec.String(),
CodecHex: fmt.Sprintf("0x%x", uint64(cidCodec)),
Node: parseNode(blockCid, blockData),
}); err != nil {
err = fmt.Errorf("failed to generate HTML listing for this DAG: try fetching raw block with ?format=raw: %w", err)
i.webError(w, r, err, http.StatusInternalServerError)
return false
})
if err != nil {
_, _ = w.Write([]byte(fmt.Sprintf("error during body generation: %v", err)))
}

return true
return err == nil
}

// parseNode does a best effort attempt to parse this request's block such that
Expand Down
2 changes: 1 addition & 1 deletion gateway/handler_unixfs_dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func (i *handler) serveDirectory(ctx context.Context, w http.ResponseWriter, r *
rq.logger.Debugw("request processed", "tplDataDNSLink", globalData.DNSLink, "tplDataSize", size, "tplDataBackLink", backLink, "tplDataHash", hash)

if err := assets.DirectoryTemplate.Execute(w, tplData); err != nil {
i.webError(w, r, err, http.StatusInternalServerError)
_, _ = w.Write([]byte(fmt.Sprintf("error during body generation: %v", err)))
return false
}

Expand Down

0 comments on commit d06f7ff

Please sign in to comment.