@robiki/proxy 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +588 -0
- package/dist/config-_6LOsppp.d.ts +180 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +542 -0
- package/dist/utils/config.d.ts +5 -0
- package/dist/utils/config.js +226 -0
- package/package.json +86 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Robiki sp. z o.o
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
# ๐ Robiki Proxy
|
|
2
|
+
|
|
3
|
+
> A high-performance, flexible HTTP/2 reverse proxy with WebSocket support, configurable routing, CORS, and request validation. Use it as an npm package in your Node.js application or as a standalone Docker container.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@robiki/proxy)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## โจ Features
|
|
9
|
+
|
|
10
|
+
- **๐ HTTP/2 & SSL/TLS Support**: Full HTTP/2 protocol support with automatic HTTP/1.1 fallback
|
|
11
|
+
- **๐ WebSocket Proxying**: Seamless WebSocket connection handling and proxying
|
|
12
|
+
- **๐ Flexible Routing**: Configure routes by domain/host with wildcard support
|
|
13
|
+
- **๐ก๏ธ CORS Management**: Global and per-route CORS configuration
|
|
14
|
+
- **โ
Request Validation**: Custom validation logic for authentication, rate limiting, etc.
|
|
15
|
+
- **๐ URL Remapping**: Transform URLs before forwarding to target services
|
|
16
|
+
- **๐ฆ Dual Usage**: Use as npm package or Docker container
|
|
17
|
+
- **๐ฏ Multi-Port Support**: Listen on multiple ports simultaneously
|
|
18
|
+
- **โก High Performance**: Built on Node.js native HTTP/2 implementation
|
|
19
|
+
|
|
20
|
+
## ๐ฆ Installation
|
|
21
|
+
|
|
22
|
+
### As an npm Package
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @robiki/proxy
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
yarn add @robiki/proxy
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### As a Docker Container
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
docker pull robiki/proxy:latest
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Or build from source:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
docker build -t robiki/proxy .
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## ๐ Quick Start
|
|
45
|
+
|
|
46
|
+
### Using as npm Package
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
import { createProxy } from '@robiki/proxy';
|
|
50
|
+
|
|
51
|
+
const proxy = await createProxy({
|
|
52
|
+
ports: [443, 8080],
|
|
53
|
+
ssl: {
|
|
54
|
+
key: './certs/key.pem',
|
|
55
|
+
cert: './certs/cert.pem',
|
|
56
|
+
allowHTTP1: true,
|
|
57
|
+
},
|
|
58
|
+
routes: {
|
|
59
|
+
'api.example.com': {
|
|
60
|
+
target: 'localhost:3000',
|
|
61
|
+
ssl: true,
|
|
62
|
+
},
|
|
63
|
+
'example.com': {
|
|
64
|
+
target: 'localhost:8080',
|
|
65
|
+
ssl: false,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
console.log('Proxy server is running!');
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Using with Docker
|
|
74
|
+
|
|
75
|
+
1. Create a `proxy.config.json` file:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"ports": [443, 8080],
|
|
80
|
+
"ssl": {
|
|
81
|
+
"key": "/app/certs/key.pem",
|
|
82
|
+
"cert": "/app/certs/cert.pem",
|
|
83
|
+
"allowHTTP1": true
|
|
84
|
+
},
|
|
85
|
+
"routes": {
|
|
86
|
+
"api.example.com": {
|
|
87
|
+
"target": "backend-service:3000",
|
|
88
|
+
"ssl": true
|
|
89
|
+
},
|
|
90
|
+
"example.com": {
|
|
91
|
+
"target": "frontend-service:8080",
|
|
92
|
+
"ssl": false
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
2. Create a `docker-compose.yml`:
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
version: '3.8'
|
|
102
|
+
|
|
103
|
+
services:
|
|
104
|
+
proxy:
|
|
105
|
+
image: robiki/proxy:latest
|
|
106
|
+
ports:
|
|
107
|
+
- '443:443'
|
|
108
|
+
- '8080:8080'
|
|
109
|
+
volumes:
|
|
110
|
+
- ./proxy.config.json:/app/proxy.config.json:ro
|
|
111
|
+
- ./certs:/app/certs:ro
|
|
112
|
+
environment:
|
|
113
|
+
- PROXY_CONFIG=/app/proxy.config.json
|
|
114
|
+
networks:
|
|
115
|
+
- app-network
|
|
116
|
+
|
|
117
|
+
backend-service:
|
|
118
|
+
image: your-backend-image
|
|
119
|
+
networks:
|
|
120
|
+
- app-network
|
|
121
|
+
|
|
122
|
+
frontend-service:
|
|
123
|
+
image: your-frontend-image
|
|
124
|
+
networks:
|
|
125
|
+
- app-network
|
|
126
|
+
|
|
127
|
+
networks:
|
|
128
|
+
app-network:
|
|
129
|
+
driver: bridge
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
3. Start the services:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
docker-compose up -d
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## ๐ Configuration
|
|
139
|
+
|
|
140
|
+
### Configuration File
|
|
141
|
+
|
|
142
|
+
Create a `proxy.config.json` file with the following structure:
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"ports": [443, 8080],
|
|
147
|
+
"ssl": {
|
|
148
|
+
"key": "./certs/key.pem",
|
|
149
|
+
"cert": "./certs/cert.pem",
|
|
150
|
+
"ca": "./certs/ca.pem",
|
|
151
|
+
"allowHTTP1": true
|
|
152
|
+
},
|
|
153
|
+
"cors": {
|
|
154
|
+
"origin": "*",
|
|
155
|
+
"methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
156
|
+
"allowedHeaders": ["Content-Type", "Authorization"],
|
|
157
|
+
"credentials": true,
|
|
158
|
+
"maxAge": 86400
|
|
159
|
+
},
|
|
160
|
+
"routes": {
|
|
161
|
+
"api.example.com": {
|
|
162
|
+
"target": "backend-service:3000",
|
|
163
|
+
"ssl": true,
|
|
164
|
+
"cors": {
|
|
165
|
+
"origin": ["https://example.com"],
|
|
166
|
+
"credentials": true
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
"*.example.com": {
|
|
170
|
+
"target": "wildcard-service:4000",
|
|
171
|
+
"ssl": true
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Environment Variables
|
|
178
|
+
|
|
179
|
+
You can also configure the proxy using environment variables:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# SSL Configuration
|
|
183
|
+
SSL_KEY=/app/certs/key.pem
|
|
184
|
+
SSL_CERT=/app/certs/cert.pem
|
|
185
|
+
SSL_CA=/app/certs/ca.pem
|
|
186
|
+
SSL_ALLOW_HTTP1=true
|
|
187
|
+
|
|
188
|
+
# CORS Configuration
|
|
189
|
+
CORS_ORIGIN=*
|
|
190
|
+
CORS_METHODS=GET,POST,PUT,DELETE,OPTIONS
|
|
191
|
+
CORS_HEADERS=Content-Type,Authorization
|
|
192
|
+
CORS_CREDENTIALS=true
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## ๐ฏ Advanced Usage
|
|
196
|
+
|
|
197
|
+
### URL Remapping
|
|
198
|
+
|
|
199
|
+
Transform URLs before forwarding to target services:
|
|
200
|
+
|
|
201
|
+
```javascript
|
|
202
|
+
const config = {
|
|
203
|
+
routes: {
|
|
204
|
+
'api.example.com': {
|
|
205
|
+
target: 'backend:3000',
|
|
206
|
+
ssl: true,
|
|
207
|
+
remap: (url) => {
|
|
208
|
+
// Remove /api prefix
|
|
209
|
+
return url.replace(/^\/api/, '');
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Request Validation
|
|
217
|
+
|
|
218
|
+
Add custom validation logic for authentication, rate limiting, etc.:
|
|
219
|
+
|
|
220
|
+
```javascript
|
|
221
|
+
const config = {
|
|
222
|
+
// Global validation
|
|
223
|
+
validate: async (info) => {
|
|
224
|
+
if (!info.headers.authorization) {
|
|
225
|
+
return {
|
|
226
|
+
status: false,
|
|
227
|
+
code: 401,
|
|
228
|
+
message: 'Unauthorized',
|
|
229
|
+
headers: { 'www-authenticate': 'Bearer' },
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
return { status: true };
|
|
233
|
+
},
|
|
234
|
+
routes: {
|
|
235
|
+
'api.example.com': {
|
|
236
|
+
target: 'backend:3000',
|
|
237
|
+
ssl: true,
|
|
238
|
+
// Route-specific validation
|
|
239
|
+
validate: async (info) => {
|
|
240
|
+
const rateLimit = await checkRateLimit(info.remoteAddress);
|
|
241
|
+
if (!rateLimit.allowed) {
|
|
242
|
+
return {
|
|
243
|
+
status: false,
|
|
244
|
+
code: 429,
|
|
245
|
+
message: 'Too Many Requests',
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
return { status: true };
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Custom CORS Configuration
|
|
256
|
+
|
|
257
|
+
Configure CORS globally or per-route:
|
|
258
|
+
|
|
259
|
+
```javascript
|
|
260
|
+
const config = {
|
|
261
|
+
// Global CORS
|
|
262
|
+
cors: {
|
|
263
|
+
origin: ['https://example.com', 'https://www.example.com'],
|
|
264
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE'],
|
|
265
|
+
allowedHeaders: ['Content-Type', 'Authorization'],
|
|
266
|
+
credentials: true,
|
|
267
|
+
maxAge: 86400,
|
|
268
|
+
},
|
|
269
|
+
routes: {
|
|
270
|
+
'api.example.com': {
|
|
271
|
+
target: 'backend:3000',
|
|
272
|
+
ssl: true,
|
|
273
|
+
// Route-specific CORS (overrides global)
|
|
274
|
+
cors: {
|
|
275
|
+
origin: '*',
|
|
276
|
+
credentials: false,
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
};
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Custom Handlers
|
|
284
|
+
|
|
285
|
+
Create custom request handlers for advanced use cases:
|
|
286
|
+
|
|
287
|
+
```javascript
|
|
288
|
+
import { createCustomProxy } from '@robiki/proxy';
|
|
289
|
+
|
|
290
|
+
const customRestHandler = async (req, res) => {
|
|
291
|
+
if (req.url === '/health') {
|
|
292
|
+
res.writeHead(200, { 'content-type': 'application/json' });
|
|
293
|
+
return res.end(JSON.stringify({ status: 'ok' }));
|
|
294
|
+
}
|
|
295
|
+
// Fall back to default proxy behavior
|
|
296
|
+
const { restAPIProxyHandler } = await import('@robiki/proxy/connections');
|
|
297
|
+
return restAPIProxyHandler(req, res);
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
const proxy = await createCustomProxy(config, {
|
|
301
|
+
rest: customRestHandler,
|
|
302
|
+
websocket: customWebSocketHandler,
|
|
303
|
+
stream: customStreamHandler,
|
|
304
|
+
});
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## ๐ง API Reference
|
|
308
|
+
|
|
309
|
+
### `createProxy(config: ServerConfig): Promise<ProxyServer>`
|
|
310
|
+
|
|
311
|
+
Creates and starts a proxy server with the given configuration.
|
|
312
|
+
|
|
313
|
+
**Parameters:**
|
|
314
|
+
|
|
315
|
+
- `config`: Server configuration object
|
|
316
|
+
|
|
317
|
+
**Returns:** Promise that resolves to a `ProxyServer` instance
|
|
318
|
+
|
|
319
|
+
### `ProxyServer`
|
|
320
|
+
|
|
321
|
+
**Methods:**
|
|
322
|
+
|
|
323
|
+
- `start()`: Start the proxy server
|
|
324
|
+
- `stop()`: Stop the proxy server
|
|
325
|
+
- `getConfig()`: Get the current configuration
|
|
326
|
+
|
|
327
|
+
### Configuration Types
|
|
328
|
+
|
|
329
|
+
#### `ServerConfig`
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
interface ServerConfig {
|
|
333
|
+
ports?: number[];
|
|
334
|
+
ssl?: CertificateConfig;
|
|
335
|
+
routes: Record<string, RouteConfig>;
|
|
336
|
+
cors?: CorsConfig;
|
|
337
|
+
validate?: (info: ConnectionInfo) => Promise<ForwardValidationResult>;
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
#### `RouteConfig`
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
interface RouteConfig {
|
|
345
|
+
target: string;
|
|
346
|
+
ssl?: boolean;
|
|
347
|
+
remap?: (url: string) => string;
|
|
348
|
+
cors?: CorsConfig;
|
|
349
|
+
validate?: (info: ConnectionInfo) => Promise<ForwardValidationResult>;
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
#### `CorsConfig`
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
interface CorsConfig {
|
|
357
|
+
origin?: string | string[];
|
|
358
|
+
methods?: string[];
|
|
359
|
+
allowedHeaders?: string[];
|
|
360
|
+
exposedHeaders?: string[];
|
|
361
|
+
credentials?: boolean;
|
|
362
|
+
maxAge?: number;
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
#### `ConnectionInfo`
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
interface ConnectionInfo {
|
|
370
|
+
id: number;
|
|
371
|
+
method: string;
|
|
372
|
+
path: string;
|
|
373
|
+
remoteAddress: string;
|
|
374
|
+
scheme: string;
|
|
375
|
+
authority: string;
|
|
376
|
+
origin: string;
|
|
377
|
+
headers: IncomingHttpHeaders;
|
|
378
|
+
query: URLSearchParams;
|
|
379
|
+
type: RequestType;
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## ๐ณ Docker Usage
|
|
384
|
+
|
|
385
|
+
### Using in Another Project
|
|
386
|
+
|
|
387
|
+
1. Add the proxy to your `docker-compose.yml`:
|
|
388
|
+
|
|
389
|
+
```yaml
|
|
390
|
+
services:
|
|
391
|
+
proxy:
|
|
392
|
+
image: robiki/proxy:latest
|
|
393
|
+
ports:
|
|
394
|
+
- '443:443'
|
|
395
|
+
- '8080:8080'
|
|
396
|
+
volumes:
|
|
397
|
+
- ./proxy.config.json:/app/proxy.config.json:ro
|
|
398
|
+
- ./certs:/app/certs:ro
|
|
399
|
+
networks:
|
|
400
|
+
- your-network
|
|
401
|
+
|
|
402
|
+
your-service:
|
|
403
|
+
image: your-service-image
|
|
404
|
+
networks:
|
|
405
|
+
- your-network
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
2. Configure routes in `proxy.config.json` to point to your services
|
|
409
|
+
|
|
410
|
+
3. Start your stack:
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
docker-compose up -d
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Building Custom Image
|
|
417
|
+
|
|
418
|
+
Create a custom Dockerfile:
|
|
419
|
+
|
|
420
|
+
```dockerfile
|
|
421
|
+
FROM robiki/proxy:latest
|
|
422
|
+
|
|
423
|
+
# Copy your configuration
|
|
424
|
+
COPY proxy.config.json /app/proxy.config.json
|
|
425
|
+
COPY certs /app/certs
|
|
426
|
+
|
|
427
|
+
# Set environment variables
|
|
428
|
+
ENV PROXY_CONFIG=/app/proxy.config.json
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
## ๐ Examples
|
|
432
|
+
|
|
433
|
+
Check the `examples/` directory for more usage examples:
|
|
434
|
+
|
|
435
|
+
- `basic-usage.js` - Simple proxy setup
|
|
436
|
+
- `advanced-usage.js` - Advanced features (validation, CORS, remapping)
|
|
437
|
+
- `custom-handlers.js` - Custom request handlers
|
|
438
|
+
- `docker-compose.example.yml` - Complete Docker setup
|
|
439
|
+
|
|
440
|
+
## ๐ SSL/TLS Certificates
|
|
441
|
+
|
|
442
|
+
### Generating Self-Signed Certificates
|
|
443
|
+
|
|
444
|
+
For development:
|
|
445
|
+
|
|
446
|
+
```bash
|
|
447
|
+
mkdir -p certs
|
|
448
|
+
openssl req -x509 -newkey rsa:4096 -keyout certs/key.pem -out certs/cert.pem -days 365 -nodes
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### Using Let's Encrypt
|
|
452
|
+
|
|
453
|
+
For production, use Let's Encrypt certificates:
|
|
454
|
+
|
|
455
|
+
```bash
|
|
456
|
+
certbot certonly --standalone -d example.com
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
Then reference them in your config:
|
|
460
|
+
|
|
461
|
+
```json
|
|
462
|
+
{
|
|
463
|
+
"ssl": {
|
|
464
|
+
"key": "/etc/letsencrypt/live/example.com/privkey.pem",
|
|
465
|
+
"cert": "/etc/letsencrypt/live/example.com/fullchain.pem"
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
## ๐ค Contributing
|
|
471
|
+
|
|
472
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
473
|
+
|
|
474
|
+
## ๐ License
|
|
475
|
+
|
|
476
|
+
MIT ยฉ Robiki sp. z o.o.
|
|
477
|
+
|
|
478
|
+
## ๐ Links
|
|
479
|
+
|
|
480
|
+
- [GitHub Repository](https://github.com/robiki-ai/robiki-proxy)
|
|
481
|
+
- [npm Package](https://www.npmjs.com/package/@robiki/proxy)
|
|
482
|
+
- [Issue Tracker](https://github.com/robiki-ai/robiki-proxy/issues)
|
|
483
|
+
|
|
484
|
+
## ๐ก Use Cases
|
|
485
|
+
|
|
486
|
+
- **Microservices Architecture**: Route requests to different services based on domain/path
|
|
487
|
+
- **Development Environment**: Local proxy for testing multiple services
|
|
488
|
+
- **API Gateway**: Centralized entry point with authentication and rate limiting
|
|
489
|
+
- **SSL Termination**: Handle SSL/TLS at the proxy level
|
|
490
|
+
- **CORS Management**: Centralized CORS configuration
|
|
491
|
+
- **Load Balancing**: Distribute traffic across multiple instances (with custom handlers)
|
|
492
|
+
|
|
493
|
+
## ๐ ๏ธ Troubleshooting
|
|
494
|
+
|
|
495
|
+
### Port Already in Use
|
|
496
|
+
|
|
497
|
+
The proxy will automatically attempt to kill processes on the configured ports. If this fails, manually free the ports:
|
|
498
|
+
|
|
499
|
+
```bash
|
|
500
|
+
lsof -ti:443 | xargs kill -9
|
|
501
|
+
lsof -ti:8080 | xargs kill -9
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### SSL Certificate Errors
|
|
505
|
+
|
|
506
|
+
Ensure your certificate files are readable and in the correct format (PEM). For development, use self-signed certificates.
|
|
507
|
+
|
|
508
|
+
### WebSocket Connection Issues
|
|
509
|
+
|
|
510
|
+
Make sure your WebSocket routes are configured with the correct protocol (ws/wss) and that the target service supports WebSocket connections.
|
|
511
|
+
|
|
512
|
+
## ๐งช Testing
|
|
513
|
+
|
|
514
|
+
Robiki Proxy includes a comprehensive test suite covering unit tests, integration tests, and advanced scenarios.
|
|
515
|
+
|
|
516
|
+
### Running Tests
|
|
517
|
+
|
|
518
|
+
```bash
|
|
519
|
+
# Run all tests
|
|
520
|
+
yarn test
|
|
521
|
+
|
|
522
|
+
# Run tests in watch mode
|
|
523
|
+
yarn test:watch
|
|
524
|
+
|
|
525
|
+
# Run tests with coverage
|
|
526
|
+
yarn test:coverage
|
|
527
|
+
|
|
528
|
+
# Run tests with UI
|
|
529
|
+
yarn test:ui
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### Test Coverage
|
|
533
|
+
|
|
534
|
+
The test suite includes:
|
|
535
|
+
|
|
536
|
+
- **Unit Tests**: Configuration, utilities, header conversion, CORS handling
|
|
537
|
+
- **Integration Tests**: HTTP proxying, route resolution, validation, config loading
|
|
538
|
+
- **Advanced Tests**: WebSocket proxying, HTTP/2 streams, concurrent connections
|
|
539
|
+
- **Docker Tests**: Container builds, config loading, runtime behavior
|
|
540
|
+
|
|
541
|
+
### Docker Tests
|
|
542
|
+
|
|
543
|
+
Run Docker integration tests:
|
|
544
|
+
|
|
545
|
+
```bash
|
|
546
|
+
# Full Docker integration test
|
|
547
|
+
yarn test:docker
|
|
548
|
+
|
|
549
|
+
# Test config loading specifically
|
|
550
|
+
yarn test:docker:config
|
|
551
|
+
|
|
552
|
+
# Run all tests (unit + integration + Docker)
|
|
553
|
+
yarn test:all
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
Or using Make:
|
|
557
|
+
|
|
558
|
+
```bash
|
|
559
|
+
# Quick Docker build test
|
|
560
|
+
make test-docker
|
|
561
|
+
|
|
562
|
+
# Full integration test suite
|
|
563
|
+
make test-docker-full
|
|
564
|
+
|
|
565
|
+
# Config loading test
|
|
566
|
+
make test-docker-config
|
|
567
|
+
|
|
568
|
+
# Docker Compose test
|
|
569
|
+
make test-docker-compose
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
See the [Docker Tests README](tests/docker/README.md) for more details.
|
|
573
|
+
|
|
574
|
+
## ๐ Performance
|
|
575
|
+
|
|
576
|
+
The proxy is built on Node.js native HTTP/2 implementation and is designed for high performance:
|
|
577
|
+
|
|
578
|
+
- Efficient stream handling
|
|
579
|
+
- Minimal overhead
|
|
580
|
+
- Connection pooling
|
|
581
|
+
- Automatic HTTP/1.1 fallback
|
|
582
|
+
|
|
583
|
+
For production deployments, consider:
|
|
584
|
+
|
|
585
|
+
- Using a process manager (PM2, systemd)
|
|
586
|
+
- Enabling clustering for multi-core systems
|
|
587
|
+
- Monitoring with health checks
|
|
588
|
+
- Setting up proper logging
|