@browserless.io/browserless 2.25.0-beta-2 → 2.25.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.
Files changed (224) hide show
  1. package/CHANGELOG.md +39 -3
  2. package/README.md +4 -5
  3. package/build/browserless.js +3 -1
  4. package/build/browsers/browsers.cdp.d.ts +3 -0
  5. package/build/browsers/browsers.cdp.js +4 -1
  6. package/build/browsers/browsers.playwright.d.ts +4 -0
  7. package/build/browsers/browsers.playwright.js +11 -2
  8. package/build/browsers/index.js +4 -3
  9. package/build/http.d.ts +9 -0
  10. package/build/http.js +9 -0
  11. package/build/routes/chrome/http/content.post.body.json +8 -8
  12. package/build/routes/chrome/http/pdf.post.body.json +8 -8
  13. package/build/routes/chrome/http/scrape.post.body.json +8 -8
  14. package/build/routes/chrome/http/screenshot.post.body.json +8 -8
  15. package/build/routes/chrome/tests/kill-sessions.spec.js +1 -1
  16. package/build/routes/chromium/http/content.post.body.json +8 -8
  17. package/build/routes/chromium/http/pdf.post.body.json +8 -8
  18. package/build/routes/chromium/http/scrape.post.body.json +8 -8
  19. package/build/routes/chromium/http/screenshot.post.body.json +8 -8
  20. package/build/routes/chromium/tests/kill-sessions.spec.js +1 -1
  21. package/build/routes/edge/http/content.post.body.json +579 -0
  22. package/build/routes/edge/http/content.post.d.ts +8 -0
  23. package/build/routes/edge/http/content.post.js +7 -0
  24. package/build/routes/edge/http/content.post.query.json +183 -0
  25. package/build/routes/edge/http/content.post.response.json +5 -0
  26. package/build/routes/edge/http/download.post.body.json +32 -0
  27. package/build/routes/edge/http/download.post.d.ts +8 -0
  28. package/build/routes/edge/http/download.post.js +7 -0
  29. package/build/routes/edge/http/download.post.query.json +120 -0
  30. package/build/routes/edge/http/download.post.response.json +4 -0
  31. package/build/routes/edge/http/function.post.body.json +32 -0
  32. package/build/routes/edge/http/function.post.d.ts +8 -0
  33. package/build/routes/edge/http/function.post.js +7 -0
  34. package/build/routes/edge/http/function.post.query.json +120 -0
  35. package/build/routes/edge/http/function.post.response.json +4 -0
  36. package/build/routes/edge/http/json-list.get.d.ts +5 -0
  37. package/build/routes/edge/http/json-list.get.js +5 -0
  38. package/build/routes/edge/http/json-list.get.response.json +52 -0
  39. package/build/routes/edge/http/json-new.put.d.ts +5 -0
  40. package/build/routes/edge/http/json-new.put.js +5 -0
  41. package/build/routes/edge/http/json-new.put.response.json +44 -0
  42. package/build/routes/edge/http/json-protocol.get.d.ts +5 -0
  43. package/build/routes/edge/http/json-protocol.get.js +5 -0
  44. package/build/routes/edge/http/json-protocol.get.response.json +6 -0
  45. package/build/routes/edge/http/json-version.get.d.ts +5 -0
  46. package/build/routes/edge/http/json-version.get.js +5 -0
  47. package/build/routes/edge/http/json-version.get.response.json +44 -0
  48. package/build/routes/edge/http/pdf.post.body.json +724 -0
  49. package/build/routes/edge/http/pdf.post.d.ts +8 -0
  50. package/build/routes/edge/http/pdf.post.js +7 -0
  51. package/build/routes/edge/http/pdf.post.query.json +120 -0
  52. package/build/routes/edge/http/pdf.post.response.json +5 -0
  53. package/build/routes/edge/http/performance.post.body.json +26 -0
  54. package/build/routes/edge/http/performance.post.d.ts +8 -0
  55. package/build/routes/edge/http/performance.post.js +7 -0
  56. package/build/routes/edge/http/performance.post.query.json +120 -0
  57. package/build/routes/edge/http/performance.post.response.json +7 -0
  58. package/build/routes/edge/http/scrape.post.body.json +626 -0
  59. package/build/routes/edge/http/scrape.post.d.ts +8 -0
  60. package/build/routes/edge/http/scrape.post.js +7 -0
  61. package/build/routes/edge/http/scrape.post.query.json +183 -0
  62. package/build/routes/edge/http/scrape.post.response.json +334 -0
  63. package/build/routes/edge/http/screenshot.post.body.json +669 -0
  64. package/build/routes/edge/http/screenshot.post.d.ts +8 -0
  65. package/build/routes/edge/http/screenshot.post.js +7 -0
  66. package/build/routes/edge/http/screenshot.post.query.json +120 -0
  67. package/build/routes/edge/http/screenshot.post.response.json +5 -0
  68. package/build/routes/edge/tests/content.spec.d.ts +1 -0
  69. package/build/routes/edge/tests/content.spec.js +312 -0
  70. package/build/routes/edge/tests/download.spec.d.ts +1 -0
  71. package/build/routes/edge/tests/download.spec.js +67 -0
  72. package/build/routes/edge/tests/function.spec.d.ts +1 -0
  73. package/build/routes/edge/tests/function.spec.js +277 -0
  74. package/build/routes/edge/tests/json-version.spec.d.ts +1 -0
  75. package/build/routes/edge/tests/json-version.spec.js +37 -0
  76. package/build/routes/edge/tests/kill-sessions.spec.d.ts +1 -0
  77. package/build/routes/edge/tests/kill-sessions.spec.js +80 -0
  78. package/build/routes/edge/tests/page-websocket.spec.d.ts +1 -0
  79. package/build/routes/edge/tests/page-websocket.spec.js +97 -0
  80. package/build/routes/edge/tests/pdf.spec.d.ts +1 -0
  81. package/build/routes/edge/tests/pdf.spec.js +345 -0
  82. package/build/routes/edge/tests/performance.spec.d.ts +1 -0
  83. package/build/routes/edge/tests/performance.spec.js +124 -0
  84. package/build/routes/edge/tests/scrape.spec.d.ts +1 -0
  85. package/build/routes/edge/tests/scrape.spec.js +354 -0
  86. package/build/routes/edge/tests/screenshot.spec.d.ts +1 -0
  87. package/build/routes/edge/tests/screenshot.spec.js +339 -0
  88. package/build/routes/edge/tests/websocket.spec.d.ts +1 -0
  89. package/build/routes/edge/tests/websocket.spec.js +384 -0
  90. package/build/routes/edge/ws/browser.d.ts +7 -0
  91. package/build/routes/edge/ws/browser.js +6 -0
  92. package/build/routes/edge/ws/browser.query.json +120 -0
  93. package/build/routes/edge/ws/cdp.d.ts +8 -0
  94. package/build/routes/edge/ws/cdp.js +7 -0
  95. package/build/routes/edge/ws/cdp.query.json +120 -0
  96. package/build/routes/edge/ws/page.d.ts +8 -0
  97. package/build/routes/edge/ws/page.js +7 -0
  98. package/build/routes/edge/ws/page.query.json +120 -0
  99. package/build/routes/edge/ws/playwright.d.ts +8 -0
  100. package/build/routes/edge/ws/playwright.js +7 -0
  101. package/build/routes/edge/ws/playwright.query.json +100 -0
  102. package/build/routes/firefox/tests/kill-sessions.spec.js +1 -1
  103. package/build/routes/management/http/meta.get.js +3 -1
  104. package/build/routes/webkit/tests/kill-sessions.spec.js +1 -1
  105. package/build/sdk-utils.js +1 -1
  106. package/build/shared/scrape.http.js +2 -2
  107. package/build/types.d.ts +32 -0
  108. package/build/types.js +18 -0
  109. package/build/utils.d.ts +1 -0
  110. package/build/utils.js +16 -2
  111. package/docker/chrome/Dockerfile +14 -14
  112. package/docker/chromium/Dockerfile +14 -14
  113. package/docker/edge/.dockerignore +16 -0
  114. package/docker/edge/Dockerfile +43 -0
  115. package/docker/firefox/Dockerfile +14 -14
  116. package/docker/multi/Dockerfile +18 -18
  117. package/docker/sdk/Dockerfile +10 -0
  118. package/extensions/ublock/_locales/ar/messages.json +3 -3
  119. package/extensions/ublock/_locales/bg/messages.json +1 -1
  120. package/extensions/ublock/_locales/br_FR/messages.json +2 -2
  121. package/extensions/ublock/_locales/cy/messages.json +11 -11
  122. package/extensions/ublock/_locales/el/messages.json +2 -2
  123. package/extensions/ublock/_locales/hu/messages.json +1 -1
  124. package/extensions/ublock/_locales/id/messages.json +1 -1
  125. package/extensions/ublock/_locales/lv/messages.json +4 -4
  126. package/extensions/ublock/_locales/mk/messages.json +130 -130
  127. package/extensions/ublock/_locales/oc/messages.json +1 -1
  128. package/extensions/ublock/_locales/pt_BR/messages.json +1 -1
  129. package/extensions/ublock/_locales/pt_PT/messages.json +2 -2
  130. package/extensions/ublock/_locales/si/messages.json +100 -100
  131. package/extensions/ublock/_locales/sr/messages.json +4 -4
  132. package/extensions/ublock/_locales/vi/messages.json +19 -19
  133. package/extensions/ublock/_locales/zh_TW/messages.json +28 -28
  134. package/extensions/ublock/assets/assets.json +33 -29
  135. package/extensions/ublock/assets/thirdparties/easylist/easylist.txt +2984 -3287
  136. package/extensions/ublock/assets/thirdparties/easylist/easyprivacy.txt +150 -171
  137. package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/serverlist +37 -27
  138. package/extensions/ublock/assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat +802 -888
  139. package/extensions/ublock/assets/thirdparties/urlhaus-filter/urlhaus-filter-online.txt +2355 -2071
  140. package/extensions/ublock/assets/ublock/badlists.txt +9 -1
  141. package/extensions/ublock/assets/ublock/badware.min.txt +354 -243
  142. package/extensions/ublock/assets/ublock/filters.min.txt +5837 -5737
  143. package/extensions/ublock/assets/ublock/privacy.min.txt +151 -38
  144. package/extensions/ublock/assets/ublock/quick-fixes.min.txt +83 -127
  145. package/extensions/ublock/assets/ublock/unbreak.min.txt +66 -50
  146. package/extensions/ublock/css/codemirror.css +4 -0
  147. package/extensions/ublock/document-blocked.html +3 -1
  148. package/extensions/ublock/js/arglist-parser.js +116 -0
  149. package/extensions/ublock/js/background.js +1 -1
  150. package/extensions/ublock/js/logger-ui.js +1 -1
  151. package/extensions/ublock/js/messaging.js +9 -2
  152. package/extensions/ublock/js/pagestore.js +3 -1
  153. package/extensions/ublock/js/redirect-engine.js +3 -1
  154. package/extensions/ublock/{assets/resources/set-attr.js → js/resources/attribute.js} +115 -11
  155. package/extensions/ublock/js/resources/base.js +38 -0
  156. package/extensions/ublock/js/resources/cookie.js +419 -0
  157. package/extensions/ublock/js/resources/href-sanitizer.js +188 -0
  158. package/extensions/ublock/js/resources/localstorage.js +235 -0
  159. package/extensions/ublock/js/resources/parse-replace.js +54 -0
  160. package/extensions/ublock/js/resources/prevent-settimeout.js +236 -0
  161. package/extensions/ublock/js/resources/proxy-apply.js +109 -0
  162. package/extensions/ublock/js/resources/replace-argument.js +120 -0
  163. package/extensions/ublock/{assets → js}/resources/run-at.js +20 -4
  164. package/extensions/ublock/{assets → js}/resources/safe-self.js +5 -4
  165. package/extensions/ublock/{assets → js}/resources/scriptlets.js +90 -1589
  166. package/extensions/ublock/js/resources/set-constant.js +287 -0
  167. package/extensions/ublock/js/resources/shared.js +44 -0
  168. package/extensions/ublock/js/resources/spoof-css.js +163 -0
  169. package/extensions/ublock/js/s14e-serializer.js +2 -1
  170. package/extensions/ublock/js/scriptlet-filtering-core.js +1 -1
  171. package/extensions/ublock/js/scriptlet-filtering.js +1 -31
  172. package/extensions/ublock/js/static-dnr-filtering.js +143 -129
  173. package/extensions/ublock/js/static-filtering-parser.js +27 -117
  174. package/extensions/ublock/js/static-net-filtering.js +53 -141
  175. package/extensions/ublock/js/traffic.js +1 -1
  176. package/extensions/ublock/js/urlskip.js +166 -0
  177. package/extensions/ublock/js/vapi-background-ext.js +38 -14
  178. package/extensions/ublock/manifest.json +1 -1
  179. package/package.json +22 -22
  180. package/src/browserless.ts +4 -0
  181. package/src/browsers/browsers.cdp.ts +5 -0
  182. package/src/browsers/browsers.playwright.ts +14 -1
  183. package/src/browsers/index.ts +5 -2
  184. package/src/http.ts +9 -0
  185. package/src/routes/chrome/tests/kill-sessions.spec.ts +1 -1
  186. package/src/routes/chromium/tests/kill-sessions.spec.ts +1 -1
  187. package/src/routes/edge/http/content.post.ts +20 -0
  188. package/src/routes/edge/http/download.post.ts +20 -0
  189. package/src/routes/edge/http/function.post.ts +20 -0
  190. package/src/routes/edge/http/json-list.get.ts +7 -0
  191. package/src/routes/edge/http/json-new.put.ts +7 -0
  192. package/src/routes/edge/http/json-protocol.get.ts +7 -0
  193. package/src/routes/edge/http/json-version.get.ts +7 -0
  194. package/src/routes/edge/http/pdf.post.ts +20 -0
  195. package/src/routes/edge/http/performance.post.ts +20 -0
  196. package/src/routes/edge/http/scrape.post.ts +20 -0
  197. package/src/routes/edge/http/screenshot.post.ts +20 -0
  198. package/src/routes/edge/tests/content.spec.ts +376 -0
  199. package/src/routes/edge/tests/download.spec.ts +77 -0
  200. package/src/routes/edge/tests/function.spec.ts +317 -0
  201. package/src/routes/edge/tests/json-version.spec.ts +52 -0
  202. package/src/routes/edge/tests/kill-sessions.spec.ts +99 -0
  203. package/src/routes/edge/tests/page-websocket.spec.ts +129 -0
  204. package/src/routes/edge/tests/pdf.spec.ts +389 -0
  205. package/src/routes/edge/tests/performance.spec.ts +155 -0
  206. package/src/routes/edge/tests/scrape.spec.ts +417 -0
  207. package/src/routes/edge/tests/screenshot.spec.ts +387 -0
  208. package/src/routes/edge/tests/websocket.spec.ts +510 -0
  209. package/src/routes/edge/ws/browser.ts +10 -0
  210. package/src/routes/edge/ws/cdp.ts +17 -0
  211. package/src/routes/edge/ws/page.ts +10 -0
  212. package/src/routes/edge/ws/playwright.ts +17 -0
  213. package/src/routes/firefox/tests/kill-sessions.spec.ts +1 -1
  214. package/src/routes/management/http/meta.get.ts +6 -1
  215. package/src/routes/management/http/static.get.ts +1 -1
  216. package/src/routes/webkit/tests/kill-sessions.spec.ts +1 -1
  217. package/src/sdk-utils.ts +1 -1
  218. package/src/shared/scrape.http.ts +2 -2
  219. package/src/types.ts +19 -0
  220. package/src/utils.ts +38 -16
  221. package/static/docs/swagger.json +2097 -10
  222. package/static/docs/swagger.min.json +2096 -9
  223. package/static/function/client.js +141 -253
  224. package/static/function/index.html +141 -253
