@reldens/server-utils 0.33.0 → 0.35.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/README.md CHANGED
@@ -9,6 +9,8 @@ A Node.js server toolkit providing secure application server creation, file hand
9
9
  ### AppServerFactory
10
10
  - Complete Express.js server configuration with modular security
11
11
  - HTTPS/HTTP server creation with SSL certificate management
12
+ - HTTP/2 support via spdy with automatic HTTP/1.1 fallback
13
+ - Optimized static asset caching for CSS, JS, fonts, and images
12
14
  - SNI (Server Name Indication) support for multi-domain hosting
13
15
  - Virtual host management with domain mapping
14
16
  - Development mode detection with appropriate configurations
@@ -99,6 +101,40 @@ if(serverResult){
99
101
  }
100
102
  ```
101
103
 
104
+ ### HTTP/2 Server with Optimized Caching
105
+
106
+ ```javascript
107
+ let appServerFactory = new AppServerFactory();
108
+ let serverResult = appServerFactory.createAppServer({
109
+ port: 443,
110
+ useHttps: true,
111
+ useHttp2: true,
112
+ keyPath: '/ssl/server.key',
113
+ certPath: '/ssl/server.crt',
114
+ autoListen: true
115
+ });
116
+ ```
117
+
118
+ Cache configuration is automatic with defaults:
119
+ - CSS/JS: 1 year
120
+ - Fonts: 1 year
121
+ - Images: 30 days
122
+
123
+ Override cache settings if needed:
124
+
125
+ ```javascript
126
+ let appServerFactory = new AppServerFactory();
127
+ appServerFactory.cacheConfig = {
128
+ '.css': 86400,
129
+ '.js': 86400,
130
+ '.png': 604800
131
+ };
132
+ let serverResult = appServerFactory.createAppServer({
133
+ useHttps: true,
134
+ useHttp2: true
135
+ });
136
+ ```
137
+
102
138
  ### File Operations
103
139
 
104
140
  ```javascript
