fix(chromium): report unreachable resources behind the pinning proxy as loading failures

This commit is contained in:
Julien Neuhart
2026-10-13 19:45:06 +02:00
parent e1d714e5e0
commit db150b7733
6 changed files with 87 additions and 10 deletions

View File

@@ -522,7 +522,7 @@ func (p *pinningProxy) handleForward(w http.ResponseWriter, req *http.Request) {
} else {
p.logger.WarnContext(req.Context(), fmt.Sprintf("forward RoundTrip failed for '%s': %s", req.URL, err))
}
http.Error(w, "upstream error", http.StatusBadGateway)
resetClient(w)
return
}
defer resp.Body.Close()
@@ -585,3 +585,23 @@ func isClientCancellation(ctx context.Context, err error) bool {
func (p *pinningProxy) dialThroughUpstreamProxy(ctx context.Context, proxyURL *url.URL, target string) (net.Conn, error) {
return gotenberg.DialThroughProxy(ctx, proxyURL, target, p.dialBypass)
}
// resetClient aborts the client connection with a TCP reset instead of
// answering. Chromium treats a proxy response as the origin's own, so a 502
// would reach the page as an ordinary HTTP error; a reset surfaces as a
// network failure, as it would without the proxy.
func resetClient(w http.ResponseWriter) {
hj, ok := w.(http.Hijacker)
if !ok {
http.Error(w, "upstream error", http.StatusBadGateway)
return
}
conn, _, err := hj.Hijack()
if err != nil {
return
}
if tcpConn, ok := conn.(*net.TCPConn); ok {
_ = tcpConn.SetLinger(0)
}
_ = conn.Close()
}