Commit Graph

13 Commits

Author SHA1 Message Date
Ciro Spaciari
a14a89ca95 fix(proxy): respect NO_PROXY for explicit proxy options in fetch and ws (#26608)
### What does this PR do?

Extract NO_PROXY checking logic from getHttpProxyFor into a reusable
isNoProxy method on the env Loader. This allows both fetch() and
WebSocket to check NO_PROXY even when a proxy is explicitly provided via
the proxy option (not just via http_proxy env var).

Changes:
- env_loader.zig: Extract isNoProxy() from getHttpProxyFor()
- FetchTasklet.zig: Check isNoProxy() before using explicit proxy
- WebSocket.cpp: Check Bun__isNoProxy() before using explicit proxy
- virtual_machine_exports.zig: Export Bun__isNoProxy for C++ access
- Add NO_PROXY tests for both fetch and WebSocket proxy paths

### How did you verify your code works?
Tests

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
2026-01-30 16:20:45 -08:00
robobun
8dc79641c8 fix(http): support proxy passwords longer than 4096 characters (#25530)
## Summary
- Fixes silent 401 Unauthorized errors when using proxies with long
passwords (e.g., JWT tokens > 4096 chars)
- Bun was silently dropping proxy passwords exceeding 4095 characters,
falling through to code that only encoded the username

## Changes
- Added `PercentEncoding.decodeWithFallback` which uses a 4KB stack
buffer for the common case and falls back to heap allocation only for
larger inputs
- Updated proxy auth encoding in `AsyncHTTP.zig` to use the new fallback
method

## Test plan
- [x] Added test case that verifies passwords > 4096 chars are handled
correctly
- [x] Test fails with system bun (v1.3.3), passes with this fix
- [x] All 29 proxy tests pass

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

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-15 13:21:41 -08:00
robobun
8dc084af5f fix(fetch): ignore proxy object without url property (#25414)
## Summary
- When a URL object is passed as the proxy option, or when a proxy
object lacks a "url" property, ignore it instead of throwing an error
- This fixes a regression introduced in 1.3.4 where libraries like taze
that pass URL objects as proxy values would fail

## Test plan
- Added test: "proxy as URL object should be ignored (no url property)"
- passes a URL object directly as proxy
- Updated test: "proxy object without url is ignored (regression
#25413)" - proxy object with headers but no url
- Updated test: "proxy object with null url is ignored (regression
#25413)" - proxy object where url is null
- All 29 proxy tests pass

Fixes #25413

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

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-12-09 12:31:45 -08:00
robobun
908ab9ce30 feat(fetch): add proxy object format with headers support (#25090)
## Summary

- Extends `fetch()` proxy option to accept an object format: `proxy: {
url: string, headers?: Headers }`
- Allows sending custom headers to the proxy server (useful for proxy
authentication, custom routing headers, etc.)
- Headers are sent in CONNECT requests (for HTTPS targets) and direct
proxy requests (for HTTP targets)
- User-provided `Proxy-Authorization` header overrides auto-generated
credentials from URL

## Usage

```typescript
// Old format (still works)
fetch(url, { proxy: "http://proxy.example.com:8080" });

// New object format with headers
fetch(url, {
  proxy: {
    url: "http://proxy.example.com:8080",
    headers: {
      "Proxy-Authorization": "Bearer token",
      "X-Custom-Proxy-Header": "value"
    }
  }
});
```

## Test plan

- [x] Test proxy object with url string works same as string proxy
- [x] Test proxy object with headers sends headers to proxy (HTTP
target)
- [x] Test proxy object with headers sends headers in CONNECT request
(HTTPS target)
- [x] Test proxy object with Headers instance
- [x] Test proxy object with empty headers
- [x] Test proxy object with undefined headers
- [x] Test user-provided Proxy-Authorization overrides URL credentials
- [x] All existing proxy tests pass (25 total)

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

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-26 15:11:45 -08:00
avarayr
24d9d642de ProxyTunnel: close-delimited responses via proxy cause ECONNRESET (#23719)
fixes: oven-sh/bun#23717

### What does this PR do?
- Align ProxyTunnel.onClose with
[HTTPClient.onClose](https://github.com/oven-sh/bun/blob/bun-v1.3.0/src/http.zig#L223-L241):
when a tunneled HTTPS response is in-progress and either
  - parsing chunked trailers (trailer-line states), or
- transfer-encoding is identity with content_length == null while in
.body,
treat EOF as end-of-message and complete the request, rather than
ECONNRESET.
- Schedule proxy deref instead of deref inside callbacks to avoid
lifetime hazards.

### How did you verify your code works?
- `test/js/bun/http/proxy.test.ts`: raw TLS origin returns
close-delimited 200 OK; verified no ECONNRESET and body delivered.
- Test suite passes under bun bd test.

## Risk/compat
- Only affects CONNECT/TLS path. Direct HTTP/HTTPS unchanged. Behavior
mirrors existing
[HTTPClient.onClose](https://github.com/oven-sh/bun/blob/bun-v1.3.0/src/http.zig#L223-L241).

## Repro (minimal)
See issue; core condition is no Content-Length and no Transfer-Encoding
(close-delimited).

Co-authored-by: Ciro Spaciari <ciro.spaciari@gmail.com>
2025-10-23 13:04:23 -07:00
avarayr
b3f5dd73da http(proxy): preserve TLS record ordering in proxy tunnel writes (#22417)
### What does this PR do?

Fixes a TLS corruption bug in CONNECT proxy tunneling for HTTPS uploads.
When a large request body is sent over a tunneled TLS connection, the
client could interleave direct socket writes with previously buffered
encrypted bytes, causing TLS records to be emitted out-of-order. Some
proxies/upstreams detect this as a MAC mismatch and terminate with
SSLV3_ALERT_BAD_RECORD_MAC, which surfaced to users as ECONNRESET ("The
socket connection was closed unexpectedly").

This change makes `ProxyTunnel.write` preserve strict FIFO ordering of
encrypted bytes: if any bytes are already buffered, we enqueue new bytes
instead of calling `socket.write` directly. Flushing continues
exclusively via `onWritable`, which writes the buffered stream in order.
This eliminates interleaving and restores correctness for large proxied
HTTPS POST requests.

### How did you verify your code works?

- Local reproduction using a minimal script that POSTs ~20MB over HTTPS
via an HTTP proxy (CONNECT):
- Before: frequent ECONNRESET. With detailed SSL logs, upstream sent
`SSLV3_ALERT_BAD_RECORD_MAC`.
  - After: requests complete successfully. Upstream responds as expected
  
- Verified small bodies and non-proxied HTTPS continue to work.
- Verified no linter issues and no unrelated code changes. The edit is
isolated to `src/http/ProxyTunnel.zig` and only affects the write path
to maintain TLS record ordering.

Rationale: TLS record boundaries must be preserved; mixing buffered data
with immediate writes risks fragmenting or reordering records under
backpressure. Enqueuing while buffered guarantees FIFO semantics and
avoids record corruption.


fixes: 
#17434

#18490 (false fix in corresponding pr)

---------

Co-authored-by: Ciro Spaciari <ciro.spaciari@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-09-10 21:02:23 -07:00
Ciro Spaciari
183c661c40 net compatibility improvements (#14933)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2024-11-07 22:03:53 -08:00
Ashcon Partovi
117e1b3883 bun run prettier (#14153)
Co-authored-by: Electroid <Electroid@users.noreply.github.com>
2024-09-24 22:46:18 -07:00
Ciro Spaciari
d80d9f450c fix(node:http) improve agent support (#13780)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2024-09-19 23:04:36 -07:00
Jarred Sumner
1458fcca4a Run formatter 2024-09-06 18:13:08 -07:00
Ciro Spaciari
d8e2c24d70 fix(fetch) fix lifecycle of SSL Proxy, fix lifecycle of tls_props, fix handling chunked encoded redirects when proxing. (#13752) 2024-09-06 01:50:02 -07:00
Jarred Sumner
cd6785771e run prettier and add back format action (#13722) 2024-09-03 21:32:52 -07:00
Ciro Spaciari
bac38b8967 fix(tls/fetch) Better SSLWrapper for http proxy and start of Duplex support on tls (#12750)
Co-authored-by: cirospaciari <cirospaciari@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2024-08-30 23:22:58 -07:00