fix(http): check socket state before operations in doRedirect (#26221)

## Summary
- Fix assertion failure when using HTTP proxy with redirects and socket
closes during redirect processing
- Add `isClosedOrHasError()` checks before `releaseSocket` and
`closeSocket` in `doRedirect`

Fixes #26220

## Root Cause
In `doRedirect` (`src/http.zig:786-797`), the code called
`releaseSocket` or `closeSocket` without checking if the socket was
already closed. When `onClose` is triggered while `is_redirect_pending`
is true, it calls `doRedirect`, but the socket is already closed at that
point, causing the assertion in `HTTPContext.zig:168` to fail:

```zig
assert(!socket.isClosed());  // FAILS - socket IS closed
```

## Fix
Added `!socket.isClosedOrHasError()` checks before socket operations in
`doRedirect`, matching the pattern already used at line 1790 in the same
file.

## Test plan
- [x] All existing proxy redirect tests pass (`bun bd test
test/js/bun/http/proxy.test.ts`)
- [x] Build completes successfully (`bun bd`)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
robobun
2026-01-18 13:19:30 -08:00
committed by GitHub
parent 3d46ae2fa4
commit c3b4e5568c

View File

@@ -783,7 +783,7 @@ pub fn doRedirect(
NewHTTPContext(is_ssl).closeSocket(socket);
} else {
// we need to clean the client reference before closing the socket because we are going to reuse the same ref in a another request
if (this.isKeepAlivePossible()) {
if (this.isKeepAlivePossible() and !socket.isClosedOrHasError()) {
log("Keep-Alive release in redirect", .{});
assert(this.connected_url.hostname.len > 0);
ctx.releaseSocket(