vite-plugin-proxy-http2
v0.2.2
Published
Vite plugin for HTTP/2 proxy support with proper protocol handling
Readme
Vite HTTP/2 Proxy Plugin
Vite plugin that provides HTTP/2 proxy support with full feature parity to Vite's built-in proxy.
Features
- 🚀 Native HTTP/2 Support - Uses Node's native
http2module, no intermediate proxy module. - 🔄 Connection Pooling - Efficient HTTP/2 connection reuse with automatic cleanup.
- 🔌 WebSocket Support - Full WebSocket proxying with HTTP/2 upgrade handling.
- 🍪 Cookie Management - Advanced cookie rewriting with domain and path support.
- 🔒 Security Features - SSL validation, authentication, and X-Forwarded headers.
- 📡 SSE Support - Server-Sent Events with buffering control.
- 🛣️ Advanced Routing - Dynamic routing with function support.
- 📊 Comprehensive Logging - Detailed request logging with timing information.
- 🎯 Full Vite Compatibility - Supports Vite standard proxy configuration options.
Installation
npm install vite-plugin-proxy-http2
# or
yarn add vite-plugin-proxy-http2
# or
pnpm add vite-plugin-proxy-http2Quick Start
Recommended: Plugin-level Configuration (HTTP/2 by default)
// vite.config.ts
import { defineConfig } from 'vite'
import http2ProxyPlugin from 'vite-plugin-proxy-http2'
export default defineConfig({
plugins: [
http2ProxyPlugin({
// Global settings (optional)
maxSessions: 50, // Limit HTTP/2 sessions
defaultTimeout: 30000, // 30 second timeout for all proxies
// Proxy routes
proxy: {
'/api': 'https://api.example.com',
'/ws': {
target: 'wss://websocket.example.com',
ws: true
}
}
})
]
})Note: This approach ensures HTTP/2 is used by default and prevents Vite from downgrading to HTTP/1.1.
Alternative: Vite Server Configuration
// vite.config.ts
import { defineConfig } from 'vite'
import http2ProxyPlugin from 'vite-plugin-proxy-http2'
export default defineConfig({
plugins: [http2ProxyPlugin()],
server: {
proxy: {
'/api': 'https://api.example.com'
}
}
})Warning: Using Vite's
server.proxymay cause Vite to downgrade connections to HTTP/1.1. We recommend using the plugin-level configuration instead.
Configuration
Basic Examples
export default defineConfig({
plugins: [
http2ProxyPlugin({
proxy: {
// String shorthand
'/api': 'https://api.example.com',
// With options
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
headers: {
'X-Custom-Header': 'value'
}
},
// RegExp pattern
'^/api/.*': {
target: 'https://api.example.com',
changeOrigin: true
}
}
})
]
})Advanced Features
WebSocket Support
'/socket.io': {
target: 'https://socket-server.com',
ws: true,
changeOrigin: true
}Cookie Rewriting
'/api': {
target: 'https://api.example.com',
cookieDomainRewrite: 'localhost',
cookiePathRewrite: {
'/api': '/',
'/api/v2': '/v2'
}
}Dynamic Routing
'/api': {
target: 'https://default-api.com',
router: (req) => {
// Route based on headers, query params, etc.
if (req.headers['x-api-version'] === 'v2') {
return 'https://api-v2.example.com'
}
return 'https://api-v1.example.com'
}
}Conditional Bypass
'/api': {
target: 'https://api.example.com',
bypass: (req, res, options) => {
// Skip proxy for certain conditions
if (req.headers.accept?.includes('text/html')) {
return '/index.html'
}
}
}Protocol Support (HTTP/1.1 and HTTP/2)
// Force HTTP/1.1 for servers that don't support HTTP/2
'/legacy-api': {
target: 'https://old-server.com',
forceHttp1: true
}
// Automatically detect protocol support
'/auto': {
target: 'https://api.example.com',
autoDetectProtocol: true // Will use HTTP/2 if supported, fallback to HTTP/1.1
}Security Options
'/api': {
target: 'https://api.example.com',
secure: true, // Verify SSL certificates
auth: 'username:password', // Basic authentication
xfwd: true, // Add X-Forwarded-* headers
headers: {
'Authorization': 'Bearer token'
}
}Timeout Configuration
http2ProxyPlugin({
// Set global defaults for all proxies
defaultTimeout: 30000, // 30 seconds
defaultProxyTimeout: 25000, // 25 seconds
proxy: {
'/api': 'https://api.example.com', // Uses global defaults
'/slow-api': {
target: 'https://slow-api.example.com',
timeout: 60000 // Override for specific route
}
}
})Server-Sent Events
'/events': {
target: 'https://sse-server.com',
sse: true, // Optimizes for SSE streams
changeOrigin: true
}Custom Response Handling
'/api': {
target: 'https://api.example.com',
selfHandleResponse: true,
configure: (proxyReq, options) => {
// Custom request/response handling
proxyReq.on('response', (headers) => {
console.log('Response headers:', headers)
})
}
}Configuration Options
Global Plugin Options
These options are configured at the plugin level and affect all proxies:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| proxy | object | - | Proxy route configurations |
| maxSessions | number | 100 | Maximum number of HTTP/2 sessions |
| sessionMaxAge | number | 300000 | Session idle timeout in milliseconds (5 minutes) |
| connectionTimeout | number | 10000 | Initial connection timeout in milliseconds |
| maxQueueSize | number | 100 | Maximum queued requests across all origins |
| queueTimeout | number | 30000 | Queue timeout in milliseconds |
| defaultTimeout | number | 120000 | Default timeout for all proxies in milliseconds |
| defaultProxyTimeout | number | - | Default proxy-specific timeout in milliseconds |
Example:
http2ProxyPlugin({
// Global settings
maxSessions: 50,
sessionMaxAge: 2 * 60 * 1000, // 2 minutes
maxQueueSize: 200,
defaultTimeout: 30000, // 30 seconds
// Proxy routes
proxy: {
'/api': 'https://api.example.com'
}
})Per-Proxy Options
These options can be configured for each individual proxy route:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| target | string \| object | required | Backend server URL |
| changeOrigin | boolean | true | Changes the origin header to match the target |
| ws | boolean | false | Enable WebSocket proxy |
| rewrite | function | - | Rewrite request paths |
| configure | function | - | Custom proxy configuration callback |
| bypass | function | - | Conditionally bypass the proxy |
| secure | boolean | true | Verify SSL certificates |
| auth | string | - | Basic authentication credentials |
| headers | object | - | Custom headers to add to requests |
| forceHttp1 | boolean | false | Force HTTP/1.1 protocol for this proxy |
| autoDetectProtocol | boolean | false | Auto-detect if origin supports HTTP/2 |
| xfwd | boolean | true | Add X-Forwarded-* headers |
| preserveHeaderKeyCase | boolean | false | Preserve original header key casing |
| cookieDomainRewrite | string \| object | - | Rewrite cookie domains |
| cookiePathRewrite | string \| object | - | Rewrite cookie paths |
| router | string \| function | - | Dynamic target routing |
| timeout | number | global default | Proxy timeout in milliseconds (overrides global) |
| proxyTimeout | number | global default | Proxy timeout in milliseconds (overrides global) |
| selfHandleResponse | boolean | false | Handle response manually |
| followRedirects | boolean | false | Follow HTTP redirects |
| sse | boolean | false | Optimize for Server-Sent Events |
Debugging
Enable debug logging by setting the DEBUG environment variable:
DEBUG=vite:http2-proxy npm run devOr set LOG_LEVEL for more detailed logging:
LOG_LEVEL=debug npm run devPerformance
The plugin implements several performance optimizations:
- Connection Pooling: Reuses HTTP/2 connections across requests
- Automatic Cleanup: Removes idle connections after configurable timeout (default: 5 minutes)
- Connection Limits: Prevents resource exhaustion with configurable session limits (default: 100)
- Request Queueing: Handles high load with configurable queue size (default: 100 requests)
- Stream Management: Proper HTTP/2 stream lifecycle handling
- Timeout Handling: Configurable timeouts prevent hanging requests
Migration from http-proxy
This plugin maintains API compatibility with Vite's built-in proxy (which uses http-proxy). Simply install and add the plugin to migrate:
// vite.config.ts
import { defineConfig } from 'vite'
+import http2ProxyPlugin from 'vite-http2-proxy'
export default defineConfig({
+ plugins: [http2ProxyPlugin({
+ proxy: {
+ // Your existing proxy config works as-is,
+ // just move it into the plugin config
+ '/api': 'https://api.example.com'
+ }
})],
server: {
// Remove proxy config from here
}
})Troubleshooting
Common Issues
SSL Certificate Errors
// Disable SSL verification for development '/api': { target: 'https://self-signed.example.com', secure: false }Cookie Issues
// Ensure cookies work on localhost '/api': { target: 'https://api.example.com', cookieDomainRewrite: 'localhost', cookiePathRewrite: '/' }Timeout Errors
// Increase timeout for slow endpoints '/api': { target: 'https://slow-api.example.com', timeout: 300000 // 5 minutes }
License
MIT
