@reldens/server-utils 0.45.0 → 0.46.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/.claude/api-reference.md +24 -1
- package/CLAUDE.md +1 -1
- package/lib/app-server-factory.js +35 -72
- package/lib/cdn-request-handler.js +2 -9
- package/lib/http2-cdn-server.js +106 -54
- package/package.json +3 -3
package/.claude/api-reference.md
CHANGED
|
@@ -77,6 +77,7 @@ Creates Express app servers with modular security components. Supports HTTP, HTT
|
|
|
77
77
|
- Lifecycle event dispatching
|
|
78
78
|
|
|
79
79
|
**Configuration Properties:**
|
|
80
|
+
- `http2CdnDomains` - Array of domain configurations for HTTP/2 CDN multi-certificate SNI (optional)
|
|
80
81
|
- `onError` - Custom error handler callback for server errors
|
|
81
82
|
- `onRequestSuccess` - Callback for successful requests
|
|
82
83
|
- `onRequestError` - Callback for failed requests
|
|
@@ -84,8 +85,11 @@ Creates Express app servers with modular security components. Supports HTTP, HTT
|
|
|
84
85
|
|
|
85
86
|
**Methods:**
|
|
86
87
|
- `createAppServer(config)` - Create and configure server
|
|
88
|
+
- `createHttp2CdnServer()` - Create HTTP/2 CDN server with optional multi-cert SNI
|
|
87
89
|
- `addDomain(domainConfig)` - Add virtual host domain
|
|
88
90
|
- `addDevelopmentDomain(domain)` - Add development domain
|
|
91
|
+
- `dispatch(eventName, eventData)` - Dispatch lifecycle event (wrapper for EventDispatcher)
|
|
92
|
+
- `handleError(errorType, error, context)` - Handle and log error (wrapper for ServerErrorHandler)
|
|
89
93
|
- `enableServeHome(app, callback)` - Enable homepage serving
|
|
90
94
|
- `serveStatics(app, staticPath)` - Serve static files
|
|
91
95
|
- `enableCSP(cspOptions)` - Enable Content Security Policy
|
|
@@ -157,6 +161,7 @@ File upload handling with Multer.
|
|
|
157
161
|
HTTP/2 secure server for CDN-like static file serving.
|
|
158
162
|
|
|
159
163
|
**Features:**
|
|
164
|
+
- Multi-certificate SNI support for multiple domains
|
|
160
165
|
- Optimized for CSS, JavaScript, images, and fonts
|
|
161
166
|
- Dynamic CORS origin validation with regex pattern support
|
|
162
167
|
- Configurable cache headers per file extension
|
|
@@ -167,19 +172,37 @@ HTTP/2 secure server for CDN-like static file serving.
|
|
|
167
172
|
- Comprehensive error handling (server, TLS, session, stream errors)
|
|
168
173
|
|
|
169
174
|
**Configuration Properties:**
|
|
175
|
+
- `domains` - Array of domain configurations for multi-certificate SNI (optional)
|
|
176
|
+
- `keyPath` - Path to SSL key file (backward compatibility, single cert mode)
|
|
177
|
+
- `certPath` - Path to SSL certificate file (backward compatibility, single cert mode)
|
|
170
178
|
- `onError` - Custom error handler callback for server errors
|
|
171
179
|
- `onRequestSuccess` - Callback for successful requests
|
|
172
180
|
- `onRequestError` - Callback for failed requests
|
|
173
181
|
- `onEvent` - Callback for lifecycle events
|
|
174
182
|
|
|
183
|
+
**Multi-Certificate Configuration Example:**
|
|
184
|
+
```javascript
|
|
185
|
+
domains: [
|
|
186
|
+
{hostname: 'cdn.domain1.com', keyPath: '/path/to/key1.pem', certPath: '/path/to/cert1.pem'},
|
|
187
|
+
{hostname: 'cdn.domain2.com', keyPath: '/path/to/key2.pem', certPath: '/path/to/cert2.pem'}
|
|
188
|
+
]
|
|
189
|
+
```
|
|
190
|
+
|
|
175
191
|
**Methods:**
|
|
176
|
-
- `create()` - Create HTTP/2 secure server
|
|
192
|
+
- `create()` - Create HTTP/2 secure server with SNI support
|
|
177
193
|
- `listen()` - Start listening on configured port
|
|
178
194
|
- `close()` - Gracefully close server
|
|
195
|
+
- `dispatch(eventName, eventData)` - Dispatch lifecycle event (wrapper for EventDispatcher)
|
|
196
|
+
- `handleError(errorType, error, context)` - Handle and log error (wrapper for ServerErrorHandler)
|
|
179
197
|
- `handleStream(stream, headers)` - Handle HTTP/2 stream
|
|
180
198
|
- `handleHttp1Request(req, res)` - Handle HTTP/1.1 fallback requests
|
|
181
199
|
- `resolveFilePath(requestPath)` - Resolve file path from request
|
|
182
200
|
- `setupEventHandlers()` - Configure server error event handlers
|
|
201
|
+
- `setupDomainConfiguration()` - Configure single or multi-certificate mode
|
|
202
|
+
- `validateCertificates()` - Validate all domain certificates exist
|
|
203
|
+
- `buildSniContexts()` - Build TLS contexts for each domain
|
|
204
|
+
- `getSniCallback()` - Get SNI callback for certificate selection
|
|
205
|
+
- `buildServerOptions()` - Build HTTP/2 server options with SNI support
|
|
183
206
|
|
|
184
207
|
## Utility Classes
|
|
185
208
|
|
package/CLAUDE.md
CHANGED
|
@@ -39,7 +39,7 @@ See `.claude/api-reference.md` for complete API documentation of all classes and
|
|
|
39
39
|
|
|
40
40
|
**UploaderFactory** - File upload handling with Multer and multi-level security validation.
|
|
41
41
|
|
|
42
|
-
**Http2CdnServer** - HTTP/2 secure server for CDN-like static file serving with CORS, cache headers, and callback-based logging.
|
|
42
|
+
**Http2CdnServer** - HTTP/2 secure server for CDN-like static file serving with multi-certificate SNI support, CORS, cache headers, and callback-based logging.
|
|
43
43
|
|
|
44
44
|
## Utility Classes Summary
|
|
45
45
|
|
|
@@ -117,12 +117,24 @@ class AppServerFactory
|
|
|
117
117
|
this.http2CdnCacheConfig = {};
|
|
118
118
|
this.http2CdnSecurityHeaders = {};
|
|
119
119
|
this.http2CdnServer = false;
|
|
120
|
+
this.http2CdnDomains = [];
|
|
120
121
|
this.reverseProxyEnabled = false;
|
|
121
122
|
this.reverseProxyRules = [];
|
|
122
123
|
this.onError = null;
|
|
123
124
|
this.onRequestSuccess = null;
|
|
124
125
|
this.onRequestError = null;
|
|
125
126
|
this.onEvent = null;
|
|
127
|
+
this.eventSource = 'appServerFactory';
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
dispatch(eventName, eventData)
|
|
131
|
+
{
|
|
132
|
+
EventDispatcher.dispatch(this.onEvent, eventName, this.eventSource, this, eventData);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
handleError(errorType, error, context)
|
|
136
|
+
{
|
|
137
|
+
ServerErrorHandler.handleError(this.onError, this.eventSource, this, errorType, error, context);
|
|
126
138
|
}
|
|
127
139
|
|
|
128
140
|
buildStaticHeaders(res, path)
|
|
@@ -168,13 +180,11 @@ class AppServerFactory
|
|
|
168
180
|
}
|
|
169
181
|
return false;
|
|
170
182
|
}
|
|
171
|
-
|
|
172
|
-
this.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
{port: this.port, useHttps: this.useHttps, isDevelopmentMode: this.isDevelopmentMode}
|
|
177
|
-
);
|
|
183
|
+
this.dispatch('app-server-created', {
|
|
184
|
+
port: this.port,
|
|
185
|
+
useHttps: this.useHttps,
|
|
186
|
+
isDevelopmentMode: this.isDevelopmentMode
|
|
187
|
+
});
|
|
178
188
|
if(this.http2CdnEnabled){
|
|
179
189
|
if(!this.createHttp2CdnServer()){
|
|
180
190
|
this.error = {message: 'The createHttp2CdnServer() returned false.'};
|
|
@@ -192,9 +202,14 @@ class AppServerFactory
|
|
|
192
202
|
this.http2CdnServer = new Http2CdnServer();
|
|
193
203
|
this.http2CdnServer.enabled = this.http2CdnEnabled;
|
|
194
204
|
this.http2CdnServer.port = this.http2CdnPort;
|
|
195
|
-
this.
|
|
196
|
-
|
|
197
|
-
|
|
205
|
+
if(this.http2CdnDomains && 0 < this.http2CdnDomains.length){
|
|
206
|
+
this.http2CdnServer.domains = this.http2CdnDomains;
|
|
207
|
+
}
|
|
208
|
+
if(!this.http2CdnDomains || 0 === this.http2CdnDomains.length){
|
|
209
|
+
this.http2CdnServer.keyPath = this.http2CdnKeyPath || this.keyPath;
|
|
210
|
+
this.http2CdnServer.certPath = this.http2CdnCertPath || this.certPath;
|
|
211
|
+
this.http2CdnServer.httpsChain = this.http2CdnHttpsChain || this.httpsChain;
|
|
212
|
+
}
|
|
198
213
|
this.http2CdnServer.staticPaths = this.http2CdnStaticPaths;
|
|
199
214
|
this.http2CdnServer.cacheConfig = this.http2CdnCacheConfig && 0 < Object.keys(this.http2CdnCacheConfig).length
|
|
200
215
|
? this.http2CdnCacheConfig
|
|
@@ -219,13 +234,7 @@ class AppServerFactory
|
|
|
219
234
|
this.error = this.http2CdnServer.error;
|
|
220
235
|
return false;
|
|
221
236
|
}
|
|
222
|
-
|
|
223
|
-
this.onEvent,
|
|
224
|
-
'http2-cdn-created',
|
|
225
|
-
'appServerFactory',
|
|
226
|
-
this,
|
|
227
|
-
{port: this.http2CdnPort}
|
|
228
|
-
);
|
|
237
|
+
this.dispatch('http2-cdn-created', {port: this.http2CdnPort});
|
|
229
238
|
return true;
|
|
230
239
|
}
|
|
231
240
|
|
|
@@ -434,14 +443,7 @@ class AppServerFactory
|
|
|
434
443
|
return next();
|
|
435
444
|
}
|
|
436
445
|
this.error = {message: 'No hostname provided and no default domain configured'};
|
|
437
|
-
|
|
438
|
-
this.onError,
|
|
439
|
-
'appServerFactory',
|
|
440
|
-
this,
|
|
441
|
-
'virtual-host-no-hostname',
|
|
442
|
-
this.error,
|
|
443
|
-
{request: req, response: res}
|
|
444
|
-
);
|
|
446
|
+
this.handleError('virtual-host-no-hostname', this.error, {request: req, response: res});
|
|
445
447
|
return res.status(400).send('Bad Request');
|
|
446
448
|
}
|
|
447
449
|
let domain = this.findDomainConfig(hostname);
|
|
@@ -451,10 +453,7 @@ class AppServerFactory
|
|
|
451
453
|
return next();
|
|
452
454
|
}
|
|
453
455
|
this.error = {message: 'Unknown domain: '+hostname};
|
|
454
|
-
|
|
455
|
-
this.onError,
|
|
456
|
-
'appServerFactory',
|
|
457
|
-
this,
|
|
456
|
+
this.handleError(
|
|
458
457
|
'virtual-host-unknown-domain',
|
|
459
458
|
this.error,
|
|
460
459
|
{hostname: hostname, request: req, response: res}
|
|
@@ -489,13 +488,7 @@ class AppServerFactory
|
|
|
489
488
|
{
|
|
490
489
|
if(!this.useHttps){
|
|
491
490
|
let httpServer = http.createServer(this.app);
|
|
492
|
-
|
|
493
|
-
this.onEvent,
|
|
494
|
-
'http-server-created',
|
|
495
|
-
'appServerFactory',
|
|
496
|
-
this,
|
|
497
|
-
{port: this.port}
|
|
498
|
-
);
|
|
491
|
+
this.dispatch('http-server-created', {port: this.port});
|
|
499
492
|
return httpServer;
|
|
500
493
|
}
|
|
501
494
|
if(this.useVirtualHosts && 0 < this.domains.length){
|
|
@@ -524,13 +517,7 @@ class AppServerFactory
|
|
|
524
517
|
}
|
|
525
518
|
}
|
|
526
519
|
let httpsServer = https.createServer(credentials, this.app);
|
|
527
|
-
|
|
528
|
-
this.onEvent,
|
|
529
|
-
'https-server-created',
|
|
530
|
-
'appServerFactory',
|
|
531
|
-
this,
|
|
532
|
-
{port: this.port}
|
|
533
|
-
);
|
|
520
|
+
this.dispatch('https-server-created', {port: this.port});
|
|
534
521
|
return httpsServer;
|
|
535
522
|
}
|
|
536
523
|
|
|
@@ -549,10 +536,7 @@ class AppServerFactory
|
|
|
549
536
|
let key = FileHandler.readFile(domain.keyPath, 'Domain Key');
|
|
550
537
|
if(!key){
|
|
551
538
|
this.error = {message: 'Could not read domain SSL key: '+domain.keyPath};
|
|
552
|
-
|
|
553
|
-
this.onError,
|
|
554
|
-
'appServerFactory',
|
|
555
|
-
this,
|
|
539
|
+
this.handleError(
|
|
556
540
|
'sni-key-read-failure',
|
|
557
541
|
this.error,
|
|
558
542
|
{hostname: hostname, domain: domain, keyPath: domain.keyPath}
|
|
@@ -562,10 +546,7 @@ class AppServerFactory
|
|
|
562
546
|
let cert = FileHandler.readFile(domain.certPath, 'Domain Cert');
|
|
563
547
|
if(!cert){
|
|
564
548
|
this.error = {message: 'Could not read domain SSL certificate: '+domain.certPath};
|
|
565
|
-
|
|
566
|
-
this.onError,
|
|
567
|
-
'appServerFactory',
|
|
568
|
-
this,
|
|
549
|
+
this.handleError(
|
|
569
550
|
'sni-cert-read-failure',
|
|
570
551
|
this.error,
|
|
571
552
|
{hostname: hostname, domain: domain, certPath: domain.certPath}
|
|
@@ -576,13 +557,7 @@ class AppServerFactory
|
|
|
576
557
|
callback(null, ctx);
|
|
577
558
|
};
|
|
578
559
|
let sniServer = https.createServer(httpsOptions, this.app);
|
|
579
|
-
|
|
580
|
-
this.onEvent,
|
|
581
|
-
'sni-server-created',
|
|
582
|
-
'appServerFactory',
|
|
583
|
-
this,
|
|
584
|
-
{port: this.port, domainsCount: this.domains.length}
|
|
585
|
-
);
|
|
560
|
+
this.dispatch('sni-server-created', {port: this.port, domainsCount: this.domains.length});
|
|
586
561
|
return sniServer;
|
|
587
562
|
}
|
|
588
563
|
|
|
@@ -609,13 +584,7 @@ class AppServerFactory
|
|
|
609
584
|
return false;
|
|
610
585
|
}
|
|
611
586
|
this.appServer.listen(listenPort);
|
|
612
|
-
|
|
613
|
-
this.onEvent,
|
|
614
|
-
'app-server-listening',
|
|
615
|
-
'appServerFactory',
|
|
616
|
-
this,
|
|
617
|
-
{port: listenPort}
|
|
618
|
-
);
|
|
587
|
+
this.dispatch('app-server-listening', {port: listenPort});
|
|
619
588
|
return true;
|
|
620
589
|
}
|
|
621
590
|
|
|
@@ -677,13 +646,7 @@ class AppServerFactory
|
|
|
677
646
|
return false;
|
|
678
647
|
}
|
|
679
648
|
this.domains.push(domainConfig);
|
|
680
|
-
|
|
681
|
-
this.onEvent,
|
|
682
|
-
'domain-added',
|
|
683
|
-
'appServerFactory',
|
|
684
|
-
this,
|
|
685
|
-
{hostname: domainConfig.hostname}
|
|
686
|
-
);
|
|
649
|
+
this.dispatch('domain-added', {hostname: domainConfig.hostname});
|
|
687
650
|
return true;
|
|
688
651
|
}
|
|
689
652
|
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
const { FileHandler } = require('./file-handler');
|
|
8
8
|
const { ServerFactoryUtils } = require('./server-factory-utils');
|
|
9
|
-
const { ServerErrorHandler } = require('./server-error-handler');
|
|
10
9
|
|
|
11
10
|
class CdnRequestHandler
|
|
12
11
|
{
|
|
@@ -62,10 +61,7 @@ class CdnRequestHandler
|
|
|
62
61
|
requestData.statusCode = 500;
|
|
63
62
|
requestData.responseTime = Date.now()-startTime;
|
|
64
63
|
requestData.error = err;
|
|
65
|
-
|
|
66
|
-
this.cdnServer.onError,
|
|
67
|
-
'http2CdnServer',
|
|
68
|
-
this.cdnServer,
|
|
64
|
+
this.cdnServer.handleError(
|
|
69
65
|
requestContext.isHttp2 ? 'stream-error' : 'http1-stream-error',
|
|
70
66
|
err,
|
|
71
67
|
{port: this.cdnServer.port, path: requestData.path}
|
|
@@ -77,10 +73,7 @@ class CdnRequestHandler
|
|
|
77
73
|
requestData.statusCode = 500;
|
|
78
74
|
requestData.responseTime = Date.now()-startTime;
|
|
79
75
|
requestData.error = err;
|
|
80
|
-
|
|
81
|
-
this.cdnServer.onError,
|
|
82
|
-
'http2CdnServer',
|
|
83
|
-
this.cdnServer,
|
|
76
|
+
this.cdnServer.handleError(
|
|
84
77
|
requestContext.isHttp2 ? 'handle-stream-error' : 'handle-http1-request-error',
|
|
85
78
|
err,
|
|
86
79
|
{port: this.cdnServer.port, path: requestData.path}
|
package/lib/http2-cdn-server.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const http2 = require('http2');
|
|
8
|
+
const tls = require('tls');
|
|
8
9
|
const { FileHandler } = require('./file-handler');
|
|
9
10
|
const { ServerDefaultConfigurations } = require('./server-default-configurations');
|
|
10
11
|
const { ServerFactoryUtils } = require('./server-factory-utils');
|
|
@@ -41,22 +42,112 @@ class Http2CdnServer
|
|
|
41
42
|
this.onRequestError = null;
|
|
42
43
|
this.onEvent = null;
|
|
43
44
|
this.requestHandler = new CdnRequestHandler(this);
|
|
45
|
+
this.domains = [];
|
|
46
|
+
this.useMultiCert = false;
|
|
47
|
+
this.defaultDomain = null;
|
|
48
|
+
this.sniContexts = {};
|
|
49
|
+
this.eventSource = 'http2CdnServer';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
dispatch(eventName, eventData)
|
|
53
|
+
{
|
|
54
|
+
EventDispatcher.dispatch(this.onEvent, eventName, this.eventSource, this, eventData);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
handleError(errorType, error, context)
|
|
58
|
+
{
|
|
59
|
+
ServerErrorHandler.handleError(this.onError, this.eventSource, this, errorType, error, context);
|
|
44
60
|
}
|
|
45
61
|
|
|
46
62
|
create()
|
|
47
63
|
{
|
|
48
|
-
|
|
49
|
-
|
|
64
|
+
this.setupDomainConfiguration();
|
|
65
|
+
if(!this.validateCertificates()){
|
|
50
66
|
return false;
|
|
51
67
|
}
|
|
52
|
-
|
|
68
|
+
if(this.useMultiCert){
|
|
69
|
+
this.buildSniContexts();
|
|
70
|
+
}
|
|
71
|
+
let options = this.buildServerOptions();
|
|
72
|
+
if(!options){
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
this.http2Server = http2.createSecureServer(options);
|
|
76
|
+
this.setupEventHandlers();
|
|
77
|
+
this.dispatch(
|
|
78
|
+
'cdn-server-created',
|
|
79
|
+
{port: this.port, allowHTTP1: this.allowHTTP1, multiCert: this.useMultiCert})
|
|
80
|
+
;
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
setupDomainConfiguration()
|
|
85
|
+
{
|
|
86
|
+
if(this.domains && 0 < this.domains.length){
|
|
87
|
+
this.useMultiCert = true;
|
|
88
|
+
this.defaultDomain = this.domains[0];
|
|
89
|
+
this.dispatch('cdn-multi-cert-enabled', {domains: this.domains.map(d => d.hostname)});
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if(this.keyPath && this.certPath){
|
|
93
|
+
this.useMultiCert = false;
|
|
94
|
+
this.domains = [{hostname: 'default', keyPath: this.keyPath, certPath: this.certPath}];
|
|
95
|
+
this.defaultDomain = this.domains[0];
|
|
96
|
+
this.dispatch('cdn-single-cert-mode', {hostname: this.defaultDomain.hostname});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
this.error = {message: 'HTTP/2 CDN requires domains array or keyPath/certPath'};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
validateCertificates()
|
|
103
|
+
{
|
|
104
|
+
for(let domain of this.domains){
|
|
105
|
+
if(!FileHandler.exists(domain.keyPath)){
|
|
106
|
+
this.error = {message: 'Certificate key not found for '+domain.hostname+': '+domain.keyPath};
|
|
107
|
+
this.handleError('certificate-key-not-found', this.error, {hostname: domain.hostname, keyPath: domain.keyPath});
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
if(!FileHandler.exists(domain.certPath)){
|
|
111
|
+
this.error = {message: 'Certificate file not found for '+domain.hostname+': '+domain.certPath};
|
|
112
|
+
this.handleError('certificate-not-found', this.error, {hostname: domain.hostname, certPath: domain.certPath});
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
buildSniContexts()
|
|
120
|
+
{
|
|
121
|
+
for(let domain of this.domains){
|
|
122
|
+
let key = FileHandler.readFile(domain.keyPath);
|
|
123
|
+
let cert = FileHandler.readFile(domain.certPath);
|
|
124
|
+
this.sniContexts[domain.hostname] = tls.createSecureContext({key, cert});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
getSniCallback()
|
|
129
|
+
{
|
|
130
|
+
return (servername, callback) => {
|
|
131
|
+
this.dispatch('cdn-sni-request', {servername});
|
|
132
|
+
let context = this.sniContexts[servername];
|
|
133
|
+
if(!context){
|
|
134
|
+
this.dispatch('cdn-sni-fallback', {servername, defaultHostname: this.defaultDomain.hostname});
|
|
135
|
+
context = this.sniContexts[this.defaultDomain.hostname];
|
|
136
|
+
}
|
|
137
|
+
callback(null, context);
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
buildServerOptions()
|
|
142
|
+
{
|
|
143
|
+
let key = FileHandler.readFile(this.defaultDomain.keyPath);
|
|
53
144
|
if(!key){
|
|
54
|
-
this.error = {message: 'Could not read key from: '+this.keyPath};
|
|
145
|
+
this.error = {message: 'Could not read key from: '+this.defaultDomain.keyPath};
|
|
55
146
|
return false;
|
|
56
147
|
}
|
|
57
|
-
let cert = FileHandler.readFile(this.certPath);
|
|
148
|
+
let cert = FileHandler.readFile(this.defaultDomain.certPath);
|
|
58
149
|
if(!cert){
|
|
59
|
-
this.error = {message: 'Could not read cert from: '+this.certPath};
|
|
150
|
+
this.error = {message: 'Could not read cert from: '+this.defaultDomain.certPath};
|
|
60
151
|
return false;
|
|
61
152
|
}
|
|
62
153
|
let options = {key, cert, allowHTTP1: this.allowHTTP1};
|
|
@@ -66,16 +157,10 @@ class Http2CdnServer
|
|
|
66
157
|
options.ca = ca;
|
|
67
158
|
}
|
|
68
159
|
}
|
|
69
|
-
this.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
'cdn-server-created',
|
|
74
|
-
'http2CdnServer',
|
|
75
|
-
this,
|
|
76
|
-
{port: this.port, allowHTTP1: this.allowHTTP1}
|
|
77
|
-
);
|
|
78
|
-
return true;
|
|
160
|
+
if(this.useMultiCert){
|
|
161
|
+
options.SNICallback = this.getSniCallback();
|
|
162
|
+
}
|
|
163
|
+
return options;
|
|
79
164
|
}
|
|
80
165
|
|
|
81
166
|
setupEventHandlers()
|
|
@@ -87,42 +172,15 @@ class Http2CdnServer
|
|
|
87
172
|
this.handleHttp1Request(req, res);
|
|
88
173
|
});
|
|
89
174
|
this.http2Server.on('error', (err) => {
|
|
90
|
-
|
|
91
|
-
this.onError,
|
|
92
|
-
'http2CdnServer',
|
|
93
|
-
this,
|
|
94
|
-
'server-error',
|
|
95
|
-
err,
|
|
96
|
-
{port: this.port}
|
|
97
|
-
);
|
|
175
|
+
this.handleError('server-error', err, {port: this.port});
|
|
98
176
|
});
|
|
99
177
|
this.http2Server.on('tlsClientError', (err, tlsSocket) => {
|
|
100
|
-
|
|
101
|
-
this.onError,
|
|
102
|
-
'http2CdnServer',
|
|
103
|
-
this,
|
|
104
|
-
'tls-client-error',
|
|
105
|
-
err,
|
|
106
|
-
{port: this.port, remoteAddress: tlsSocket.remoteAddress}
|
|
107
|
-
);
|
|
178
|
+
this.handleError('tls-client-error', err, {port: this.port, remoteAddress: tlsSocket.remoteAddress});
|
|
108
179
|
});
|
|
109
180
|
this.http2Server.on('sessionError', (err) => {
|
|
110
|
-
|
|
111
|
-
this.onError,
|
|
112
|
-
'http2CdnServer',
|
|
113
|
-
this,
|
|
114
|
-
'session-error',
|
|
115
|
-
err,
|
|
116
|
-
{port: this.port}
|
|
117
|
-
);
|
|
181
|
+
this.handleError('session-error', err, {port: this.port});
|
|
118
182
|
});
|
|
119
|
-
|
|
120
|
-
this.onEvent,
|
|
121
|
-
'cdn-handlers-setup',
|
|
122
|
-
'http2CdnServer',
|
|
123
|
-
this,
|
|
124
|
-
{port: this.port}
|
|
125
|
-
);
|
|
183
|
+
this.dispatch('cdn-handlers-setup', {port: this.port});
|
|
126
184
|
}
|
|
127
185
|
|
|
128
186
|
invokeRequestSuccess(requestData)
|
|
@@ -246,13 +304,7 @@ class Http2CdnServer
|
|
|
246
304
|
return false;
|
|
247
305
|
}
|
|
248
306
|
this.http2Server.listen(this.port);
|
|
249
|
-
|
|
250
|
-
this.onEvent,
|
|
251
|
-
'cdn-server-listening',
|
|
252
|
-
'http2CdnServer',
|
|
253
|
-
this,
|
|
254
|
-
{port: this.port}
|
|
255
|
-
);
|
|
307
|
+
this.dispatch('cdn-server-listening', {port: this.port});
|
|
256
308
|
return true;
|
|
257
309
|
}
|
|
258
310
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reldens/server-utils",
|
|
3
3
|
"scope": "@reldens",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.46.0",
|
|
5
5
|
"description": "Reldens - Server Utils",
|
|
6
6
|
"author": "Damian A. Pastorini",
|
|
7
7
|
"license": "MIT",
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"body-parser": "2.2.2",
|
|
40
40
|
"compression": "1.8.1",
|
|
41
|
-
"cors": "2.8.
|
|
41
|
+
"cors": "2.8.6",
|
|
42
42
|
"express": "4.22.1",
|
|
43
43
|
"express-rate-limit": "8.2.1",
|
|
44
|
-
"express-session": "1.
|
|
44
|
+
"express-session": "1.19.0",
|
|
45
45
|
"helmet": "8.1.0",
|
|
46
46
|
"http-proxy-middleware": "3.0.5",
|
|
47
47
|
"multer": "2.0.2",
|