Skip to content

Commit

Permalink
refactor: use abort handler from #9333
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Oct 13, 2022
1 parent 634b0a5 commit bb8be14
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 20 deletions.
23 changes: 23 additions & 0 deletions core/corehttp/gateway_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1085,3 +1085,26 @@ func (i *gatewayHandler) setCommonHeaders(w http.ResponseWriter, r *http.Request

return nil
}

// abortConn forcefully closes an HTTP connection, leading to a network error on the
// client side. This is a way of showing the client that there was an error while streaming
// the contents since there are no good ways of showing an error during a stream.
func abortConn(w http.ResponseWriter) {
hj, ok := w.(http.Hijacker)
if !ok {
// If we could not Hijack the connection (such as in HTTP/2.x) connections, we
// panic using http.ErrAbortHandler, which aborts the response.
// https://pkg.go.dev/net/http#ErrAbortHandler
panic(http.ErrAbortHandler)
}

conn, _, err := hj.Hijack()
if err != nil {
panic(http.ErrAbortHandler)
}

err = conn.Close()
if err != nil {
panic(http.ErrAbortHandler)
}
}
22 changes: 2 additions & 20 deletions core/corehttp/gateway_handler_tar.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,25 +67,7 @@ func (i *gatewayHandler) serveTAR(ctx context.Context, w http.ResponseWriter, r
w.Header().Set("Content-Type", "application/x-tar")

// The TAR has a top-level directory (or file) named by the CID.
if tarErr := tarw.WriteFile(file, resolvedPath.Cid().String()); tarErr != nil {
// There are no good ways of showing an error during a stream. Therefore, we try
// to hijack the connection to forcefully close it, causing a network error.
hj, ok := w.(http.Hijacker)
if !ok {
// If we could not Hijack the connection, we write the original error. This will hopefully
// corrupt the generated TAR file, such that the client will receive an error unpacking.
webError(w, "could not build tar archive", tarErr, http.StatusInternalServerError)
return
}

conn, _, err := hj.Hijack()
if err != nil {
// Deliberately pass the original tar error here instead of the hijacking error.
webError(w, "could not build tar archive", tarErr, http.StatusInternalServerError)
return
}

conn.Close()
return
if err := tarw.WriteFile(file, resolvedPath.Cid().String()); err != nil {
abortConn(w)
}
}

0 comments on commit bb8be14

Please sign in to comment.