mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
feat(websocket): add HTTP/HTTPS proxy support (#25614)
## Summary
Add `proxy` option to WebSocket constructor for connecting through HTTP
CONNECT proxies.
### Features
- Support for `ws://` and `wss://` through HTTP proxies
- Support for `ws://` and `wss://` through HTTPS proxies (with
`rejectUnauthorized: false`)
- Proxy authentication via URL credentials (Basic auth)
- Custom proxy headers support
- Full TLS options (`ca`, `cert`, `key`, etc.) for target connections
using `SSLConfig.fromJS`
### API
```javascript
// String format
new WebSocket("wss://example.com", { proxy: "http://proxy:8080" })
// With credentials
new WebSocket("wss://example.com", { proxy: "http://user:pass@proxy:8080" })
// Object format with custom headers
new WebSocket("wss://example.com", {
proxy: { url: "http://proxy:8080", headers: { "X-Custom": "value" } }
})
// HTTPS proxy
new WebSocket("ws://example.com", {
proxy: "https://proxy:8443",
tls: { rejectUnauthorized: false }
})
```
### Implementation
| File | Changes |
|------|---------|
| `WebSocketUpgradeClient.zig` | Proxy state machine and CONNECT
handling |
| `WebSocketProxyTunnel.zig` | **New** - TLS tunnel inside CONNECT for
wss:// through HTTP proxy |
| `JSWebSocket.cpp` | Parse proxy option and TLS options using
`SSLConfig.fromJS` |
| `WebSocket.cpp` | Pass proxy parameters to Zig, handle HTTPS proxy
socket selection |
| `bun.d.ts` | Add `proxy` and full TLS options to WebSocket types |
### Supported Scenarios
| Scenario | Status |
|----------|--------|
| ws:// through HTTP proxy | ✅ Working |
| wss:// through HTTP proxy | ✅ Working (TLS tunnel) |
| ws:// through HTTPS proxy | ✅ Working (with `rejectUnauthorized:
false`) |
| wss:// through HTTPS proxy | ✅ Working (with `rejectUnauthorized:
false`) |
| Proxy authentication (Basic) | ✅ Working |
| Custom proxy headers | ✅ Working |
| Custom CA for HTTPS proxy | ✅ Working |
## Test plan
- [x] API tests verify proxy option is accepted in various formats
- [x] Functional tests with local HTTP CONNECT proxy server
- [x] Proxy authentication tests (Basic auth)
- [x] HTTPS proxy tests with `rejectUnauthorized: false`
- [x] Error handling tests (auth failures, wrong credentials)
Run tests: `bun test test/js/web/websocket/websocket-proxy.test.ts`
## Changelog
- Added `proxy` option to `WebSocket` constructor for HTTP/HTTPS proxy
support
- Added full TLS options (`ca`, `cert`, `key`, `passphrase`, etc.) to
`WebSocket` constructor
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
80
packages/bun-types/bun.d.ts
vendored
80
packages/bun-types/bun.d.ts
vendored
@@ -3290,16 +3290,29 @@ declare module "bun" {
|
||||
|
||||
type WebSocketOptionsTLS = {
|
||||
/**
|
||||
* Options for the TLS connection
|
||||
* Options for the TLS connection.
|
||||
*
|
||||
* Supports full TLS configuration including custom CA certificates,
|
||||
* client certificates, and other TLS settings (same as fetch).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Using BunFile for certificates
|
||||
* const ws = new WebSocket("wss://example.com", {
|
||||
* tls: {
|
||||
* ca: Bun.file("./ca.pem")
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* // Using Buffer
|
||||
* const ws = new WebSocket("wss://example.com", {
|
||||
* tls: {
|
||||
* ca: fs.readFileSync("./ca.pem")
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
tls?: {
|
||||
/**
|
||||
* Whether to reject the connection if the certificate is not valid
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
rejectUnauthorized?: boolean;
|
||||
};
|
||||
tls?: TLSOptions;
|
||||
};
|
||||
|
||||
type WebSocketOptionsHeaders = {
|
||||
@@ -3309,10 +3322,57 @@ declare module "bun" {
|
||||
headers?: import("node:http").OutgoingHttpHeaders;
|
||||
};
|
||||
|
||||
type WebSocketOptionsProxy = {
|
||||
/**
|
||||
* HTTP proxy to use for the WebSocket connection.
|
||||
*
|
||||
* Can be a string URL or an object with `url` and optional `headers`.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // String format
|
||||
* const ws = new WebSocket("wss://example.com", {
|
||||
* proxy: "http://proxy.example.com:8080"
|
||||
* });
|
||||
*
|
||||
* // With credentials
|
||||
* const ws = new WebSocket("wss://example.com", {
|
||||
* proxy: "http://user:pass@proxy.example.com:8080"
|
||||
* });
|
||||
*
|
||||
* // Object format with custom headers
|
||||
* const ws = new WebSocket("wss://example.com", {
|
||||
* proxy: {
|
||||
* url: "http://proxy.example.com:8080",
|
||||
* headers: {
|
||||
* "Proxy-Authorization": "Bearer token"
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
proxy?:
|
||||
| string
|
||||
| {
|
||||
/**
|
||||
* The proxy URL (http:// or https://)
|
||||
*/
|
||||
url: string;
|
||||
/**
|
||||
* Custom headers to send to the proxy server.
|
||||
* Supports plain objects or Headers class instances.
|
||||
*/
|
||||
headers?: import("node:http").OutgoingHttpHeaders | Headers;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor options for the `Bun.WebSocket` client
|
||||
*/
|
||||
type WebSocketOptions = WebSocketOptionsProtocolsOrProtocol & WebSocketOptionsTLS & WebSocketOptionsHeaders;
|
||||
type WebSocketOptions = WebSocketOptionsProtocolsOrProtocol &
|
||||
WebSocketOptionsTLS &
|
||||
WebSocketOptionsHeaders &
|
||||
WebSocketOptionsProxy;
|
||||
|
||||
interface WebSocketEventMap {
|
||||
close: CloseEvent;
|
||||
|
||||
Reference in New Issue
Block a user