@@ -193,6 +229,7 @@ appServerFactory.addDomain({
193
229
 
194
230
  let serverResult = appServerFactory.createAppServer({
195
231
  useHttps: true,
232
+ useHttp2: true,
196
233
  useVirtualHosts: true,
197
234
  keyPath: '/ssl/default.key',
198
235
  certPath: '/ssl/default.crt',
@@ -328,6 +365,9 @@ Configurable rate limiting with development mode detection for appropriate thres
328
365
  ### HTTPS Support
329
366
  Full SSL/TLS support with SNI for multi-domain hosting and automatic certificate management.
330
367
 
368
+ ### HTTP/2 Support
369
+ HTTP/2 support via spdy with multiplexing for improved performance and automatic HTTP/1.1 fallback for older clients.
370
+
331
371
  ### Input Validation
332
372
  Built-in validators for common input types including email, username, strong passwords, alphanumeric strings, and IP addresses.
333
373
 
@@ -61,15 +61,28 @@ class AppServerFactory
61
61
  this.defaultDomain = '';
62
62
  this.maxRequestSize = '10mb';
63
63
  this.sanitizeOptions = {allowedTags: [], allowedAttributes: {}};
64
+ this.cacheConfig = {
65
+ '.css': 31536000,
66
+ '.js': 31536000,
67
+ '.woff': 31536000,
68
+ '.woff2': 31536000,
69
+ '.ttf': 31536000,
70
+ '.eot': 31536000,
71
+ '.jpg': 2592000,
72
+ '.jpeg': 2592000,
73
+ '.png': 2592000,
74
+ '.gif': 2592000,
75
+ '.webp': 2592000,
76
+ '.svg': 2592000,
77
+ '.ico': 2592000
78
+ };
64
79
  this.staticOptions = {
65
80
  maxAge: '1d',
81
+ immutable: false,
66
82
  etag: true,
67
83
  lastModified: true,
68
84
  index: false,
69
- setHeaders: function(res){
70
- res.set('X-Content-Type-Options', 'nosniff');
71
- res.set('X-Frame-Options', 'DENY');
72
- }
85
+ setHeaders: this.buildStaticHeaders.bind(this)
73
86
  };
74
87
  this.isDevelopmentMode = false;
75
88
  this.developmentDomains = [];
@@ -98,6 +111,28 @@ class AppServerFactory
98
111
  };
99
112
  }
100
113
 
114
+ buildStaticHeaders(res, path)
115
+ {
116
+ res.set('X-Content-Type-Options', 'nosniff');
117
+ res.set('X-Frame-Options', 'DENY');
118
+ res.set('Vary', 'Accept-Encoding');
119
+ let cacheMaxAge = this.getCacheConfigForPath(path);
120
+ if(cacheMaxAge){
121
+ res.set('Cache-Control', 'public, max-age='+cacheMaxAge+', immutable');
122
+ }
123
+ }
124
+
125
+ getCacheConfigForPath(path)
126
+ {
127
+ let cacheKeys = Object.keys(this.cacheConfig);
128
+ for(let ext of cacheKeys){
129
+ if(path.endsWith(ext)){
130
+ return this.cacheConfig[ext];
131
+ }
132
+ }
133
+ return false;
134
+ }
135
+
101
136
  createAppServer(appServerConfig)
102
137
  {
103
138
  if(appServerConfig){
@@ -117,7 +152,7 @@ class AppServerFactory
117
152
  try {
118
153
  this.appServer = this.createServer();
119
154
  } catch (error) {
120
- this.error = {message: 'Server creation exception: ' + error.message};
155
+ this.error = {message: 'Server creation exception: '+error.message};
121
156
  return false;
122
157
  }
123
158
  if(!this.appServer){
@@ -172,12 +207,14 @@ class AppServerFactory
172
207
  if(!this.isDevelopmentMode){
173
208
  return;
174
209
  }
175
- this.staticOptions.setHeaders = (res) => {
210
+ this.staticOptions.immutable = false;
211
+ this.staticOptions.setHeaders = (res, path) => {
176
212
  res.set('X-Content-Type-Options', 'nosniff');
177
213
  res.set('X-Frame-Options', 'SAMEORIGIN');
178
214
  res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
179
215
  res.set('Pragma', 'no-cache');
180
216
  res.set('Expires', '0');
217
+ res.set('Vary', 'Accept-Encoding');
181
218
  };
182
219
  }
183
220
 
@@ -313,7 +350,7 @@ class AppServerFactory
313
350
  req.domain = this.defaultDomain;
314
351
  return next();
315
352
  }
316
- this.error = {message: 'Unknown domain: ' + hostname};
353
+ this.error = {message: 'Unknown domain: '+hostname};
317
354
  return res.status(404).send('Domain not found');
318
355
  }
319
356
  req.domain = domain;
@@ -355,12 +392,12 @@ class AppServerFactory
355
392
  {
356
393
  let key = FileHandler.readFile(this.keyPath, 'Key');
357
394
  if(!key){
358
- this.error = {message: 'Could not read SSL key file: ' + this.keyPath};
395
+ this.error = {message: 'Could not read SSL key file: '+this.keyPath};
359
396
  return false;
360
397
  }
361
398
  let cert = FileHandler.readFile(this.certPath, 'Cert');
362
399
  if(!cert){
363
- this.error = {message: 'Could not read SSL certificate file: ' + this.certPath};
400
+ this.error = {message: 'Could not read SSL certificate file: '+this.certPath};
364
401
  return false;
365
402
  }
366
403
  let credentials = {key, cert, passphrase: this.passphrase};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@reldens/server-utils",
3
3
  "scope": "@reldens",
4
- "version": "0.33.0",
4
+ "version": "0.35.0",
5
5
  "description": "Reldens - Server Utils",
6
6
  "author": "Damian A. Pastorini",
7
7
  "license": "MIT",
@@ -17,17 +17,18 @@
17
17
  "utils",
18
18
  "shortcuts",
19
19
  "system",
20
- "game",
21
- "mmorpg",
22
- "rpg",
20
+ "server",
21
+ "http",
22
+ "https",
23
23
  "dwd",
24
- "colyseus",
25
- "phaser",
26
- "parcel",
24
+ "http2",
25
+ "file",
26
+ "encrypt",
27
+ "uploader",
28
+ "upload",
29
+ "cors",
27
30
  "nodejs",
28
- "mmo",
29
- "multiplayer",
30
- "rol",
31
+ "protocol",
31
32
  "platform",
32
33
  "framework"
33
34
  ],