alchemymvc 1.3.17 → 1.3.18
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/lib/class/conduit.js +69 -23
- package/lib/init/alchemy.js +128 -24
- package/lib/init/requirements.js +0 -7
- package/package.json +1 -1
package/lib/class/conduit.js
CHANGED
|
@@ -125,12 +125,23 @@ Conduit.setProperty(function scene() {
|
|
|
125
125
|
return this.getSession().getScene(this.scene_id);
|
|
126
126
|
});
|
|
127
127
|
|
|
128
|
+
/**
|
|
129
|
+
* The session cookie name to use
|
|
130
|
+
*
|
|
131
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
132
|
+
* @since 1.3.18
|
|
133
|
+
* @version 1.3.18
|
|
134
|
+
*/
|
|
135
|
+
Conduit.setProperty(function session_cookie_name() {
|
|
136
|
+
return alchemy.settings.session_key || 'alchemy_sid';
|
|
137
|
+
});
|
|
138
|
+
|
|
128
139
|
/**
|
|
129
140
|
* Enforce the scene_id
|
|
130
141
|
*
|
|
131
142
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
132
143
|
* @since 1.1.0
|
|
133
|
-
* @version 1.3.
|
|
144
|
+
* @version 1.3.18
|
|
134
145
|
*/
|
|
135
146
|
Conduit.enforceProperty(function scene_id(new_value, old_value) {
|
|
136
147
|
|
|
@@ -160,7 +171,10 @@ Conduit.enforceProperty(function scene_id(new_value, old_value) {
|
|
|
160
171
|
path: path,
|
|
161
172
|
|
|
162
173
|
// Cookie should not live for more than 15 seconds
|
|
163
|
-
maxAge: 1000 * 15
|
|
174
|
+
maxAge: 1000 * 15,
|
|
175
|
+
|
|
176
|
+
// It should be restricted to the same domain
|
|
177
|
+
domain: false,
|
|
164
178
|
});
|
|
165
179
|
}
|
|
166
180
|
}
|
|
@@ -259,12 +273,17 @@ Conduit.setProperty(function is_secure() {
|
|
|
259
273
|
*
|
|
260
274
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
261
275
|
* @since 1.1.0
|
|
262
|
-
* @version 1.
|
|
276
|
+
* @version 1.3.18
|
|
263
277
|
*
|
|
264
|
-
* @param {Object}
|
|
278
|
+
* @param {Object|String}
|
|
265
279
|
*/
|
|
266
280
|
Conduit.setMethod(function setRequestBody(body) {
|
|
267
281
|
|
|
282
|
+
if (typeof body == 'string') {
|
|
283
|
+
this.body = body;
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
|
|
268
287
|
if (!body) {
|
|
269
288
|
return;
|
|
270
289
|
}
|
|
@@ -492,20 +511,18 @@ Conduit.setMethod(function time() {
|
|
|
492
511
|
*
|
|
493
512
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
494
513
|
* @since 0.2.0
|
|
495
|
-
* @version 1.3.
|
|
514
|
+
* @version 1.3.18
|
|
496
515
|
*
|
|
497
516
|
* @param {IncomingMessage} req
|
|
498
517
|
* @param {ServerResponse} res
|
|
499
518
|
*/
|
|
500
519
|
Conduit.setMethod(async function parseRequest() {
|
|
501
520
|
|
|
502
|
-
var protocol,
|
|
503
|
-
section;
|
|
504
|
-
|
|
505
521
|
if (this.method == null && this.request && this.request.method) {
|
|
506
522
|
this.method = this.request.method.toLowerCase();
|
|
507
523
|
}
|
|
508
524
|
|
|
525
|
+
this.parseUrl();
|
|
509
526
|
this.parseShortcuts();
|
|
510
527
|
this.parseLanguages();
|
|
511
528
|
this.parsePrefix();
|
|
@@ -529,11 +546,25 @@ Conduit.setMethod(async function parseRequest() {
|
|
|
529
546
|
this.overrideResponseUrl(new_url);
|
|
530
547
|
}
|
|
531
548
|
|
|
549
|
+
this.parseUrl();
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Parse the url if it hasn't been done already
|
|
554
|
+
*
|
|
555
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
556
|
+
* @since 1.3.18
|
|
557
|
+
* @version 1.3.18
|
|
558
|
+
*/
|
|
559
|
+
Conduit.setMethod(function parseUrl() {
|
|
560
|
+
|
|
532
561
|
// If the url has already been parsed, return early
|
|
533
562
|
if (this.url) {
|
|
534
|
-
return;
|
|
563
|
+
return false;
|
|
535
564
|
}
|
|
536
565
|
|
|
566
|
+
let protocol;
|
|
567
|
+
|
|
537
568
|
if (alchemy.settings.assume_https) {
|
|
538
569
|
protocol = 'https://';
|
|
539
570
|
} else if (this.headers['x-forwarded-proto']) {
|
|
@@ -557,10 +588,10 @@ Conduit.setMethod(async function parseRequest() {
|
|
|
557
588
|
|
|
558
589
|
// If no URL was set, use the first requests URL (without the path)
|
|
559
590
|
if (!alchemy.settings.url && this.headers.host) {
|
|
560
|
-
alchemy.
|
|
591
|
+
alchemy.setUrl(this.url);
|
|
561
592
|
}
|
|
562
593
|
|
|
563
|
-
let path = this.
|
|
594
|
+
let path = this.original_path;
|
|
564
595
|
|
|
565
596
|
if (this.prefix) {
|
|
566
597
|
path = '/' + this.prefix + '/' + path;
|
|
@@ -2290,7 +2321,7 @@ Conduit.setMethod(function _sendStream(stream, options) {
|
|
|
2290
2321
|
*
|
|
2291
2322
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
2292
2323
|
* @since 0.2.0
|
|
2293
|
-
* @version 1.3.
|
|
2324
|
+
* @version 1.3.18
|
|
2294
2325
|
*
|
|
2295
2326
|
* @param {Boolean} create Create a session if none exist
|
|
2296
2327
|
*
|
|
@@ -2303,13 +2334,10 @@ Conduit.setMethod(function getSession(allow_create = true) {
|
|
|
2303
2334
|
return this.sessionData;
|
|
2304
2335
|
}
|
|
2305
2336
|
|
|
2306
|
-
let cookie_name,
|
|
2337
|
+
let cookie_name = this.session_cookie_name,
|
|
2307
2338
|
session_id,
|
|
2308
2339
|
session;
|
|
2309
2340
|
|
|
2310
|
-
// Set the name of the cookie (could change in the future)
|
|
2311
|
-
cookie_name = alchemy.settings.session_key || 'alchemy_sid';
|
|
2312
|
-
|
|
2313
2341
|
// Get the ID of the session
|
|
2314
2342
|
session_id = this.cookie(cookie_name);
|
|
2315
2343
|
|
|
@@ -2473,9 +2501,9 @@ Conduit.setMethod(function setRouteParameters(data) {
|
|
|
2473
2501
|
/**
|
|
2474
2502
|
* Get/set a cookie
|
|
2475
2503
|
*
|
|
2476
|
-
* @author Jelle De Loecker <jelle@
|
|
2504
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
2477
2505
|
* @since 0.2.0
|
|
2478
|
-
* @version
|
|
2506
|
+
* @version 1.3.18
|
|
2479
2507
|
*
|
|
2480
2508
|
* @param {String} name
|
|
2481
2509
|
* @param {Mixed} value
|
|
@@ -2483,10 +2511,6 @@ Conduit.setMethod(function setRouteParameters(data) {
|
|
|
2483
2511
|
*/
|
|
2484
2512
|
Conduit.setMethod(function cookie(name, value, options) {
|
|
2485
2513
|
|
|
2486
|
-
var header,
|
|
2487
|
-
arr,
|
|
2488
|
-
key;
|
|
2489
|
-
|
|
2490
2514
|
// Return if cookies are disabled
|
|
2491
2515
|
if (!alchemy.settings.cookies) {
|
|
2492
2516
|
return;
|
|
@@ -2517,12 +2541,34 @@ Conduit.setMethod(function cookie(name, value, options) {
|
|
|
2517
2541
|
// Store it in the new_cookies object, for quick access
|
|
2518
2542
|
this.new_cookies[name] = value;
|
|
2519
2543
|
|
|
2544
|
+
// If there is no domain set, see if it is required
|
|
2545
|
+
if ((options.domain === true || options.domain == null) && alchemy.settings.cookie_domain && this.url) {
|
|
2546
|
+
let wanted_domain = alchemy.settings.cookie_domain,
|
|
2547
|
+
actual_domain = this.url.hostname;
|
|
2548
|
+
|
|
2549
|
+
if (wanted_domain != actual_domain) {
|
|
2550
|
+
// You can only set a cookie on the current domain,
|
|
2551
|
+
// or a parent domain. But not on a child domain.
|
|
2552
|
+
if (wanted_domain.length < actual_domain.length && actual_domain.endsWith(wanted_domain)) {
|
|
2553
|
+
// It's allowed!
|
|
2554
|
+
} else {
|
|
2555
|
+
// When on a domain like "11ways.be" you
|
|
2556
|
+
// can not set a cookie for "www.11ways.be"
|
|
2557
|
+
wanted_domain = false;
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
|
|
2561
|
+
if (wanted_domain) {
|
|
2562
|
+
options.domain = wanted_domain;
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
|
|
2520
2566
|
if (this.websocket) {
|
|
2521
2567
|
return this.socket.emit('alchemy-set-cookie', {name: name, value: value, options: options});
|
|
2522
2568
|
}
|
|
2523
2569
|
|
|
2524
2570
|
// Create the basic header string
|
|
2525
|
-
header = String.encodeCookie(name, value, options);
|
|
2571
|
+
let header = String.encodeCookie(name, value, options);
|
|
2526
2572
|
|
|
2527
2573
|
// Add this to the cookieheader array
|
|
2528
2574
|
this.new_cookie_header.push(header);
|
package/lib/init/alchemy.js
CHANGED
|
@@ -338,7 +338,7 @@ Alchemy.setMethod(function isTooBusyForRequests() {
|
|
|
338
338
|
*
|
|
339
339
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
340
340
|
* @since 1.3.1
|
|
341
|
-
* @version 1.3.
|
|
341
|
+
* @version 1.3.18
|
|
342
342
|
*
|
|
343
343
|
* @return {Boolean}
|
|
344
344
|
*/
|
|
@@ -348,11 +348,11 @@ Alchemy.setMethod(function isTooBusyForAjax() {
|
|
|
348
348
|
return false;
|
|
349
349
|
}
|
|
350
350
|
|
|
351
|
-
let
|
|
352
|
-
|
|
353
|
-
let max_event_loop_lag = alchemy.settings.max_event_loop_lag || alchemy.settings.toobusy;
|
|
351
|
+
let max_event_loop_lag = alchemy.settings.max_event_loop_lag ?? alchemy.settings.toobusy;
|
|
354
352
|
|
|
355
353
|
if (max_event_loop_lag) {
|
|
354
|
+
let lag = this.lagInMs();
|
|
355
|
+
|
|
356
356
|
if (lag > (max_event_loop_lag * 3)) {
|
|
357
357
|
return true;
|
|
358
358
|
}
|
|
@@ -361,6 +361,28 @@ Alchemy.setMethod(function isTooBusyForAjax() {
|
|
|
361
361
|
return false;
|
|
362
362
|
});
|
|
363
363
|
|
|
364
|
+
/**
|
|
365
|
+
* Set the maximum event loop lag before the server is considered overloaded
|
|
366
|
+
*
|
|
367
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
368
|
+
* @since 1.3.18
|
|
369
|
+
* @version 1.3.18
|
|
370
|
+
*
|
|
371
|
+
* @param {Number} max_lag
|
|
372
|
+
*/
|
|
373
|
+
Alchemy.setMethod(function setMaxEventLoopLag(max_lag) {
|
|
374
|
+
|
|
375
|
+
if (typeof max_lag != 'number' || !isFinite(max_lag)) {
|
|
376
|
+
max_lag = null;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (max_lag == null) {
|
|
380
|
+
max_lag = 70;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
this.settings.max_event_loop_lag = max_lag;
|
|
384
|
+
});
|
|
385
|
+
|
|
364
386
|
/**
|
|
365
387
|
* Called after the server has started
|
|
366
388
|
*
|
|
@@ -588,7 +610,7 @@ Alchemy.setMethod(function printLog(level, args, options) {
|
|
|
588
610
|
*
|
|
589
611
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
590
612
|
* @since 0.4.0
|
|
591
|
-
* @version 1.3.
|
|
613
|
+
* @version 1.3.18
|
|
592
614
|
*/
|
|
593
615
|
Alchemy.setMethod(function loadSettings() {
|
|
594
616
|
|
|
@@ -726,8 +748,10 @@ Alchemy.setMethod(function loadSettings() {
|
|
|
726
748
|
settings.url = this.argv.url;
|
|
727
749
|
}
|
|
728
750
|
|
|
729
|
-
|
|
730
|
-
|
|
751
|
+
this.setUrl(settings.url);
|
|
752
|
+
|
|
753
|
+
if (settings.cookie_domain) {
|
|
754
|
+
this.setCookieDomain(settings.cookie_domain);
|
|
731
755
|
}
|
|
732
756
|
|
|
733
757
|
if (this.argv.preload) {
|
|
@@ -780,10 +804,76 @@ Alchemy.setMethod(function loadSettings() {
|
|
|
780
804
|
this.doPreload();
|
|
781
805
|
}
|
|
782
806
|
|
|
807
|
+
this.setMaxEventLoopLag(settings.max_event_loop_lag);
|
|
808
|
+
|
|
783
809
|
// Set the debug value
|
|
784
810
|
global.DEBUG = settings.debug;
|
|
785
811
|
});
|
|
786
812
|
|
|
813
|
+
/**
|
|
814
|
+
* Set the main url
|
|
815
|
+
*
|
|
816
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
817
|
+
* @since 1.3.18
|
|
818
|
+
* @version 1.3.18
|
|
819
|
+
*
|
|
820
|
+
* @param {RURL|String} value
|
|
821
|
+
*/
|
|
822
|
+
Alchemy.setMethod(function setUrl(value) {
|
|
823
|
+
|
|
824
|
+
if (value) {
|
|
825
|
+
value = ''+value;
|
|
826
|
+
|
|
827
|
+
if (value.indexOf('{') > -1) {
|
|
828
|
+
value = value.assign(this.settings);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
this.settings.url = value;
|
|
833
|
+
|
|
834
|
+
if (this.settings.cookie_domain === true || this.settings.cookie_domain == null) {
|
|
835
|
+
this.setCookieDomain(value);
|
|
836
|
+
}
|
|
837
|
+
});
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Set the cookie domain
|
|
841
|
+
*
|
|
842
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
843
|
+
* @since 1.3.18
|
|
844
|
+
* @version 1.3.18
|
|
845
|
+
*
|
|
846
|
+
* @param {RURL|String} value
|
|
847
|
+
*/
|
|
848
|
+
Alchemy.setMethod(function setCookieDomain(value) {
|
|
849
|
+
|
|
850
|
+
if (value === false) {
|
|
851
|
+
this.settings.cookie_domain = false;
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
if (!value) {
|
|
856
|
+
value = this.settings.url;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
if (!value) {
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
value = ''+value;
|
|
864
|
+
|
|
865
|
+
if (value.indexOf('{') > -1) {
|
|
866
|
+
value = value.assign(this.settings);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
if (value.indexOf('/') > -1) {
|
|
870
|
+
let url = RURL.parse(value);
|
|
871
|
+
value = url.hostname;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
this.settings.cookie_domain = value;
|
|
875
|
+
});
|
|
876
|
+
|
|
787
877
|
/**
|
|
788
878
|
* Set status
|
|
789
879
|
*
|
|
@@ -1651,7 +1741,7 @@ Alchemy.setMethod(function addAppcacheEntry(entry) {
|
|
|
1651
1741
|
*
|
|
1652
1742
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
1653
1743
|
* @since 1.1.0
|
|
1654
|
-
* @version 1.3.
|
|
1744
|
+
* @version 1.3.18
|
|
1655
1745
|
*
|
|
1656
1746
|
* @param {IncomingMessage} req
|
|
1657
1747
|
* @param {OutgoingMessage} res Optional
|
|
@@ -1674,8 +1764,10 @@ Alchemy.setMethod(function parseRequestBody(req, res, callback) {
|
|
|
1674
1764
|
return callback(null, req.body);
|
|
1675
1765
|
}
|
|
1676
1766
|
|
|
1767
|
+
let content_type = req.headers['content-type'];
|
|
1768
|
+
|
|
1677
1769
|
// Multipart data is handled by "formidable"
|
|
1678
|
-
if (
|
|
1770
|
+
if (content_type && content_type.startsWith('multipart/form-data')) {
|
|
1679
1771
|
|
|
1680
1772
|
let form = new formidable.IncomingForm({
|
|
1681
1773
|
multiples : true,
|
|
@@ -1729,7 +1821,7 @@ Alchemy.setMethod(function parseRequestBody(req, res, callback) {
|
|
|
1729
1821
|
}
|
|
1730
1822
|
|
|
1731
1823
|
// Regular form-encoded data
|
|
1732
|
-
if (
|
|
1824
|
+
if (content_type && content_type.indexOf('form-urlencoded') > -1) {
|
|
1733
1825
|
|
|
1734
1826
|
urlFormBody(req, res, function parsedBody(err) {
|
|
1735
1827
|
|
|
@@ -1760,25 +1852,36 @@ Alchemy.setMethod(function parseRequestBody(req, res, callback) {
|
|
|
1760
1852
|
// Any other encoded data (like JSON)
|
|
1761
1853
|
anyBody(req, function parsedBody(err, body) {
|
|
1762
1854
|
|
|
1763
|
-
|
|
1764
|
-
|
|
1855
|
+
function handleResponse(err, body) {
|
|
1856
|
+
if (err && req.conduit && req.conduit.aborted) {
|
|
1857
|
+
return callback(null);
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
// You can't send files using a regular post
|
|
1861
|
+
req.files = {};
|
|
1862
|
+
|
|
1863
|
+
if (err) {
|
|
1864
|
+
log.error('Error parsing body data', {err: err});
|
|
1865
|
+
req.body = {};
|
|
1866
|
+
} else {
|
|
1867
|
+
req.body = body;
|
|
1868
|
+
|
|
1869
|
+
if (conduit) {
|
|
1870
|
+
conduit.setRequestBody(body);
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
callback(null, req.body);
|
|
1765
1875
|
}
|
|
1766
1876
|
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
log.error('Error parsing body data', {err: err});
|
|
1772
|
-
req.body = {};
|
|
1773
|
-
} else {
|
|
1774
|
-
req.body = body;
|
|
1775
|
-
|
|
1776
|
-
if (conduit) {
|
|
1777
|
-
conduit.setRequestBody(body);
|
|
1877
|
+
if (err?.type == 'invalid.content.type') {
|
|
1878
|
+
if (!content_type || content_type.startsWith('text/')) {
|
|
1879
|
+
textBody(req, handleResponse);
|
|
1880
|
+
return;
|
|
1778
1881
|
}
|
|
1779
1882
|
}
|
|
1780
1883
|
|
|
1781
|
-
|
|
1884
|
+
handleResponse(err, body);
|
|
1782
1885
|
});
|
|
1783
1886
|
});
|
|
1784
1887
|
|
|
@@ -2258,6 +2361,7 @@ log.todo = function todo(...args) {
|
|
|
2258
2361
|
|
|
2259
2362
|
const anyBody = alchemy.use('body/any'),
|
|
2260
2363
|
formBody = alchemy.use('body/form'),
|
|
2364
|
+
textBody = alchemy.use('body'),
|
|
2261
2365
|
formidable = alchemy.use('formidable'),
|
|
2262
2366
|
bodyParser = alchemy.use('body-parser'),
|
|
2263
2367
|
urlFormBody = bodyParser.urlencoded({extended: true});
|
package/lib/init/requirements.js
CHANGED
|
@@ -57,13 +57,6 @@ alchemy.hawkejs = Classes.Hawkejs.Hawkejs.getInstance();
|
|
|
57
57
|
*/
|
|
58
58
|
alchemy.toobusy = alchemy.use('toobusy-js', 'toobusy');
|
|
59
59
|
|
|
60
|
-
let max_event_loop_lag = alchemy.settings.max_event_loop_lag || alchemy.settings.toobusy;
|
|
61
|
-
|
|
62
|
-
// If the config is a number, use that as the lag threshold
|
|
63
|
-
if (typeof max_event_loop_lag === 'number') {
|
|
64
|
-
alchemy.toobusy.maxLag(max_event_loop_lag);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
60
|
/**
|
|
68
61
|
* Load Sputnik, the stage-based launcher
|
|
69
62
|
*/
|