@@ -28,6 +28,7 @@ import BidiTrieContainer from './biditrie.js';
28
28
  import { CompiledListReader } from './static-filtering-io.js';
29
29
  import { FilteringContext } from './filtering-context.js';
30
30
  import HNTrieContainer from './hntrie.js';
31
+ import { urlSkip } from './urlskip.js';
31
32
 
32
33
  /******************************************************************************/
33
34
 
@@ -418,7 +419,7 @@ class LogData {
418
419
  }
419
420
 
420
421
  static requote(s) {
421
- if ( /^(["'`]).+\1$|,/.test(s) === false ) { return s; }
422
+ if ( /^\$|^(["'`]).*\1$|,/.test(s) === false ) { return s; }
422
423
  if ( s.includes("'") === false ) { return `'${s}'`; }
423
424
  if ( s.includes('"') === false ) { return `"${s}"`; }
424
425
  if ( s.includes('`') === false ) { return `\`${s}\``; }
@@ -4452,22 +4453,23 @@ StaticNetFilteringEngine.prototype.dnrFromCompiled = function(op, context, ...ar
4452
4453
  }
4453
4454
 
4454
4455
  // Priority:
4455
- // Block: 1 (default priority)
4456
- // Redirect: 2-9
4457
- // Excepted redirect: 12-19
4458
- // Allow: 20
4459
- // Block important: 30
4460
- // Redirect important: 32-39
4456
+ // Removeparam: 1-4
4457
+ // Block: 10 (default priority)
4458
+ // Redirect: 11-19
4459
+ // Excepted redirect: 21-29
4460
+ // Allow: 30
4461
+ // Block important: 40
4462
+ // Redirect important: 41-49
4461
4463
 
4462
4464
  const realms = new Map([
4463
- [ BLOCK_REALM, { type: 'block', priority: 0 } ],
4464
- [ ALLOW_REALM, { type: 'allow', priority: 20 } ],
4465
- [ REDIRECT_REALM, { type: 'redirect', priority: 2 } ],
4465
+ [ BLOCK_REALM, { type: 'block', priority: 10 } ],
4466
+ [ ALLOW_REALM, { type: 'allow', priority: 30 } ],
4467
+ [ REDIRECT_REALM, { type: 'redirect', priority: 11 } ],
4466
4468
  [ REMOVEPARAM_REALM, { type: 'removeparam', priority: 0 } ],
4467
4469
  [ CSP_REALM, { type: 'csp', priority: 0 } ],
4468
4470
  [ PERMISSIONS_REALM, { type: 'permissions', priority: 0 } ],
4469
4471
  [ URLTRANSFORM_REALM, { type: 'uritransform', priority: 0 } ],
4470
- [ HEADERS_REALM, { type: 'block', priority: 0 } ],
4472
+ [ HEADERS_REALM, { type: 'block', priority: 10 } ],
4471
4473
  [ URLSKIP_REALM, { type: 'urlskip', priority: 0 } ],
4472
4474
  ]);
4473
4475
  const partyness = new Map([
@@ -4605,7 +4607,7 @@ StaticNetFilteringEngine.prototype.dnrFromCompiled = function(op, context, ...ar
4605
4607
  if ( token !== '' ) {
4606
4608
  const match = /:(\d+)$/.exec(token);
4607
4609
  if ( match !== null ) {
4608
- rule.priority = Math.min(rule.priority + parseInt(match[1], 10), 9);
4610
+ rule.priority += Math.min(rule.priority + parseInt(match[1], 10), 9);
4609
4611
  token = token.slice(0, match.index);
4610
4612
  }
4611
4613
  }
@@ -4623,7 +4625,7 @@ StaticNetFilteringEngine.prototype.dnrFromCompiled = function(op, context, ...ar
4623
4625
  }
4624
4626
  break;
4625
4627
  }
4626
- case 'removeparam':
4628
+ case 'removeparam': {
4627
4629
  rule.action.type = 'redirect';
4628
4630
  if ( rule.__modifierValue === '|' ) {
4629
4631
  rule.__modifierValue = '';
@@ -4651,20 +4653,52 @@ StaticNetFilteringEngine.prototype.dnrFromCompiled = function(op, context, ...ar
4651
4653
  };
4652
4654
  }
4653
4655
  if ( rule.condition.resourceTypes === undefined ) {
4654
- rule.condition.resourceTypes = [
4655
- 'main_frame',
4656
- 'sub_frame',
4657
- 'xmlhttprequest',
4658
- ];
4656
+ if ( rule.condition.excludedResourceTypes === undefined ) {
4657
+ rule.condition.resourceTypes = [
4658
+ 'main_frame',
4659
+ 'sub_frame',
4660
+ 'xmlhttprequest',
4661
+ ];
4662
+ }
4663
+ }
4664
+ // https://github.com/uBlockOrigin/uBOL-home/issues/140
4665
+ // Mitigate until DNR API flaw is addressed by browser vendors
4666
+ let priority = rule.priority || 1;
4667
+ if ( rule.condition.urlFilter !== undefined ) { priority += 1; }
4668
+ if ( rule.condition.regexFilter !== undefined ) { priority += 1; }
4669
+ if ( rule.condition.initiatorDomains !== undefined ) { priority += 1; }
4670
+ if ( rule.condition.requestDomains !== undefined ) { priority += 1; }
4671
+ if ( priority !== 1 ) {
4672
+ rule.priority = priority;
4659
4673
  }
4660
4674
  if ( rule.__modifierAction === ALLOW_REALM ) {
4661
4675
  dnrAddRuleError(rule, `Unsupported removeparam exception: ${rule.__modifierValue}`);
4662
4676
  }
4663
4677
  break;
4678
+ }
4664
4679
  case 'uritransform': {
4665
4680
  dnrAddRuleError(rule, `Incompatible with DNR: uritransform=${rule.__modifierValue}`);
4666
4681
  break;
4667
4682
  }
4683
+ case 'urlskip': {
4684
+ let urlFilter = rule.condition?.urlFilter;
4685
+ if ( urlFilter === undefined ) { break; }
4686
+ let anchor = 0b000;
4687
+ if ( urlFilter.startsWith('||') ) {
4688
+ anchor |= 0b100;
4689
+ urlFilter = urlFilter.slice(2);
4690
+ } else if ( urlFilter.startsWith('|') ) {
4691
+ anchor |= 0b10;
4692
+ urlFilter = urlFilter.slice(1);
4693
+ }
4694
+ if ( urlFilter.endsWith('|') ) {
4695
+ anchor |= 0b001;
4696
+ urlFilter = urlFilter.slice(0, -1);
4697
+ }
4698
+ rule.condition.urlFilter = undefined;
4699
+ rule.condition.regexFilter = restrFromGenericPattern(urlFilter, anchor);
4700
+ break;
4701
+ }
4668
4702
  default:
4669
4703
  dnrAddRuleError(rule, `Unsupported modifier ${rule.__modifierType}`);
4670
4704
  break;
@@ -5377,55 +5411,6 @@ StaticNetFilteringEngine.prototype.transformRequest = function(fctxt, out = [])
5377
5411
  return out;
5378
5412
  };
5379
5413
 
5380
- /**
5381
- * @trustedOption urlskip
5382
- *
5383
- * @description
5384
- * Extract a URL from another URL according to one or more transformation steps,
5385
- * thereby skipping over intermediate network request(s) to remote servers.
5386
- * Requires a trusted source.
5387
- *
5388
- * @param steps
5389
- * A serie of space-separated directives representing the transformation steps
5390
- * to perform to extract the final URL to which a network request should be
5391
- * redirected.
5392
- *
5393
- * Supported directives:
5394
- *
5395
- * `?name`: extract the value of parameter `name` as the current string.
5396
- *
5397
- * `&i`: extract the name of the parameter at position `i` as the current
5398
- * string. The position is 1-based.
5399
- *
5400
- * `/.../`: extract the first capture group of a regex as the current string.
5401
- *
5402
- * `+https`: prepend the current string with `https://`.
5403
- *
5404
- * `-base64`: decode the current string as a base64-encoded string.
5405
- *
5406
- * `-uricomponent`: decode the current string as a URI encoded string.
5407
- *
5408
- * `-blocked`: allow the redirection of blocked requests. By default, blocked
5409
- * requests can't by urlskip'ed.
5410
- *
5411
- * At any given step, the currently extracted string may not necessarily be
5412
- * a valid URL, and more transformation steps may be needed to obtain a valid
5413
- * URL once all the steps are applied.
5414
- *
5415
- * An unsupported step or a failed step will abort the transformation and no
5416
- * redirection will be performed.
5417
- *
5418
- * The final step is expected to yield a valid URL. If the result is not a
5419
- * valid URL, no redirection will be performed.
5420
- *
5421
- * @example
5422
- * ||example.com/path/to/tracker$urlskip=?url
5423
- * ||example.com/path/to/tracker$urlskip=?url ?to
5424
- * ||pixiv.net/jump.php?$urlskip=&1
5425
- * ||podtrac.com/pts/redirect.mp3/$urlskip=/\/redirect\.mp3\/(.*?\.mp3\b)/ +https
5426
- *
5427
- * */
5428
-
5429
5414
  StaticNetFilteringEngine.prototype.urlSkip = function(
5430
5415
  fctxt,
5431
5416
  blocked,
@@ -5442,7 +5427,7 @@ StaticNetFilteringEngine.prototype.urlSkip = function(
5442
5427
  const urlin = fctxt.url;
5443
5428
  const value = directive.value;
5444
5429
  const steps = value.includes(' ') && value.split(/ +/) || [ value ];
5445
- const urlout = urlSkip(directive, urlin, blocked, steps);
5430
+ const urlout = urlSkip(urlin, blocked, steps, directive);
5446
5431
  if ( urlout === undefined ) { continue; }
5447
5432
  if ( urlout === urlin ) { continue; }
5448
5433
  fctxt.redirectURL = urlout;
@@ -5453,79 +5438,6 @@ StaticNetFilteringEngine.prototype.urlSkip = function(
5453
5438
  return out;
5454
5439
  };
5455
5440
 
5456
- function urlSkip(directive, url, blocked, steps) {
5457
- try {
5458
- let redirectBlocked = false;
5459
- let urlout = url;
5460
- for ( const step of steps ) {
5461
- const urlin = urlout;
5462
- const c0 = step.charCodeAt(0);
5463
- // Extract from URL parameter name at position i
5464
- if ( c0 === 0x26 ) { // &
5465
- const i = (parseInt(step.slice(1)) || 0) - 1;
5466
- if ( i < 0 ) { return; }
5467
- const url = new URL(urlin);
5468
- if ( i >= url.searchParams.size ) { return; }
5469
- const params = Array.from(url.searchParams.keys());
5470
- urlout = decodeURIComponent(params[i]);
5471
- continue;
5472
- }
5473
- // Enforce https
5474
- if ( c0 === 0x2B && step === '+https' ) {
5475
- const s = urlin.replace(/^https?:\/\//, '');
5476
- if ( /^[\w-]:\/\//.test(s) ) { return; }
5477
- urlout = `https://${s}`;
5478
- continue;
5479
- }
5480
- // Decode
5481
- if ( c0 === 0x2D ) {
5482
- // Base64
5483
- if ( step === '-base64' ) {
5484
- urlout = self.atob(urlin);
5485
- continue;
5486
- }
5487
- // URI component
5488
- if ( step === '-uricomponent' ) {
5489
- urlout = self.decodeURIComponent(urlin);
5490
- continue;
5491
- }
5492
- // Enable skip of blocked requests
5493
- if ( step === '-blocked' ) {
5494
- redirectBlocked = true;
5495
- continue;
5496
- }
5497
- }
5498
- // Regex extraction from first capture group
5499
- if ( c0 === 0x2F ) { // /
5500
- if ( directive.cache === null ) {
5501
- directive.cache = new RegExp(step.slice(1, -1));
5502
- }
5503
- const match = directive.cache.exec(urlin);
5504
- if ( match === null ) { return; }
5505
- if ( match.length <= 1 ) { return; }
5506
- urlout = match[1];
5507
- continue;
5508
- }
5509
- // Extract from URL parameter
5510
- if ( c0 === 0x3F ) { // ?
5511
- urlout = (new URL(urlin)).searchParams.get(step.slice(1));
5512
- if ( urlout === null ) { return; }
5513
- if ( urlout.includes(' ') ) {
5514
- urlout = urlout.replace(/ /g, '%20');
5515
- }
5516
- continue;
5517
- }
5518
- // Unknown directive
5519
- return;
5520
- }
5521
- const urlfinal = new URL(urlout);
5522
- if ( urlfinal.protocol !== 'https:' ) { return; }
5523
- if ( blocked && redirectBlocked !== true ) { return; }
5524
- return urlout;
5525
- } catch(x) {
5526
- }
5527
- }
5528
-
5529
5441
  /******************************************************************************/
5530
5442
 
5531
5443
  // https://github.com/uBlockOrigin/uBlock-issues/issues/1626
@@ -969,7 +969,7 @@ const injectCSP = function(fctxt, pageStore, responseHeaders) {
969
969
  const builtinDirectives = [];
970
970
 
971
971
  if ( pageStore.filterScripting(fctxt, true) === 1 ) {
972
- builtinDirectives.push(µb.cspNoScripting);
972
+ builtinDirectives.push(µb.hiddenSettings.noScriptingCSP);
973
973
  if ( logger.enabled ) {
974
974
  fctxt.setRealm('network').setType('scripting').toLogger();
975
975
  }
@@ -0,0 +1,166 @@
1
+ /*******************************************************************************
2
+
3
+ uBlock Origin - a comprehensive, efficient content blocker
4
+ Copyright (C) 2022-present Raymond Hill
5
+
6
+ This program is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program. If not, see {http://www.gnu.org/licenses/}.
18
+
19
+ Home: https://github.com/gorhill/uBlock
20
+ */
21
+
22
+ /**
23
+ * @trustedOption urlskip
24
+ *
25
+ * @description
26
+ * Extract a URL from another URL according to one or more transformation steps,
27
+ * thereby skipping over intermediate network request(s) to remote servers.
28
+ * Requires a trusted source.
29
+ *
30
+ * @param steps
31
+ * A serie of space-separated directives representing the transformation steps
32
+ * to perform to extract the final URL to which a network request should be
33
+ * redirected.
34
+ *
35
+ * Supported directives:
36
+ *
37
+ * `?name`: extract the value of parameter `name` as the current string.
38
+ *
39
+ * `&i`: extract the name of the parameter at position `i` as the current
40
+ * string. The position is 1-based.
41
+ *
42
+ * `#`: extract the hash as the current string.
43
+ *
44
+ * `/.../`: extract the first capture group of a regex as the current string.
45
+ *
46
+ * `+https`: prepend the current string with `https://`.
47
+ *
48
+ * `-base64`: decode the current string as a base64-encoded string.
49
+ *
50
+ * `-safebase64`: decode the current string as a safe base64-encoded string.
51
+ *
52
+ * `-uricomponent`: decode the current string as a URI encoded string.
53
+ *
54
+ * `-blocked`: allow the redirection of blocked requests. By default, blocked
55
+ * requests can't by urlskip'ed.
56
+ *
57
+ * At any given step, the currently extracted string may not necessarily be
58
+ * a valid URL, and more transformation steps may be needed to obtain a valid
59
+ * URL once all the steps are applied.
60
+ *
61
+ * An unsupported step or a failed step will abort the transformation and no
62
+ * redirection will be performed.
63
+ *
64
+ * The final step is expected to yield a valid URL. If the result is not a
65
+ * valid URL, no redirection will be performed.
66
+ *
67
+ * @example
68
+ * ||example.com/path/to/tracker$urlskip=?url
69
+ * ||example.com/path/to/tracker$urlskip=?url ?to
70
+ * ||pixiv.net/jump.php?$urlskip=&1
71
+ * ||podtrac.com/pts/redirect.mp3/$urlskip=/\/redirect\.mp3\/(.*?\.mp3\b)/ +https
72
+ *
73
+ * */
74
+
75
+ export function urlSkip(url, blocked, steps, directive = {}) {
76
+ try {
77
+ let redirectBlocked = false;
78
+ let urlout = url;
79
+ for ( const step of steps ) {
80
+ const urlin = urlout;
81
+ const c0 = step.charCodeAt(0);
82
+ // Extract from hash
83
+ if ( c0 === 0x23 && step === '#' ) { // #
84
+ const pos = urlin.indexOf('#');
85
+ urlout = pos !== -1 ? urlin.slice(pos+1) : '';
86
+ continue;
87
+ }
88
+ // Extract from URL parameter name at position i
89
+ if ( c0 === 0x26 ) { // &
90
+ const i = (parseInt(step.slice(1)) || 0) - 1;
91
+ if ( i < 0 ) { return; }
92
+ const url = new URL(urlin);
93
+ if ( i >= url.searchParams.size ) { return; }
94
+ const params = Array.from(url.searchParams.keys());
95
+ urlout = decodeURIComponent(params[i]);
96
+ continue;
97
+ }
98
+ // Enforce https
99
+ if ( c0 === 0x2B && step === '+https' ) { // +
100
+ const s = urlin.replace(/^https?:\/\//, '');
101
+ if ( /^[\w-]:\/\//.test(s) ) { return; }
102
+ urlout = `https://${s}`;
103
+ continue;
104
+ }
105
+ // Decode
106
+ if ( c0 === 0x2D ) { // -
107
+ // Base64
108
+ if ( step === '-base64' ) {
109
+ urlout = self.atob(urlin);
110
+ continue;
111
+ }
112
+ // Safe Base64
113
+ if ( step === '-safebase64' ) {
114
+ if ( urlSkip.safeBase64Replacer === undefined ) {
115
+ urlSkip.safeBase64Map = { '-': '+', '_': '/' };
116
+ urlSkip.safeBase64Replacer = s => urlSkip.safeBase64Map[s];
117
+ }
118
+ urlout = urlin.replace(/[-_]/g, urlSkip.safeBase64Replacer);
119
+ urlout = self.atob(urlout);
120
+ continue;
121
+ }
122
+ // URI component
123
+ if ( step === '-uricomponent' ) {
124
+ urlout = self.decodeURIComponent(urlin);
125
+ continue;
126
+ }
127
+ // Enable skip of blocked requests
128
+ if ( step === '-blocked' ) {
129
+ redirectBlocked = true;
130
+ continue;
131
+ }
132
+ }
133
+ // Regex extraction from first capture group
134
+ if ( c0 === 0x2F ) { // /
135
+ const re = directive.cache ?? new RegExp(step.slice(1, -1));
136
+ if ( directive.cache === null ) {
137
+ directive.cache = re;
138
+ }
139
+ const match = re.exec(urlin);
140
+ if ( match === null ) { return; }
141
+ if ( match.length <= 1 ) { return; }
142
+ urlout = match[1];
143
+ continue;
144
+ }
145
+ // Extract from URL parameter
146
+ if ( c0 === 0x3F ) { // ?
147
+ urlout = (new URL(urlin)).searchParams.get(step.slice(1));
148
+ if ( urlout === null ) { return; }
149
+ if ( urlout.includes(' ') ) {
150
+ urlout = urlout.replace(/ /g, '%20');
151
+ }
152
+ continue;
153
+ }
154
+ // Unknown directive
155
+ return;
156
+ }
157
+ const urlfinal = new URL(urlout);
158
+ if ( urlfinal.protocol !== 'https:' ) {
159
+ if ( urlfinal.protocol !== 'http:' ) { return; }
160
+ urlout = urlout.replace('http', 'https');
161
+ }
162
+ if ( blocked && redirectBlocked !== true ) { return; }
163
+ return urlout;
164
+ } catch(x) {
165
+ }
166
+ }
@@ -208,19 +208,43 @@ vAPI.prefetching = (( ) => {
208
208
 
209
209
  /******************************************************************************/
210
210
 
211
- vAPI.scriptletsInjector = ((doc, details) => {
212
- let script;
213
- try {
214
- script = doc.createElement('script');
215
- script.appendChild(doc.createTextNode(details.scriptlets));
216
- (doc.head || doc.documentElement).appendChild(script);
217
- self.uBO_scriptletsInjected = details.filters;
218
- } catch (ex) {
219
- }
220
- if ( script ) {
221
- script.remove();
222
- script.textContent = '';
223
- }
224
- }).toString();
211
+ vAPI.scriptletsInjector = (( ) => {
212
+ const parts = [
213
+ '(',
214
+ function(details) {
215
+ if ( typeof self.uBO_scriptletsInjected === 'string' ) { return; }
216
+ const doc = document;
217
+ const { location } = doc;
218
+ if ( location === null ) { return; }
219
+ const { hostname } = location;
220
+ if ( hostname !== '' && details.hostname !== hostname ) { return; }
221
+ let script;
222
+ try {
223
+ script = doc.createElement('script');
224
+ script.appendChild(doc.createTextNode(details.scriptlets));
225
+ (doc.head || doc.documentElement).appendChild(script);
226
+ self.uBO_scriptletsInjected = details.filters;
227
+ } catch (ex) {
228
+ }
229
+ if ( script ) {
230
+ script.remove();
231
+ script.textContent = '';
232
+ }
233
+ return 0;
234
+ }.toString(),
235
+ ')(',
236
+ 'json-slot',
237
+ ');',
238
+ ];
239
+ const jsonSlot = parts.indexOf('json-slot');
240
+ return (hostname, details) => {
241
+ parts[jsonSlot] = JSON.stringify({
242
+ hostname,
243
+ scriptlets: details.mainWorld,
244
+ filters: details.filters,
245
+ });
246
+ return parts.join('');
247
+ };
248
+ })();
225
249
 
226
250
  /******************************************************************************/
@@ -111,7 +111,7 @@
111
111
  "storage": {
112
112
  "managed_schema": "managed_storage.json"
113
113
  },
114
- "version": "1.61.2",
114
+ "version": "1.62.0",
115
115
  "web_accessible_resources": [
116
116
  "/web_accessible_resources/*"
117
117
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@browserless.io/browserless",
3
- "version": "2.25.0-beta-2",
3
+ "version": "2.25.0",
4
4
  "license": "SSPL",
5
5
  "description": "The browserless platform",
6
6
  "author": "browserless.io",
@@ -25,7 +25,7 @@
25
25
  "dev": "npm run build:dev && env-cmd -f .env node build",
26
26
  "install:adblock": "node scripts/install-adblock.js",
27
27
  "install:debugger": "node scripts/install-debugger.js",
28
- "install:browsers": "node node_modules/playwright-core/cli.js install chromium firefox webkit",
28
+ "install:browsers": "node node_modules/playwright-core/cli.js install chromium firefox webkit msedge",
29
29
  "install:dev": "npm run install:browsers && npm run install:debugger",
30
30
  "lint": "cross-env ESLINT_USE_FLAT_CONFIG=false eslint . --ext .ts --fix",
31
31
  "prepack": "npm run build:dev",
@@ -51,60 +51,60 @@
51
51
  "debug": "^4.4.0",
52
52
  "del": "^8.0.0",
53
53
  "enjoi": "^9.0.1",
54
- "file-type": "^19.6.0",
54
+ "file-type": "^20.1.0",
55
55
  "get-port": "^7.1.0",
56
56
  "gradient-string": "^3.0.0",
57
57
  "http-proxy": "^1.18.1",
58
58
  "lighthouse": "^12.3.0",
59
59
  "micromatch": "^4.0.8",
60
- "playwright-1.45": "npm:playwright-core@1.45.3",
61
60
  "playwright-1.46": "npm:playwright-core@1.46.1",
62
61
  "playwright-1.47": "npm:playwright-core@1.47.2",
63
62
  "playwright-1.48": "npm:playwright-core@1.48.2",
64
- "playwright-core": "^1.49.1",
65
- "puppeteer-core": "^23.11.0",
63
+ "playwright-1.49": "npm:playwright-core@1.49.1",
64
+ "playwright-core": "1.50.1",
65
+ "puppeteer-core": "24.2.1",
66
66
  "puppeteer-extra": "^3.3.6",
67
67
  "puppeteer-extra-plugin-stealth": "^2.11.2",
68
68
  "queue": "^7.0.0",
69
- "systeminformation": "^5.23.14",
70
- "tar-fs": "^3.0.6"
69
+ "systeminformation": "^5.25.11",
70
+ "tar-fs": "^3.0.8"
71
71
  },
72
72
  "optionalDependencies": {
73
73
  "@types/chai": "^5.0.1",
74
74
  "@types/debug": "^4.1.12",
75
75
  "@types/gradient-string": "^1.1.6",
76
- "@types/http-proxy": "^1.17.15",
76
+ "@types/http-proxy": "^1.17.16",
77
77
  "@types/micromatch": "^4.0.9",
78
78
  "@types/mocha": "^10.0.10",
79
- "@types/node": "^22.10.2",
79
+ "@types/node": "^22.13.4",
80
80
  "@types/sinon": "^17.0.3",
81
- "@typescript-eslint/eslint-plugin": "^8.18.1",
82
- "@typescript-eslint/parser": "^8.18.1",
81
+ "@typescript-eslint/eslint-plugin": "^8.24.1",
82
+ "@typescript-eslint/parser": "^8.24.1",
83
83
  "assert": "^2.0.0",
84
- "chai": "^5.1.2",
84
+ "chai": "^5.2.0",
85
85
  "cross-env": "^7.0.3",
86
86
  "env-cmd": "^10.1.0",
87
- "esbuild": "^0.24.0",
87
+ "esbuild": "^0.25.0",
88
88
  "esbuild-plugin-polyfill-node": "^0.3.0",
89
- "eslint": "^9.17.0",
89
+ "eslint": "^9.20.1",
90
90
  "extract-zip": "^2.0.1",
91
91
  "gunzip-maybe": "^1.4.2",
92
- "marked": "^15.0.4",
93
- "mocha": "^11.0.1",
92
+ "marked": "^15.0.7",
93
+ "mocha": "^11.1.0",
94
94
  "move-file": "^3.1.0",
95
- "prettier": "^3.4.2",
95
+ "prettier": "^3.5.1",
96
96
  "sinon": "^19.0.2",
97
97
  "ts-node": "^10.9.2",
98
- "typescript": "^5.7.2",
98
+ "typescript": "^5.7.3",
99
99
  "typescript-json-schema": "^0.65.1"
100
100
  },
101
101
  "playwrightVersions": {
102
102
  "default": "playwright-core",
103
- "1.49": "playwright-core",
103
+ "1.50": "playwright-core",
104
+ "1.49": "playwright-1.49",
104
105
  "1.48": "playwright-1.48",
105
106
  "1.47": "playwright-1.47",
106
- "1.46": "playwright-1.46",
107
- "1.45": "playwright-1.45"
107
+ "1.46": "playwright-1.46"
108
108
  },
109
109
  "eslintConfig": {
110
110
  "root": true,
@@ -10,6 +10,8 @@ import {
10
10
  ChromiumCDP,
11
11
  ChromiumPlaywright,
12
12
  Config,
13
+ EdgeCDP,
14
+ EdgePlaywright,
13
15
  FileSystem,
14
16
  FirefoxPlaywright,
15
17
  HTTPRoute,
@@ -235,7 +237,9 @@ export class Browserless extends EventEmitter {
235
237
  const internalBrowsers = [
236
238
  ChromiumCDP,
237
239
  ChromeCDP,
240
+ EdgeCDP,
238
241
  FirefoxPlaywright,
242
+ EdgePlaywright,
239
243
  ChromiumPlaywright,
240
244
  WebKitPlaywright,
241
245
  ];
@@ -6,6 +6,7 @@ import {
6
6
  Request,
7
7
  ServerError,
8
8
  chromeExecutablePath,
9
+ edgeExecutablePath,
9
10
  noop,
10
11
  once,
11
12
  ublockPath,
@@ -374,3 +375,7 @@ export class ChromiumCDP extends EventEmitter {
374
375
  export class ChromeCDP extends ChromiumCDP {
375
376
  protected executablePath = chromeExecutablePath();
376
377
  }
378
+
379
+ export class EdgeCDP extends ChromiumCDP {
380
+ protected executablePath = edgeExecutablePath();
381
+ }