@browserless.io/browserless 2.20.0-beta-4 → 2.20.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/CHANGELOG.md +157 -8
- package/build/config.d.ts +1 -0
- package/build/config.js +3 -2
- package/build/router.js +4 -1
- package/build/routes/chrome/http/pdf.post.body.json +8 -8
- package/build/routes/chrome/http/scrape.post.body.json +8 -8
- package/build/routes/chrome/http/screenshot.post.body.json +8 -8
- package/build/routes/chromium/http/content.post.body.json +8 -8
- package/build/routes/chromium/http/pdf.post.body.json +8 -8
- package/build/routes/chromium/http/scrape.post.body.json +8 -8
- package/build/routes/chromium/http/screenshot.post.body.json +8 -8
- package/build/routes/chromium/tests/content.spec.js +23 -0
- package/build/routes/chromium/tests/function.spec.js +1 -1
- package/build/routes/chromium/tests/pdf.spec.js +1 -1
- package/build/routes/management/http/static.get.js +3 -0
- package/build/sdk-utils.js +0 -4
- package/package.json +2 -2
- package/src/config.ts +3 -2
- package/src/router.ts +4 -3
- package/src/routes/chromium/tests/content.spec.ts +27 -0
- package/src/routes/chromium/tests/function.spec.ts +1 -1
- package/src/routes/chromium/tests/pdf.spec.ts +1 -1
- package/src/routes/management/http/static.get.ts +6 -0
- package/src/sdk-utils.ts +0 -6
- package/static/docs/swagger.json +2 -2
- package/static/docs/swagger.min.json +1 -1
package/build/config.d.ts
CHANGED
package/build/config.js
CHANGED
|
@@ -145,6 +145,7 @@ export class Config extends EventEmitter {
|
|
|
145
145
|
timeoutAlertURL = process.env.TIMEOUT_ALERT_URL ?? null;
|
|
146
146
|
errorAlertURL = process.env.ERROR_ALERT_URL ?? null;
|
|
147
147
|
pwVersions = {};
|
|
148
|
+
enableDebugger = !!parseEnvVars(true, 'ENABLE_DEBUGGER');
|
|
148
149
|
getRoutes() {
|
|
149
150
|
return this.routes;
|
|
150
151
|
}
|
|
@@ -221,8 +222,8 @@ export class Config extends EventEmitter {
|
|
|
221
222
|
getErrorAlertURL() {
|
|
222
223
|
return this.errorAlertURL;
|
|
223
224
|
}
|
|
224
|
-
hasDebugger() {
|
|
225
|
-
return exists(this.debuggerDir);
|
|
225
|
+
async hasDebugger() {
|
|
226
|
+
return this.enableDebugger && (await exists(this.debuggerDir));
|
|
226
227
|
}
|
|
227
228
|
/**
|
|
228
229
|
* If true, allows GET style calls on our browser-based APIs, using
|
package/build/router.js
CHANGED
|
@@ -143,7 +143,10 @@ export class Router extends EventEmitter {
|
|
|
143
143
|
}
|
|
144
144
|
async getRouteForHTTPRequest(req) {
|
|
145
145
|
const accepts = (req.headers['accept']?.toLowerCase() || '*/*').split(',');
|
|
146
|
-
const contentType = req.headers['content-type']
|
|
146
|
+
const contentType = req.headers['content-type']
|
|
147
|
+
?.toLowerCase()
|
|
148
|
+
?.split(';')
|
|
149
|
+
.shift();
|
|
147
150
|
return (this.httpRoutes.find((r) =>
|
|
148
151
|
// Once registered, paths are always an array here.
|
|
149
152
|
r.path.some((p) => micromatch.isMatch(req.parsed.pathname, p)) &&
|
|
@@ -583,14 +583,14 @@
|
|
|
583
583
|
"length": {
|
|
584
584
|
"type": "number"
|
|
585
585
|
},
|
|
586
|
-
"__@toStringTag@
|
|
586
|
+
"__@toStringTag@112299": {
|
|
587
587
|
"type": "string",
|
|
588
588
|
"const": "Uint8Array"
|
|
589
589
|
}
|
|
590
590
|
},
|
|
591
591
|
"required": [
|
|
592
592
|
"BYTES_PER_ELEMENT",
|
|
593
|
-
"__@toStringTag@
|
|
593
|
+
"__@toStringTag@112299",
|
|
594
594
|
"buffer",
|
|
595
595
|
"byteLength",
|
|
596
596
|
"byteOffset",
|
|
@@ -625,13 +625,13 @@
|
|
|
625
625
|
"byteLength": {
|
|
626
626
|
"type": "number"
|
|
627
627
|
},
|
|
628
|
-
"__@toStringTag@
|
|
628
|
+
"__@toStringTag@112299": {
|
|
629
629
|
"type": "string"
|
|
630
630
|
}
|
|
631
631
|
},
|
|
632
632
|
"additionalProperties": false,
|
|
633
633
|
"required": [
|
|
634
|
-
"__@toStringTag@
|
|
634
|
+
"__@toStringTag@112299",
|
|
635
635
|
"byteLength"
|
|
636
636
|
]
|
|
637
637
|
},
|
|
@@ -641,18 +641,18 @@
|
|
|
641
641
|
"byteLength": {
|
|
642
642
|
"type": "number"
|
|
643
643
|
},
|
|
644
|
-
"__@species@
|
|
644
|
+
"__@species@112337": {
|
|
645
645
|
"$ref": "#/definitions/SharedArrayBuffer"
|
|
646
646
|
},
|
|
647
|
-
"__@toStringTag@
|
|
647
|
+
"__@toStringTag@112299": {
|
|
648
648
|
"type": "string",
|
|
649
649
|
"const": "SharedArrayBuffer"
|
|
650
650
|
}
|
|
651
651
|
},
|
|
652
652
|
"additionalProperties": false,
|
|
653
653
|
"required": [
|
|
654
|
-
"__@species@
|
|
655
|
-
"__@toStringTag@
|
|
654
|
+
"__@species@112337",
|
|
655
|
+
"__@toStringTag@112299",
|
|
656
656
|
"byteLength"
|
|
657
657
|
]
|
|
658
658
|
},
|
|
@@ -485,14 +485,14 @@
|
|
|
485
485
|
"length": {
|
|
486
486
|
"type": "number"
|
|
487
487
|
},
|
|
488
|
-
"__@toStringTag@
|
|
488
|
+
"__@toStringTag@126514": {
|
|
489
489
|
"type": "string",
|
|
490
490
|
"const": "Uint8Array"
|
|
491
491
|
}
|
|
492
492
|
},
|
|
493
493
|
"required": [
|
|
494
494
|
"BYTES_PER_ELEMENT",
|
|
495
|
-
"__@toStringTag@
|
|
495
|
+
"__@toStringTag@126514",
|
|
496
496
|
"buffer",
|
|
497
497
|
"byteLength",
|
|
498
498
|
"byteOffset",
|
|
@@ -527,13 +527,13 @@
|
|
|
527
527
|
"byteLength": {
|
|
528
528
|
"type": "number"
|
|
529
529
|
},
|
|
530
|
-
"__@toStringTag@
|
|
530
|
+
"__@toStringTag@126514": {
|
|
531
531
|
"type": "string"
|
|
532
532
|
}
|
|
533
533
|
},
|
|
534
534
|
"additionalProperties": false,
|
|
535
535
|
"required": [
|
|
536
|
-
"__@toStringTag@
|
|
536
|
+
"__@toStringTag@126514",
|
|
537
537
|
"byteLength"
|
|
538
538
|
]
|
|
539
539
|
},
|
|
@@ -543,18 +543,18 @@
|
|
|
543
543
|
"byteLength": {
|
|
544
544
|
"type": "number"
|
|
545
545
|
},
|
|
546
|
-
"__@species@
|
|
546
|
+
"__@species@126552": {
|
|
547
547
|
"$ref": "#/definitions/SharedArrayBuffer"
|
|
548
548
|
},
|
|
549
|
-
"__@toStringTag@
|
|
549
|
+
"__@toStringTag@126514": {
|
|
550
550
|
"type": "string",
|
|
551
551
|
"const": "SharedArrayBuffer"
|
|
552
552
|
}
|
|
553
553
|
},
|
|
554
554
|
"additionalProperties": false,
|
|
555
555
|
"required": [
|
|
556
|
-
"__@species@
|
|
557
|
-
"__@toStringTag@
|
|
556
|
+
"__@species@126552",
|
|
557
|
+
"__@toStringTag@126514",
|
|
558
558
|
"byteLength"
|
|
559
559
|
]
|
|
560
560
|
},
|
|
@@ -528,14 +528,14 @@
|
|
|
528
528
|
"length": {
|
|
529
529
|
"type": "number"
|
|
530
530
|
},
|
|
531
|
-
"__@toStringTag@
|
|
531
|
+
"__@toStringTag@140806": {
|
|
532
532
|
"type": "string",
|
|
533
533
|
"const": "Uint8Array"
|
|
534
534
|
}
|
|
535
535
|
},
|
|
536
536
|
"required": [
|
|
537
537
|
"BYTES_PER_ELEMENT",
|
|
538
|
-
"__@toStringTag@
|
|
538
|
+
"__@toStringTag@140806",
|
|
539
539
|
"buffer",
|
|
540
540
|
"byteLength",
|
|
541
541
|
"byteOffset",
|
|
@@ -570,13 +570,13 @@
|
|
|
570
570
|
"byteLength": {
|
|
571
571
|
"type": "number"
|
|
572
572
|
},
|
|
573
|
-
"__@toStringTag@
|
|
573
|
+
"__@toStringTag@140806": {
|
|
574
574
|
"type": "string"
|
|
575
575
|
}
|
|
576
576
|
},
|
|
577
577
|
"additionalProperties": false,
|
|
578
578
|
"required": [
|
|
579
|
-
"__@toStringTag@
|
|
579
|
+
"__@toStringTag@140806",
|
|
580
580
|
"byteLength"
|
|
581
581
|
]
|
|
582
582
|
},
|
|
@@ -586,18 +586,18 @@
|
|
|
586
586
|
"byteLength": {
|
|
587
587
|
"type": "number"
|
|
588
588
|
},
|
|
589
|
-
"__@species@
|
|
589
|
+
"__@species@140844": {
|
|
590
590
|
"$ref": "#/definitions/SharedArrayBuffer"
|
|
591
591
|
},
|
|
592
|
-
"__@toStringTag@
|
|
592
|
+
"__@toStringTag@140806": {
|
|
593
593
|
"type": "string",
|
|
594
594
|
"const": "SharedArrayBuffer"
|
|
595
595
|
}
|
|
596
596
|
},
|
|
597
597
|
"additionalProperties": false,
|
|
598
598
|
"required": [
|
|
599
|
-
"__@species@
|
|
600
|
-
"__@toStringTag@
|
|
599
|
+
"__@species@140844",
|
|
600
|
+
"__@toStringTag@140806",
|
|
601
601
|
"byteLength"
|
|
602
602
|
]
|
|
603
603
|
},
|
|
@@ -438,14 +438,14 @@
|
|
|
438
438
|
"length": {
|
|
439
439
|
"type": "number"
|
|
440
440
|
},
|
|
441
|
-
"__@toStringTag@
|
|
441
|
+
"__@toStringTag@155008": {
|
|
442
442
|
"type": "string",
|
|
443
443
|
"const": "Uint8Array"
|
|
444
444
|
}
|
|
445
445
|
},
|
|
446
446
|
"required": [
|
|
447
447
|
"BYTES_PER_ELEMENT",
|
|
448
|
-
"__@toStringTag@
|
|
448
|
+
"__@toStringTag@155008",
|
|
449
449
|
"buffer",
|
|
450
450
|
"byteLength",
|
|
451
451
|
"byteOffset",
|
|
@@ -480,13 +480,13 @@
|
|
|
480
480
|
"byteLength": {
|
|
481
481
|
"type": "number"
|
|
482
482
|
},
|
|
483
|
-
"__@toStringTag@
|
|
483
|
+
"__@toStringTag@155008": {
|
|
484
484
|
"type": "string"
|
|
485
485
|
}
|
|
486
486
|
},
|
|
487
487
|
"additionalProperties": false,
|
|
488
488
|
"required": [
|
|
489
|
-
"__@toStringTag@
|
|
489
|
+
"__@toStringTag@155008",
|
|
490
490
|
"byteLength"
|
|
491
491
|
]
|
|
492
492
|
},
|
|
@@ -496,18 +496,18 @@
|
|
|
496
496
|
"byteLength": {
|
|
497
497
|
"type": "number"
|
|
498
498
|
},
|
|
499
|
-
"__@species@
|
|
499
|
+
"__@species@155046": {
|
|
500
500
|
"$ref": "#/definitions/SharedArrayBuffer"
|
|
501
501
|
},
|
|
502
|
-
"__@toStringTag@
|
|
502
|
+
"__@toStringTag@155008": {
|
|
503
503
|
"type": "string",
|
|
504
504
|
"const": "SharedArrayBuffer"
|
|
505
505
|
}
|
|
506
506
|
},
|
|
507
507
|
"additionalProperties": false,
|
|
508
508
|
"required": [
|
|
509
|
-
"__@species@
|
|
510
|
-
"__@toStringTag@
|
|
509
|
+
"__@species@155046",
|
|
510
|
+
"__@toStringTag@155008",
|
|
511
511
|
"byteLength"
|
|
512
512
|
]
|
|
513
513
|
},
|
|
@@ -583,14 +583,14 @@
|
|
|
583
583
|
"length": {
|
|
584
584
|
"type": "number"
|
|
585
585
|
},
|
|
586
|
-
"__@toStringTag@
|
|
586
|
+
"__@toStringTag@267177": {
|
|
587
587
|
"type": "string",
|
|
588
588
|
"const": "Uint8Array"
|
|
589
589
|
}
|
|
590
590
|
},
|
|
591
591
|
"required": [
|
|
592
592
|
"BYTES_PER_ELEMENT",
|
|
593
|
-
"__@toStringTag@
|
|
593
|
+
"__@toStringTag@267177",
|
|
594
594
|
"buffer",
|
|
595
595
|
"byteLength",
|
|
596
596
|
"byteOffset",
|
|
@@ -625,13 +625,13 @@
|
|
|
625
625
|
"byteLength": {
|
|
626
626
|
"type": "number"
|
|
627
627
|
},
|
|
628
|
-
"__@toStringTag@
|
|
628
|
+
"__@toStringTag@267177": {
|
|
629
629
|
"type": "string"
|
|
630
630
|
}
|
|
631
631
|
},
|
|
632
632
|
"additionalProperties": false,
|
|
633
633
|
"required": [
|
|
634
|
-
"__@toStringTag@
|
|
634
|
+
"__@toStringTag@267177",
|
|
635
635
|
"byteLength"
|
|
636
636
|
]
|
|
637
637
|
},
|
|
@@ -641,18 +641,18 @@
|
|
|
641
641
|
"byteLength": {
|
|
642
642
|
"type": "number"
|
|
643
643
|
},
|
|
644
|
-
"__@species@
|
|
644
|
+
"__@species@267215": {
|
|
645
645
|
"$ref": "#/definitions/SharedArrayBuffer"
|
|
646
646
|
},
|
|
647
|
-
"__@toStringTag@
|
|
647
|
+
"__@toStringTag@267177": {
|
|
648
648
|
"type": "string",
|
|
649
649
|
"const": "SharedArrayBuffer"
|
|
650
650
|
}
|
|
651
651
|
},
|
|
652
652
|
"additionalProperties": false,
|
|
653
653
|
"required": [
|
|
654
|
-
"__@species@
|
|
655
|
-
"__@toStringTag@
|
|
654
|
+
"__@species@267215",
|
|
655
|
+
"__@toStringTag@267177",
|
|
656
656
|
"byteLength"
|
|
657
657
|
]
|
|
658
658
|
},
|
|
@@ -485,14 +485,14 @@
|
|
|
485
485
|
"length": {
|
|
486
486
|
"type": "number"
|
|
487
487
|
},
|
|
488
|
-
"__@toStringTag@
|
|
488
|
+
"__@toStringTag@281389": {
|
|
489
489
|
"type": "string",
|
|
490
490
|
"const": "Uint8Array"
|
|
491
491
|
}
|
|
492
492
|
},
|
|
493
493
|
"required": [
|
|
494
494
|
"BYTES_PER_ELEMENT",
|
|
495
|
-
"__@toStringTag@
|
|
495
|
+
"__@toStringTag@281389",
|
|
496
496
|
"buffer",
|
|
497
497
|
"byteLength",
|
|
498
498
|
"byteOffset",
|
|
@@ -527,13 +527,13 @@
|
|
|
527
527
|
"byteLength": {
|
|
528
528
|
"type": "number"
|
|
529
529
|
},
|
|
530
|
-
"__@toStringTag@
|
|
530
|
+
"__@toStringTag@281389": {
|
|
531
531
|
"type": "string"
|
|
532
532
|
}
|
|
533
533
|
},
|
|
534
534
|
"additionalProperties": false,
|
|
535
535
|
"required": [
|
|
536
|
-
"__@toStringTag@
|
|
536
|
+
"__@toStringTag@281389",
|
|
537
537
|
"byteLength"
|
|
538
538
|
]
|
|
539
539
|
},
|
|
@@ -543,18 +543,18 @@
|
|
|
543
543
|
"byteLength": {
|
|
544
544
|
"type": "number"
|
|
545
545
|
},
|
|
546
|
-
"__@species@
|
|
546
|
+
"__@species@281427": {
|
|
547
547
|
"$ref": "#/definitions/SharedArrayBuffer"
|
|
548
548
|
},
|
|
549
|
-
"__@toStringTag@
|
|
549
|
+
"__@toStringTag@281389": {
|
|
550
550
|
"type": "string",
|
|
551
551
|
"const": "SharedArrayBuffer"
|
|
552
552
|
}
|
|
553
553
|
},
|
|
554
554
|
"additionalProperties": false,
|
|
555
555
|
"required": [
|
|
556
|
-
"__@species@
|
|
557
|
-
"__@toStringTag@
|
|
556
|
+
"__@species@281427",
|
|
557
|
+
"__@toStringTag@281389",
|
|
558
558
|
"byteLength"
|
|
559
559
|
]
|
|
560
560
|
},
|
|
@@ -528,14 +528,14 @@
|
|
|
528
528
|
"length": {
|
|
529
529
|
"type": "number"
|
|
530
530
|
},
|
|
531
|
-
"__@toStringTag@
|
|
531
|
+
"__@toStringTag@309690": {
|
|
532
532
|
"type": "string",
|
|
533
533
|
"const": "Uint8Array"
|
|
534
534
|
}
|
|
535
535
|
},
|
|
536
536
|
"required": [
|
|
537
537
|
"BYTES_PER_ELEMENT",
|
|
538
|
-
"__@toStringTag@
|
|
538
|
+
"__@toStringTag@309690",
|
|
539
539
|
"buffer",
|
|
540
540
|
"byteLength",
|
|
541
541
|
"byteOffset",
|
|
@@ -570,13 +570,13 @@
|
|
|
570
570
|
"byteLength": {
|
|
571
571
|
"type": "number"
|
|
572
572
|
},
|
|
573
|
-
"__@toStringTag@
|
|
573
|
+
"__@toStringTag@309690": {
|
|
574
574
|
"type": "string"
|
|
575
575
|
}
|
|
576
576
|
},
|
|
577
577
|
"additionalProperties": false,
|
|
578
578
|
"required": [
|
|
579
|
-
"__@toStringTag@
|
|
579
|
+
"__@toStringTag@309690",
|
|
580
580
|
"byteLength"
|
|
581
581
|
]
|
|
582
582
|
},
|
|
@@ -586,18 +586,18 @@
|
|
|
586
586
|
"byteLength": {
|
|
587
587
|
"type": "number"
|
|
588
588
|
},
|
|
589
|
-
"__@species@
|
|
589
|
+
"__@species@309728": {
|
|
590
590
|
"$ref": "#/definitions/SharedArrayBuffer"
|
|
591
591
|
},
|
|
592
|
-
"__@toStringTag@
|
|
592
|
+
"__@toStringTag@309690": {
|
|
593
593
|
"type": "string",
|
|
594
594
|
"const": "SharedArrayBuffer"
|
|
595
595
|
}
|
|
596
596
|
},
|
|
597
597
|
"additionalProperties": false,
|
|
598
598
|
"required": [
|
|
599
|
-
"__@species@
|
|
600
|
-
"__@toStringTag@
|
|
599
|
+
"__@species@309728",
|
|
600
|
+
"__@toStringTag@309690",
|
|
601
601
|
"byteLength"
|
|
602
602
|
]
|
|
603
603
|
},
|
|
@@ -32,6 +32,29 @@ describe('/chromium/content API', function () {
|
|
|
32
32
|
expect(res.status).to.equal(200);
|
|
33
33
|
});
|
|
34
34
|
});
|
|
35
|
+
it('allows requests with content-type charsets', async () => {
|
|
36
|
+
const config = new Config();
|
|
37
|
+
config.setToken('browserless');
|
|
38
|
+
const metrics = new Metrics();
|
|
39
|
+
await start({ config, metrics });
|
|
40
|
+
const body = {
|
|
41
|
+
url: 'https://example.com',
|
|
42
|
+
};
|
|
43
|
+
await fetch('http://localhost:3000/chromium/content?token=browserless', {
|
|
44
|
+
body: JSON.stringify(body),
|
|
45
|
+
headers: {
|
|
46
|
+
'content-type': 'application/json; charset=utf-8',
|
|
47
|
+
},
|
|
48
|
+
method: 'POST',
|
|
49
|
+
}).then((res) => {
|
|
50
|
+
expect(res.headers.get('x-response-code')).to.not.be.undefined;
|
|
51
|
+
expect(res.headers.get('x-response-url')).to.not.be.undefined;
|
|
52
|
+
expect(res.headers.get('x-response-ip')).to.not.be.undefined;
|
|
53
|
+
expect(res.headers.get('x-response-por')).to.not.be.undefined;
|
|
54
|
+
expect(res.headers.get('content-type')).to.equal('text/html; charset=UTF-8');
|
|
55
|
+
expect(res.status).to.equal(200);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
35
58
|
it('cancels request when they are closed early', async () => {
|
|
36
59
|
const config = new Config();
|
|
37
60
|
const metrics = new Metrics();
|
|
@@ -26,7 +26,7 @@ describe('/chromium/function API', function () {
|
|
|
26
26
|
await fetch('http://localhost:3000/chromium/function?token=browserless', {
|
|
27
27
|
body: JSON.stringify(body),
|
|
28
28
|
headers: {
|
|
29
|
-
'content-type': 'application/json',
|
|
29
|
+
'content-type': 'application/json; charset=utf-8',
|
|
30
30
|
},
|
|
31
31
|
method: 'POST',
|
|
32
32
|
}).then(async (res) => {
|
|
@@ -20,7 +20,7 @@ describe('/chromium/pdf API', function () {
|
|
|
20
20
|
await fetch('http://localhost:3000/chromium/pdf?token=browserless', {
|
|
21
21
|
body: JSON.stringify(body),
|
|
22
22
|
headers: {
|
|
23
|
-
'content-type': 'application/json',
|
|
23
|
+
'content-type': 'application/json; charset=utf-8',
|
|
24
24
|
},
|
|
25
25
|
method: 'POST',
|
|
26
26
|
}).then((res) => {
|
|
@@ -44,6 +44,9 @@ export default class StaticGetRoute extends HTTPRoute {
|
|
|
44
44
|
const sdkPath = path.join(sdkDir, pathname);
|
|
45
45
|
locations.push(...[sdkPath, path.join(sdkPath, 'index.html')]);
|
|
46
46
|
}
|
|
47
|
+
if (pathname.includes('/debugger/') && !(await config.hasDebugger())) {
|
|
48
|
+
throw new NotFound(`No route or file found for resource ${req.method}: ${pathname}`);
|
|
49
|
+
}
|
|
47
50
|
const foundFilePaths = (await Promise.all(locations.map((l) => fileExists(l).then((e) => (e ? l : undefined))))).filter((_) => !!_);
|
|
48
51
|
if (!foundFilePaths.length) {
|
|
49
52
|
throw new NotFound(`No route or file found for resource ${req.method}: ${pathname}`);
|
package/build/sdk-utils.js
CHANGED
|
@@ -36,11 +36,7 @@ export const getSourceFiles = async (cwd) => {
|
|
|
36
36
|
const buildDir = path.join(cwd, 'build');
|
|
37
37
|
const files = await fs.readdir(buildDir, { recursive: true });
|
|
38
38
|
const [httpRoutes, webSocketRoutes] = files.reduce(([httpRoutes, webSocketRoutes], file) => {
|
|
39
|
-
const isInRootDir = !file.includes(path.sep);
|
|
40
39
|
const parsed = path.parse(file);
|
|
41
|
-
if (isInRootDir) {
|
|
42
|
-
return [httpRoutes, webSocketRoutes];
|
|
43
|
-
}
|
|
44
40
|
if (parsed.name.endsWith('http')) {
|
|
45
41
|
httpRoutes.push(path.join(buildDir, file));
|
|
46
42
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@browserless.io/browserless",
|
|
3
|
-
"version": "2.20.0
|
|
3
|
+
"version": "2.20.0",
|
|
4
4
|
"license": "SSPL",
|
|
5
5
|
"description": "The browserless platform",
|
|
6
6
|
"author": "browserless.io",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"mocha": "^10.7.3",
|
|
94
94
|
"move-file": "^3.1.0",
|
|
95
95
|
"prettier": "^3.3.3",
|
|
96
|
-
"sinon": "^18.0.
|
|
96
|
+
"sinon": "^18.0.1",
|
|
97
97
|
"ts-node": "^10.9.2",
|
|
98
98
|
"typescript": "^5.6.2",
|
|
99
99
|
"typescript-json-schema": "^0.65.1"
|
package/src/config.ts
CHANGED
|
@@ -175,6 +175,7 @@ export class Config extends EventEmitter {
|
|
|
175
175
|
protected timeoutAlertURL = process.env.TIMEOUT_ALERT_URL ?? null;
|
|
176
176
|
protected errorAlertURL = process.env.ERROR_ALERT_URL ?? null;
|
|
177
177
|
protected pwVersions: { [key: string]: string } = {};
|
|
178
|
+
protected enableDebugger = !!parseEnvVars(true, 'ENABLE_DEBUGGER');
|
|
178
179
|
|
|
179
180
|
public getRoutes(): string {
|
|
180
181
|
return this.routes;
|
|
@@ -261,8 +262,8 @@ export class Config extends EventEmitter {
|
|
|
261
262
|
return this.errorAlertURL;
|
|
262
263
|
}
|
|
263
264
|
|
|
264
|
-
public hasDebugger(): Promise<boolean> {
|
|
265
|
-
return exists(this.debuggerDir);
|
|
265
|
+
public async hasDebugger(): Promise<boolean> {
|
|
266
|
+
return this.enableDebugger && (await exists(this.debuggerDir));
|
|
266
267
|
}
|
|
267
268
|
|
|
268
269
|
/**
|
package/src/router.ts
CHANGED
|
@@ -220,9 +220,10 @@ export class Router extends EventEmitter {
|
|
|
220
220
|
|
|
221
221
|
public async getRouteForHTTPRequest(req: Request) {
|
|
222
222
|
const accepts = (req.headers['accept']?.toLowerCase() || '*/*').split(',');
|
|
223
|
-
const contentType = req.headers['content-type']
|
|
224
|
-
|
|
225
|
-
|
|
223
|
+
const contentType = req.headers['content-type']
|
|
224
|
+
?.toLowerCase()
|
|
225
|
+
?.split(';')
|
|
226
|
+
.shift() as contentTypes | undefined;
|
|
226
227
|
|
|
227
228
|
return (
|
|
228
229
|
this.httpRoutes.find(
|
|
@@ -48,6 +48,33 @@ describe('/chromium/content API', function () {
|
|
|
48
48
|
});
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
+
it('allows requests with content-type charsets', async () => {
|
|
52
|
+
const config = new Config();
|
|
53
|
+
config.setToken('browserless');
|
|
54
|
+
const metrics = new Metrics();
|
|
55
|
+
await start({ config, metrics });
|
|
56
|
+
const body = {
|
|
57
|
+
url: 'https://example.com',
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
await fetch('http://localhost:3000/chromium/content?token=browserless', {
|
|
61
|
+
body: JSON.stringify(body),
|
|
62
|
+
headers: {
|
|
63
|
+
'content-type': 'application/json; charset=utf-8',
|
|
64
|
+
},
|
|
65
|
+
method: 'POST',
|
|
66
|
+
}).then((res) => {
|
|
67
|
+
expect(res.headers.get('x-response-code')).to.not.be.undefined;
|
|
68
|
+
expect(res.headers.get('x-response-url')).to.not.be.undefined;
|
|
69
|
+
expect(res.headers.get('x-response-ip')).to.not.be.undefined;
|
|
70
|
+
expect(res.headers.get('x-response-por')).to.not.be.undefined;
|
|
71
|
+
expect(res.headers.get('content-type')).to.equal(
|
|
72
|
+
'text/html; charset=UTF-8',
|
|
73
|
+
);
|
|
74
|
+
expect(res.status).to.equal(200);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
51
78
|
it('cancels request when they are closed early', async () => {
|
|
52
79
|
const config = new Config();
|
|
53
80
|
const metrics = new Metrics();
|
|
@@ -34,7 +34,7 @@ describe('/chromium/function API', function () {
|
|
|
34
34
|
await fetch('http://localhost:3000/chromium/function?token=browserless', {
|
|
35
35
|
body: JSON.stringify(body),
|
|
36
36
|
headers: {
|
|
37
|
-
'content-type': 'application/json',
|
|
37
|
+
'content-type': 'application/json; charset=utf-8',
|
|
38
38
|
},
|
|
39
39
|
method: 'POST',
|
|
40
40
|
}).then(async (res) => {
|
|
@@ -28,7 +28,7 @@ describe('/chromium/pdf API', function () {
|
|
|
28
28
|
await fetch('http://localhost:3000/chromium/pdf?token=browserless', {
|
|
29
29
|
body: JSON.stringify(body),
|
|
30
30
|
headers: {
|
|
31
|
-
'content-type': 'application/json',
|
|
31
|
+
'content-type': 'application/json; charset=utf-8',
|
|
32
32
|
},
|
|
33
33
|
method: 'POST',
|
|
34
34
|
}).then((res) => {
|
|
@@ -83,6 +83,12 @@ export default class StaticGetRoute extends HTTPRoute {
|
|
|
83
83
|
locations.push(...[sdkPath, path.join(sdkPath, 'index.html')]);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
if (pathname.includes('/debugger/') && !(await config.hasDebugger())) {
|
|
87
|
+
throw new NotFound(
|
|
88
|
+
`No route or file found for resource ${req.method}: ${pathname}`,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
86
92
|
const foundFilePaths = (
|
|
87
93
|
await Promise.all(
|
|
88
94
|
locations.map((l) => fileExists(l).then((e) => (e ? l : undefined))),
|
package/src/sdk-utils.ts
CHANGED
|
@@ -59,13 +59,7 @@ export const getSourceFiles = async (cwd: string) => {
|
|
|
59
59
|
const files = await fs.readdir(buildDir, { recursive: true });
|
|
60
60
|
const [httpRoutes, webSocketRoutes] = files.reduce(
|
|
61
61
|
([httpRoutes, webSocketRoutes], file) => {
|
|
62
|
-
const isInRootDir = !file.includes(path.sep);
|
|
63
62
|
const parsed = path.parse(file);
|
|
64
|
-
|
|
65
|
-
if (isInRootDir) {
|
|
66
|
-
return [httpRoutes, webSocketRoutes];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
63
|
if (parsed.name.endsWith('http')) {
|
|
70
64
|
httpRoutes.push(path.join(buildDir, file));
|
|
71
65
|
}
|