@cypress/github-action 7.3.0 → 7.4.1

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 (3) hide show
  1. package/README.md +61 -61
  2. package/dist/index.js +303 -139
  3. package/package.json +5 -5
package/README.md CHANGED
@@ -101,7 +101,7 @@ jobs:
101
101
  runs-on: ubuntu-24.04
102
102
  steps:
103
103
  - name: Checkout
104
- uses: actions/checkout@v6
104
+ uses: actions/checkout@v7
105
105
  # Install dependencies with caching
106
106
  # and run all Cypress tests
107
107
  - name: Cypress run
@@ -126,7 +126,7 @@ jobs:
126
126
  runs-on: ubuntu-24.04
127
127
  steps:
128
128
  - name: Checkout
129
- uses: actions/checkout@v6
129
+ uses: actions/checkout@v7
130
130
  - name: Cypress run
131
131
  uses: cypress-io/github-action@v7
132
132
  with:
@@ -179,7 +179,7 @@ jobs:
179
179
  runs-on: ubuntu-24.04
180
180
  name: E2E on Chrome
181
181
  steps:
182
- - uses: actions/checkout@v6
182
+ - uses: actions/checkout@v7
183
183
  - uses: cypress-io/github-action@v7
184
184
  with:
185
185
  browser: chrome
@@ -199,7 +199,7 @@ jobs:
199
199
  runs-on: ubuntu-24.04
200
200
  name: E2E on Chrome for Testing
201
201
  steps:
202
- - uses: actions/checkout@v6
202
+ - uses: actions/checkout@v7
203
203
  - uses: browser-actions/setup-chrome@v2
204
204
  with:
205
205
  chrome-version: 140
@@ -220,7 +220,7 @@ jobs:
220
220
  runs-on: ubuntu-24.04
221
221
  name: E2E on Firefox
222
222
  steps:
223
- - uses: actions/checkout@v6
223
+ - uses: actions/checkout@v7
224
224
  - uses: cypress-io/github-action@v7
225
225
  with:
226
226
  browser: firefox
@@ -238,7 +238,7 @@ jobs:
238
238
  runs-on: ubuntu-24.04
239
239
  name: E2E on Edge
240
240
  steps:
241
- - uses: actions/checkout@v6
241
+ - uses: actions/checkout@v7
242
242
  - uses: cypress-io/github-action@v7
243
243
  with:
244
244
  browser: edge
@@ -257,7 +257,7 @@ jobs:
257
257
  cypress-run:
258
258
  runs-on: ubuntu-24.04
259
259
  steps:
260
- - uses: actions/checkout@v6
260
+ - uses: actions/checkout@v7
261
261
  - uses: cypress-io/github-action@v7
262
262
  with:
263
263
  browser: chrome
@@ -280,7 +280,7 @@ jobs:
280
280
  image: cypress/browsers:latest
281
281
  options: --user 1001
282
282
  steps:
283
- - uses: actions/checkout@v6
283
+ - uses: actions/checkout@v7
284
284
  - uses: cypress-io/github-action@v7
285
285
  with:
286
286
  browser: chrome
@@ -304,7 +304,7 @@ jobs:
304
304
  image: cypress/included:latest
305
305
  options: --user 1001
306
306
  steps:
307
- - uses: actions/checkout@v6
307
+ - uses: actions/checkout@v7
308
308
  - uses: cypress-io/github-action@v7
309
309
  with:
310
310
  browser: chrome
@@ -328,7 +328,7 @@ jobs:
328
328
  runs-on: ubuntu-24.04
329
329
  steps:
330
330
  - name: Checkout
331
- uses: actions/checkout@v6
331
+ uses: actions/checkout@v7
332
332
 
333
333
  - name: Cypress run with env
334
334
  uses: cypress-io/github-action@v7
@@ -346,7 +346,7 @@ jobs:
346
346
  runs-on: ubuntu-24.04
347
347
  steps:
348
348
  - name: Checkout
349
- uses: actions/checkout@v6
349
+ uses: actions/checkout@v7
350
350
 
351
351
  - name: Cypress run with env
352
352
  uses: cypress-io/github-action@v7
@@ -371,7 +371,7 @@ jobs:
371
371
  runs-on: ubuntu-24.04
372
372
  steps:
373
373
  - name: Checkout
374
- uses: actions/checkout@v6
374
+ uses: actions/checkout@v7
375
375
 
376
376
  - name: Cypress run with expose
377
377
  uses: cypress-io/github-action@v7
@@ -396,7 +396,7 @@ jobs:
396
396
  runs-on: ubuntu-24.04
397
397
  steps:
398
398
  - name: Checkout
399
- uses: actions/checkout@v6
399
+ uses: actions/checkout@v7
400
400
 
401
401
  - name: Cypress run
402
402
  uses: cypress-io/github-action@v7
@@ -427,7 +427,7 @@ jobs:
427
427
  runs-on: ubuntu-24.04
428
428
  steps:
429
429
  - name: Checkout
430
- uses: actions/checkout@v6
430
+ uses: actions/checkout@v7
431
431
  - name: Cypress run
432
432
  uses: cypress-io/github-action@v7
433
433
  with:
@@ -459,7 +459,7 @@ jobs:
459
459
  runs-on: ubuntu-24.04
460
460
  steps:
461
461
  - name: Checkout
462
- uses: actions/checkout@v6
462
+ uses: actions/checkout@v7
463
463
 
464
464
  - name: Cypress run
465
465
  uses: cypress-io/github-action@v7
@@ -489,7 +489,7 @@ jobs:
489
489
  runs-on: ubuntu-24.04
490
490
  steps:
491
491
  - name: Checkout
492
- uses: actions/checkout@v6
492
+ uses: actions/checkout@v7
493
493
  - name: Cypress run
494
494
  uses: cypress-io/github-action@v7
495
495
  with:
@@ -522,7 +522,7 @@ jobs:
522
522
  runs-on: ubuntu-24.04
523
523
  steps:
524
524
  - name: Checkout
525
- uses: actions/checkout@v6
525
+ uses: actions/checkout@v7
526
526
  - name: Cypress run
527
527
  uses: cypress-io/github-action@v7
528
528
  with:
@@ -560,7 +560,7 @@ jobs:
560
560
  runs-on: ubuntu-24.04
561
561
  steps:
562
562
  - name: Checkout
563
- uses: actions/checkout@v6
563
+ uses: actions/checkout@v7
564
564
 
565
565
  - name: Cypress run
566
566
  uses: cypress-io/github-action@v7
@@ -592,11 +592,11 @@ jobs:
592
592
  node:
593
593
  - 22
594
594
  - 24
595
- - 25
595
+ - 26
596
596
  name: E2E on Node v${{ matrix.node }}
597
597
  steps:
598
598
  - name: Checkout
599
- uses: actions/checkout@v6
599
+ uses: actions/checkout@v7
600
600
  - name: Install Node.js
601
601
  uses: actions/setup-node@v6
602
602
  with:
@@ -634,7 +634,7 @@ jobs:
634
634
  name: E2E
635
635
  steps:
636
636
  - name: Checkout
637
- uses: actions/checkout@v6
637
+ uses: actions/checkout@v7
638
638
 
639
639
  - name: Cypress run
640
640
  uses: cypress-io/github-action@v7
@@ -661,7 +661,7 @@ jobs:
661
661
  runs-on: ubuntu-24.04
662
662
  name: Artifacts
663
663
  steps:
664
- - uses: actions/checkout@v6
664
+ - uses: actions/checkout@v7
665
665
  - uses: cypress-io/github-action@v7
666
666
  # after the test run completes store videos and any screenshots
667
667
  - uses: actions/upload-artifact@v7
@@ -690,7 +690,7 @@ jobs:
690
690
  runs-on: ubuntu-24.04
691
691
  steps:
692
692
  - name: Checkout
693
- uses: actions/checkout@v6
693
+ uses: actions/checkout@v7
694
694
  # Install dependencies with caching
695
695
  # and run all Cypress tests with `quiet` parameter
696
696
  - name: Cypress run
@@ -715,7 +715,7 @@ jobs:
715
715
  runs-on: ubuntu-24.04
716
716
  steps:
717
717
  - name: Checkout
718
- uses: actions/checkout@v6
718
+ uses: actions/checkout@v7
719
719
 
720
720
  - name: Cypress run
721
721
  uses: cypress-io/github-action@v7
@@ -738,7 +738,7 @@ jobs:
738
738
  runs-on: ubuntu-24.04
739
739
  steps:
740
740
  - name: Checkout
741
- uses: actions/checkout@v6
741
+ uses: actions/checkout@v7
742
742
 
743
743
  - name: Cypress run
744
744
  uses: cypress-io/github-action@v7
@@ -772,7 +772,7 @@ jobs:
772
772
  containers: [1, 2, 3]
773
773
  steps:
774
774
  - name: Checkout
775
- uses: actions/checkout@v6
775
+ uses: actions/checkout@v7
776
776
 
777
777
  # because of "record" and "parallel" parameters
778
778
  # these containers will load balance all found tests among themselves
@@ -833,7 +833,7 @@ jobs:
833
833
  runs-on: ubuntu-24.04
834
834
  steps:
835
835
  - name: Checkout
836
- uses: actions/checkout@v6
836
+ uses: actions/checkout@v7
837
837
  - name: Cypress run
838
838
  uses: cypress-io/github-action@v7
839
839
  with:
@@ -852,7 +852,7 @@ jobs:
852
852
  runs-on: ubuntu-24.04
853
853
  steps:
854
854
  - name: Checkout
855
- uses: actions/checkout@v6
855
+ uses: actions/checkout@v7
856
856
  - name: Cypress run
857
857
  uses: cypress-io/github-action@v7
858
858
  with:
@@ -871,7 +871,7 @@ jobs:
871
871
  runs-on: ubuntu-24.04
872
872
  steps:
873
873
  - name: Checkout
874
- uses: actions/checkout@v6
874
+ uses: actions/checkout@v7
875
875
  - name: Cypress run
876
876
  uses: cypress-io/github-action@v7
877
877
  with:
@@ -897,7 +897,7 @@ jobs:
897
897
  runs-on: ubuntu-24.04
898
898
  steps:
899
899
  - name: Checkout
900
- uses: actions/checkout@v6
900
+ uses: actions/checkout@v7
901
901
  - name: Cypress run
902
902
  uses: cypress-io/github-action@v7
903
903
  with:
@@ -927,7 +927,7 @@ jobs:
927
927
  runs-on: ubuntu-24.04
928
928
  steps:
929
929
  - name: Checkout
930
- uses: actions/checkout@v6
930
+ uses: actions/checkout@v7
931
931
  - name: Cypress run
932
932
  uses: cypress-io/github-action@v7
933
933
  with:
@@ -1016,7 +1016,7 @@ jobs:
1016
1016
  runs-on: ubuntu-24.04
1017
1017
  steps:
1018
1018
  - name: Checkout
1019
- uses: actions/checkout@v6
1019
+ uses: actions/checkout@v7
1020
1020
  - name: Cypress run
1021
1021
  uses: cypress-io/github-action@v7
1022
1022
  with:
@@ -1043,7 +1043,7 @@ Correct example snippet:
1043
1043
 
1044
1044
  ```yml
1045
1045
  steps:
1046
- - uses: actions/checkout@v6
1046
+ - uses: actions/checkout@v7
1047
1047
  - uses: cypress-io/github-action@v7
1048
1048
  with:
1049
1049
  command: npm run custom-test
@@ -1066,7 +1066,7 @@ jobs:
1066
1066
  # run 3 copies of the current job in parallel
1067
1067
  containers: [1, 2, 3]
1068
1068
  steps:
1069
- - uses: actions/checkout@v6
1069
+ - uses: actions/checkout@v7
1070
1070
  - uses: cypress-io/github-action@v7
1071
1071
  with:
1072
1072
  record: true
@@ -1101,7 +1101,7 @@ jobs:
1101
1101
  smoke-tests:
1102
1102
  needs: ['prepare']
1103
1103
  steps:
1104
- - uses: actions/checkout@v6
1104
+ - uses: actions/checkout@v7
1105
1105
  - uses: cypress-io/github-action@v7
1106
1106
  with:
1107
1107
  record: true
@@ -1141,7 +1141,7 @@ jobs:
1141
1141
  cypress-run:
1142
1142
  runs-on: ubuntu-24.04
1143
1143
  steps:
1144
- - uses: actions/checkout@v6
1144
+ - uses: actions/checkout@v7
1145
1145
  - uses: cypress-io/github-action@v7
1146
1146
  with:
1147
1147
  start: npm start
@@ -1179,7 +1179,7 @@ jobs:
1179
1179
  test:
1180
1180
  runs-on: ubuntu-24.04
1181
1181
  steps:
1182
- - uses: actions/checkout@v6
1182
+ - uses: actions/checkout@v7
1183
1183
  - name: Install root dependencies
1184
1184
  run: npm ci
1185
1185
 
@@ -1212,11 +1212,11 @@ jobs:
1212
1212
  runs-on: ubuntu-24.04
1213
1213
  steps:
1214
1214
  - name: Checkout
1215
- uses: actions/checkout@v6
1215
+ uses: actions/checkout@v7
1216
1216
  - name: Install pnpm
1217
- uses: pnpm/action-setup@v5
1217
+ uses: pnpm/action-setup@v6
1218
1218
  with:
1219
- version: 10
1219
+ version: 11
1220
1220
  - name: Install Node.js
1221
1221
  uses: actions/setup-node@v6
1222
1222
  with:
@@ -1272,7 +1272,7 @@ jobs:
1272
1272
  runs-on: ubuntu-24.04
1273
1273
  steps:
1274
1274
  - name: Checkout
1275
- uses: actions/checkout@v6
1275
+ uses: actions/checkout@v7
1276
1276
  - name: Cypress run
1277
1277
  uses: cypress-io/github-action@v7
1278
1278
  with:
@@ -1295,7 +1295,7 @@ jobs:
1295
1295
  runs-on: ubuntu-24.04
1296
1296
  steps:
1297
1297
  - name: Checkout
1298
- uses: actions/checkout@v6
1298
+ uses: actions/checkout@v7
1299
1299
  - run: corepack enable # (experimental and optional)
1300
1300
  - name: Set up Yarn cache
1301
1301
  uses: actions/setup-node@v6
@@ -1329,7 +1329,7 @@ jobs:
1329
1329
  runs-on: ubuntu-24.04
1330
1330
  steps:
1331
1331
  - name: Checkout
1332
- uses: actions/checkout@v6
1332
+ uses: actions/checkout@v7
1333
1333
  - name: Cypress run
1334
1334
  uses: cypress-io/github-action@v7
1335
1335
  with:
@@ -1358,7 +1358,7 @@ jobs:
1358
1358
  # and tests in a subfolder like "workspace-1"
1359
1359
  runs-on: ubuntu-24.04
1360
1360
  steps:
1361
- - uses: actions/checkout@v6
1361
+ - uses: actions/checkout@v7
1362
1362
  - uses: cypress-io/github-action@v7
1363
1363
  with:
1364
1364
  working-directory: examples/start-and-yarn-workspaces/workspace-1
@@ -1390,7 +1390,7 @@ jobs:
1390
1390
  runs-on: ubuntu-24.04
1391
1391
  name:
1392
1392
  steps:
1393
- - uses: actions/checkout@v6
1393
+ - uses: actions/checkout@v7
1394
1394
  - uses: actions/setup-node@v6
1395
1395
  with:
1396
1396
  node-version: lts
@@ -1417,11 +1417,11 @@ jobs:
1417
1417
  node:
1418
1418
  - 22
1419
1419
  - 24
1420
- - 25
1420
+ - 26
1421
1421
  name: E2E on Node v${{ matrix.node }}
1422
1422
  steps:
1423
1423
  - name: Checkout
1424
- uses: actions/checkout@v6
1424
+ uses: actions/checkout@v7
1425
1425
  - name: Install Node.js
1426
1426
  uses: actions/setup-node@v6
1427
1427
  with:
@@ -1454,10 +1454,10 @@ jobs:
1454
1454
  node:
1455
1455
  - 22
1456
1456
  - 24
1457
- - 25
1457
+ - 26
1458
1458
  name: E2E on Node v${{ matrix.node }}
1459
1459
  steps:
1460
- - uses: actions/checkout@v6
1460
+ - uses: actions/checkout@v7
1461
1461
  - uses: actions/setup-node@v6
1462
1462
  with:
1463
1463
  node-version: ${{ matrix.node }}
@@ -1479,7 +1479,7 @@ jobs:
1479
1479
  test:
1480
1480
  runs-on: ubuntu-24.04
1481
1481
  steps:
1482
- - uses: actions/checkout@v6
1482
+ - uses: actions/checkout@v7
1483
1483
  - name: Install dependencies
1484
1484
  uses: cypress-io/github-action@v7
1485
1485
  with:
@@ -1512,7 +1512,7 @@ jobs:
1512
1512
  build:
1513
1513
  runs-on: ubuntu-24.04
1514
1514
  steps:
1515
- - uses: actions/checkout@v6
1515
+ - uses: actions/checkout@v7
1516
1516
  - name: Build app
1517
1517
  uses: cypress-io/github-action@v7
1518
1518
  with:
@@ -1530,7 +1530,7 @@ jobs:
1530
1530
  needs: build
1531
1531
  runs-on: ubuntu-24.04
1532
1532
  steps:
1533
- - uses: actions/checkout@v6
1533
+ - uses: actions/checkout@v7
1534
1534
  - name: Restore build artifacts
1535
1535
  uses: actions/download-artifact@v8
1536
1536
  with:
@@ -1554,7 +1554,7 @@ Finally, you might not need this GH Action at all. For example, if you want to s
1554
1554
  If the project has many dependencies, but you want to install just Cypress you can combine this action with `actions/cache` and `npm i cypress` commands yourself.
1555
1555
 
1556
1556
  ```yml
1557
- - uses: actions/checkout@v6
1557
+ - uses: actions/checkout@v7
1558
1558
  - uses: actions/cache@v5
1559
1559
  with:
1560
1560
  path: |
@@ -1581,7 +1581,7 @@ jobs:
1581
1581
  # to prevent a hanging process from using all your CI minutes
1582
1582
  timeout-minutes: 10
1583
1583
  steps:
1584
- - uses: actions/checkout@v6
1584
+ - uses: actions/checkout@v7
1585
1585
  - uses: cypress-io/github-action@v7
1586
1586
  # you can specify individual step timeout too
1587
1587
  timeout-minutes: 5
@@ -1624,7 +1624,7 @@ jobs:
1624
1624
  runs-on: ubuntu-24.04
1625
1625
  steps:
1626
1626
  - name: Check out repo
1627
- uses: actions/checkout@v6
1627
+ uses: actions/checkout@v7
1628
1628
  - name: Cypress run # install dependencies and run Cypress E2E tests
1629
1629
  uses: cypress-io/github-action@v7 # replaces CLI cypress run
1630
1630
  with:
@@ -1812,7 +1812,7 @@ jobs:
1812
1812
  runs-on: ubuntu-24.04
1813
1813
  steps:
1814
1814
  - name: Checkout
1815
- uses: actions/checkout@v6
1815
+ uses: actions/checkout@v7
1816
1816
  - name: Cypress run
1817
1817
  uses: cypress-io/github-action@v7
1818
1818
  with:
@@ -1829,7 +1829,7 @@ jobs:
1829
1829
  runs-on: ubuntu-24.04
1830
1830
  steps:
1831
1831
  - name: Checkout
1832
- uses: actions/checkout@v6
1832
+ uses: actions/checkout@v7
1833
1833
  - name: Cypress install
1834
1834
  uses: cypress-io/github-action@v7
1835
1835
  with:
@@ -1860,7 +1860,7 @@ jobs:
1860
1860
  runs-on: ubuntu-24.04
1861
1861
  steps:
1862
1862
  - name: Checkout
1863
- uses: actions/checkout@v6
1863
+ uses: actions/checkout@v7
1864
1864
  - name: Cypress nightly tests 🌃
1865
1865
  uses: cypress-io/github-action@v7
1866
1866
  ```
@@ -1880,7 +1880,7 @@ jobs:
1880
1880
  tests:
1881
1881
  runs-on: ubuntu-24.04
1882
1882
  steps:
1883
- - uses: actions/checkout@v6
1883
+ - uses: actions/checkout@v7
1884
1884
  - name: Cypress headless tests
1885
1885
  uses: cypress-io/github-action@v7
1886
1886
  with:
@@ -1909,7 +1909,7 @@ jobs:
1909
1909
  runs-on: ubuntu-24.04
1910
1910
  steps:
1911
1911
  - name: Checkout
1912
- uses: actions/checkout@v6
1912
+ uses: actions/checkout@v7
1913
1913
  - name: Cypress run
1914
1914
  uses: cypress-io/github-action@v7
1915
1915
  with:
@@ -1922,7 +1922,7 @@ jobs:
1922
1922
 
1923
1923
  Node.js is required to run this action. The recommended version `v7` supports:
1924
1924
 
1925
- - **Node.js** 22.x, 24.x and 25.x
1925
+ - **Node.js** 22.x, 24.x and 26.x
1926
1926
 
1927
1927
  and is generally aligned with [Node.js's release schedule](https://github.com/nodejs/Release#readme).
1928
1928
 
package/dist/index.js CHANGED
@@ -36268,8 +36268,6 @@ function defaultFactory (origin, opts) {
36268
36268
 
36269
36269
  class Agent extends DispatcherBase {
36270
36270
  constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) {
36271
- super()
36272
-
36273
36271
  if (typeof factory !== 'function') {
36274
36272
  throw new InvalidArgumentError('factory must be a function.')
36275
36273
  }
@@ -36282,6 +36280,8 @@ class Agent extends DispatcherBase {
36282
36280
  throw new InvalidArgumentError('maxRedirections must be a positive number')
36283
36281
  }
36284
36282
 
36283
+ super(options)
36284
+
36285
36285
  if (connect && typeof connect !== 'function') {
36286
36286
  connect = { ...connect }
36287
36287
  }
@@ -36655,6 +36655,9 @@ const EMPTY_BUF = Buffer.alloc(0)
36655
36655
  const FastBuffer = Buffer[Symbol.species]
36656
36656
  const addListener = util.addListener
36657
36657
  const removeAllListeners = util.removeAllListeners
36658
+ const kIdleSocketValidation = Symbol('kIdleSocketValidation')
36659
+ const kIdleSocketValidationTimeout = Symbol('kIdleSocketValidationTimeout')
36660
+ const kSocketUsed = Symbol('kSocketUsed')
36658
36661
 
36659
36662
  let extractBody
36660
36663
 
@@ -36877,29 +36880,71 @@ class Parser {
36877
36880
 
36878
36881
  const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr
36879
36882
 
36880
- if (ret === constants.ERROR.PAUSED_UPGRADE) {
36881
- this.onUpgrade(data.slice(offset))
36882
- } else if (ret === constants.ERROR.PAUSED) {
36883
- this.paused = true
36884
- socket.unshift(data.slice(offset))
36885
- } else if (ret !== constants.ERROR.OK) {
36886
- const ptr = llhttp.llhttp_get_error_reason(this.ptr)
36887
- let message = ''
36888
- /* istanbul ignore else: difficult to make a test case for */
36889
- if (ptr) {
36890
- const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
36891
- message =
36892
- 'Response does not match the HTTP/1.1 protocol (' +
36893
- Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
36894
- ')'
36895
- }
36896
- throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset))
36883
+ if (ret !== constants.ERROR.OK) {
36884
+ const body = data.subarray(offset)
36885
+
36886
+ if (ret === constants.ERROR.PAUSED_UPGRADE) {
36887
+ this.onUpgrade(body)
36888
+ } else if (ret === constants.ERROR.PAUSED) {
36889
+ this.paused = true
36890
+ socket.unshift(body)
36891
+ } else {
36892
+ throw this.createError(ret, body)
36893
+ }
36897
36894
  }
36898
36895
  } catch (err) {
36899
36896
  util.destroy(socket, err)
36900
36897
  }
36901
36898
  }
36902
36899
 
36900
+ finish () {
36901
+ assert(currentParser === null)
36902
+ assert(this.ptr != null)
36903
+ assert(!this.paused)
36904
+
36905
+ const { llhttp } = this
36906
+
36907
+ let ret
36908
+
36909
+ try {
36910
+ currentParser = this
36911
+ ret = llhttp.llhttp_finish(this.ptr)
36912
+ } finally {
36913
+ currentParser = null
36914
+ }
36915
+
36916
+ if (ret === constants.ERROR.OK) {
36917
+ return null
36918
+ }
36919
+
36920
+ if (ret === constants.ERROR.PAUSED || ret === constants.ERROR.PAUSED_UPGRADE) {
36921
+ this.paused = true
36922
+ return null
36923
+ }
36924
+
36925
+ return this.createError(ret, EMPTY_BUF)
36926
+ }
36927
+
36928
+ createError (ret, data) {
36929
+ const { llhttp, contentLength, bytesRead } = this
36930
+
36931
+ if (contentLength && bytesRead !== parseInt(contentLength, 10)) {
36932
+ return new ResponseContentLengthMismatchError()
36933
+ }
36934
+
36935
+ const ptr = llhttp.llhttp_get_error_reason(this.ptr)
36936
+ let message = ''
36937
+ if (ptr) {
36938
+ const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
36939
+ message =
36940
+ 'Response does not match the HTTP/1.1 protocol (' +
36941
+ Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
36942
+ ')'
36943
+ }
36944
+
36945
+ return new HTTPParserError(message, constants.ERROR[ret], data)
36946
+ }
36947
+
36903
36948
  destroy () {
36904
36949
  assert(this.ptr != null)
36905
36950
  assert(currentParser == null)
@@ -36927,6 +36972,11 @@ class Parser {
36927
36972
  return -1
36928
36973
  }
36929
36974
 
36975
+ if (client[kRunning] === 0) {
36976
+ util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
36977
+ return -1
36978
+ }
36979
+
36930
36980
  const request = client[kQueue][client[kRunningIdx]]
36931
36981
  if (!request) {
36932
36982
  return -1
@@ -37030,6 +37080,11 @@ class Parser {
37030
37080
  return -1
37031
37081
  }
37032
37082
 
37083
+ if (client[kRunning] === 0) {
37084
+ util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
37085
+ return -1
37086
+ }
37087
+
37033
37088
  const request = client[kQueue][client[kRunningIdx]]
37034
37089
 
37035
37090
  /* istanbul ignore next: difficult to make a test case for */
@@ -37203,6 +37258,7 @@ class Parser {
37203
37258
  request.onComplete(headers)
37204
37259
 
37205
37260
  client[kQueue][client[kRunningIdx]++] = null
37261
+ socket[kSocketUsed] = true
37206
37262
 
37207
37263
  if (socket[kWriting]) {
37208
37264
  assert(client[kRunning] === 0)
@@ -37261,6 +37317,9 @@ async function connectH1 (client, socket) {
37261
37317
  socket[kWriting] = false
37262
37318
  socket[kReset] = false
37263
37319
  socket[kBlocking] = false
37320
+ socket[kIdleSocketValidation] = 0
37321
+ socket[kIdleSocketValidationTimeout] = null
37322
+ socket[kSocketUsed] = false
37264
37323
  socket[kParser] = new Parser(client, socket, llhttpInstance)
37265
37324
 
37266
37325
  addListener(socket, 'error', function (err) {
@@ -37271,8 +37330,11 @@ async function connectH1 (client, socket) {
37271
37330
  // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
37272
37331
  // to the user.
37273
37332
  if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) {
37274
- // We treat all incoming data so for as a valid response.
37275
- parser.onMessageComplete()
37333
+ const parserErr = parser.finish()
37334
+ if (parserErr) {
37335
+ this[kError] = parserErr
37336
+ this[kClient][kOnError](parserErr)
37337
+ }
37276
37338
  return
37277
37339
  }
37278
37340
 
@@ -37291,8 +37353,10 @@ async function connectH1 (client, socket) {
37291
37353
  const parser = this[kParser]
37292
37354
 
37293
37355
  if (parser.statusCode && !parser.shouldKeepAlive) {
37294
- // We treat all incoming data so far as a valid response.
37295
- parser.onMessageComplete()
37356
+ const parserErr = parser.finish()
37357
+ if (parserErr) {
37358
+ util.destroy(this, parserErr)
37359
+ }
37296
37360
  return
37297
37361
  }
37298
37362
 
@@ -37302,10 +37366,11 @@ async function connectH1 (client, socket) {
37302
37366
  const client = this[kClient]
37303
37367
  const parser = this[kParser]
37304
37368
 
37369
+ clearIdleSocketValidation(this)
37370
+
37305
37371
  if (parser) {
37306
37372
  if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) {
37307
- // We treat all incoming data so far as a valid response.
37308
- parser.onMessageComplete()
37373
+ this[kError] = parser.finish() || this[kError]
37309
37374
  }
37310
37375
 
37311
37376
  this[kParser].destroy()
@@ -37368,7 +37433,7 @@ async function connectH1 (client, socket) {
37368
37433
  return socket.destroyed
37369
37434
  },
37370
37435
  busy (request) {
37371
- if (socket[kWriting] || socket[kReset] || socket[kBlocking]) {
37436
+ if (socket[kWriting] || socket[kReset] || socket[kBlocking] || socket[kIdleSocketValidation] === 1) {
37372
37437
  return true
37373
37438
  }
37374
37439
 
@@ -37406,6 +37471,31 @@ async function connectH1 (client, socket) {
37406
37471
  }
37407
37472
  }
37408
37473
 
37474
+ function clearIdleSocketValidation (socket) {
37475
+ if (socket[kIdleSocketValidationTimeout]) {
37476
+ clearTimeout(socket[kIdleSocketValidationTimeout])
37477
+ socket[kIdleSocketValidationTimeout] = null
37478
+ }
37479
+
37480
+ socket[kIdleSocketValidation] = 0
37481
+ }
37482
+
37483
+ function scheduleIdleSocketValidation (client, socket) {
37484
+ socket[kIdleSocketValidation] = 1
37485
+ socket[kIdleSocketValidationTimeout] = setTimeout(() => {
37486
+ socket[kIdleSocketValidationTimeout] = null
37487
+ socket[kIdleSocketValidation] = 2
37488
+
37489
+ if (client[kSocket] === socket && !socket.destroyed) {
37490
+ client[kResume]()
37491
+ }
37492
+ }, 0)
37493
+ socket[kIdleSocketValidationTimeout].unref?.()
37494
+ }
37495
+
37496
+ /**
37497
+ * @param {import('./client.js')} client
37498
+ */
37409
37499
  function resumeH1 (client) {
37410
37500
  const socket = client[kSocket]
37411
37501
 
@@ -37420,6 +37510,32 @@ function resumeH1 (client) {
37420
37510
  socket[kNoRef] = false
37421
37511
  }
37422
37512
 
37513
+ if (client[kRunning] === 0 && client[kPending] > 0 && socket[kSocketUsed]) {
37514
+ if (socket[kIdleSocketValidation] === 0) {
37515
+ scheduleIdleSocketValidation(client, socket)
37516
+ socket[kParser].readMore()
37517
+ if (socket.destroyed) {
37518
+ return
37519
+ }
37520
+ return
37521
+ }
37522
+
37523
+ if (socket[kIdleSocketValidation] === 1) {
37524
+ socket[kParser].readMore()
37525
+ if (socket.destroyed) {
37526
+ return
37527
+ }
37528
+ return
37529
+ }
37530
+ }
37531
+
37532
+ if (client[kRunning] === 0) {
37533
+ socket[kParser].readMore()
37534
+ if (socket.destroyed) {
37535
+ return
37536
+ }
37537
+ }
37538
+
37423
37539
  if (client[kSize] === 0) {
37424
37540
  if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) {
37425
37541
  socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE)
@@ -37513,6 +37629,7 @@ function writeH1 (client, request) {
37513
37629
  }
37514
37630
 
37515
37631
  const socket = client[kSocket]
37632
+ clearIdleSocketValidation(socket)
37516
37633
 
37517
37634
  const abort = (err) => {
37518
37635
  if (request.aborted || request.completed) {
@@ -38834,9 +38951,10 @@ class Client extends DispatcherBase {
38834
38951
  autoSelectFamilyAttemptTimeout,
38835
38952
  // h2
38836
38953
  maxConcurrentStreams,
38837
- allowH2
38954
+ allowH2,
38955
+ webSocket
38838
38956
  } = {}) {
38839
- super()
38957
+ super({ webSocket })
38840
38958
 
38841
38959
  if (keepAlive !== undefined) {
38842
38960
  throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead')
@@ -39369,15 +39487,24 @@ const { kDestroy, kClose, kClosed, kDestroyed, kDispatch, kInterceptors } = __nc
39369
39487
  const kOnDestroyed = Symbol('onDestroyed')
39370
39488
  const kOnClosed = Symbol('onClosed')
39371
39489
  const kInterceptedDispatch = Symbol('Intercepted Dispatch')
39490
+ const kWebSocketOptions = Symbol('webSocketOptions')
39372
39491
 
39373
39492
  class DispatcherBase extends Dispatcher {
39374
- constructor () {
39493
+ constructor (opts) {
39375
39494
  super()
39376
39495
 
39377
39496
  this[kDestroyed] = false
39378
39497
  this[kOnDestroyed] = null
39379
39498
  this[kClosed] = false
39380
39499
  this[kOnClosed] = []
39500
+ this[kWebSocketOptions] = opts?.webSocket ?? {}
39501
+ }
39502
+
39503
+ get webSocketOptions () {
39504
+ return {
39505
+ maxFragments: this[kWebSocketOptions].maxFragments ?? 131072,
39506
+ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024
39507
+ }
39381
39508
  }
39382
39509
 
39383
39510
  get destroyed () {
@@ -39941,8 +40068,8 @@ const kRemoveClient = Symbol('remove client')
39941
40068
  const kStats = Symbol('stats')
39942
40069
 
39943
40070
  class PoolBase extends DispatcherBase {
39944
- constructor () {
39945
- super()
40071
+ constructor (opts) {
40072
+ super(opts)
39946
40073
 
39947
40074
  this[kQueue] = new FixedQueue()
39948
40075
  this[kClients] = []
@@ -40202,8 +40329,6 @@ class Pool extends PoolBase {
40202
40329
  allowH2,
40203
40330
  ...options
40204
40331
  } = {}) {
40205
- super()
40206
-
40207
40332
  if (connections != null && (!Number.isFinite(connections) || connections < 0)) {
40208
40333
  throw new InvalidArgumentError('invalid connections')
40209
40334
  }
@@ -40228,6 +40353,8 @@ class Pool extends PoolBase {
40228
40353
  })
40229
40354
  }
40230
40355
 
40356
+ super(options)
40357
+
40231
40358
  this[kInterceptors] = options.interceptors?.Pool && Array.isArray(options.interceptors.Pool)
40232
40359
  ? options.interceptors.Pool
40233
40360
  : []
@@ -45312,32 +45439,25 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
45312
45439
  // If the attribute-name case-insensitively matches the string
45313
45440
  // "SameSite", the user agent MUST process the cookie-av as follows:
45314
45441
 
45315
- // 1. Let enforcement be "Default".
45316
- let enforcement = 'Default'
45317
-
45318
45442
  const attributeValueLowercase = attributeValue.toLowerCase()
45319
- // 2. If cookie-av's attribute-value is a case-insensitive match for
45320
- // "None", set enforcement to "None".
45321
- if (attributeValueLowercase.includes('none')) {
45322
- enforcement = 'None'
45323
- }
45324
-
45325
- // 3. If cookie-av's attribute-value is a case-insensitive match for
45326
- // "Strict", set enforcement to "Strict".
45327
- if (attributeValueLowercase.includes('strict')) {
45328
- enforcement = 'Strict'
45329
- }
45330
45443
 
45331
- // 4. If cookie-av's attribute-value is a case-insensitive match for
45332
- // "Lax", set enforcement to "Lax".
45333
- if (attributeValueLowercase.includes('lax')) {
45334
- enforcement = 'Lax'
45444
+ // 1. If cookie-av's attribute-value is a case-insensitive match for
45445
+ // "None", append an attribute to the cookie-attribute-list with an
45446
+ // attribute-name of "SameSite" and an attribute-value of "None".
45447
+ if (attributeValueLowercase === 'none') {
45448
+ cookieAttributeList.sameSite = 'None'
45449
+ } else if (attributeValueLowercase === 'strict') {
45450
+ // 2. If cookie-av's attribute-value is a case-insensitive match for
45451
+ // "Strict", append an attribute to the cookie-attribute-list with
45452
+ // an attribute-name of "SameSite" and an attribute-value of
45453
+ // "Strict".
45454
+ cookieAttributeList.sameSite = 'Strict'
45455
+ } else if (attributeValueLowercase === 'lax') {
45456
+ // 3. If cookie-av's attribute-value is a case-insensitive match for
45457
+ // "Lax", append an attribute to the cookie-attribute-list with an
45458
+ // attribute-name of "SameSite" and an attribute-value of "Lax".
45459
+ cookieAttributeList.sameSite = 'Lax'
45335
45460
  }
45336
-
45337
- // 5. Append an attribute to the cookie-attribute-list with an
45338
- // attribute-name of "SameSite" and an attribute-value of
45339
- // enforcement.
45340
- cookieAttributeList.sameSite = enforcement
45341
45461
  } else {
45342
45462
  cookieAttributeList.unparsed ??= []
45343
45463
 
@@ -58043,45 +58163,35 @@ const tail = Buffer.from([0x00, 0x00, 0xff, 0xff])
58043
58163
  const kBuffer = Symbol('kBuffer')
58044
58164
  const kLength = Symbol('kLength')
58045
58165
 
58046
- // Default maximum decompressed message size: 4 MB
58047
- const kDefaultMaxDecompressedSize = 4 * 1024 * 1024
58048
-
58049
58166
  class PerMessageDeflate {
58050
58167
  /** @type {import('node:zlib').InflateRaw} */
58051
58168
  #inflate
58052
58169
 
58053
58170
  #options = {}
58054
58171
 
58055
- /** @type {number} */
58056
- #maxDecompressedSize
58057
-
58058
- /** @type {boolean} */
58059
- #aborted = false
58060
-
58061
- /** @type {Function|null} */
58062
- #currentCallback = null
58172
+ #maxPayloadSize = 0
58063
58173
 
58064
58174
  /**
58065
58175
  * @param {Map<string, string>} extensions
58066
- * @param {{ maxDecompressedMessageSize?: number }} [options]
58067
58176
  */
58068
- constructor (extensions, options = {}) {
58177
+ constructor (extensions, options) {
58069
58178
  this.#options.serverNoContextTakeover = extensions.has('server_no_context_takeover')
58070
58179
  this.#options.serverMaxWindowBits = extensions.get('server_max_window_bits')
58071
- this.#maxDecompressedSize = options.maxDecompressedMessageSize ?? kDefaultMaxDecompressedSize
58180
+
58181
+ this.#maxPayloadSize = options.maxPayloadSize
58072
58182
  }
58073
58183
 
58184
+ /**
58185
+ * Decompress a compressed payload.
58186
+ * @param {Buffer} chunk Compressed data
58187
+ * @param {boolean} fin Final fragment flag
58188
+ * @param {Function} callback Callback function
58189
+ */
58074
58190
  decompress (chunk, fin, callback) {
58075
58191
  // An endpoint uses the following algorithm to decompress a message.
58076
58192
  // 1. Append 4 octets of 0x00 0x00 0xff 0xff to the tail end of the
58077
58193
  // payload of the message.
58078
58194
  // 2. Decompress the resulting data using DEFLATE.
58079
-
58080
- if (this.#aborted) {
58081
- callback(new MessageSizeExceededError())
58082
- return
58083
- }
58084
-
58085
58195
  if (!this.#inflate) {
58086
58196
  let windowBits = Z_DEFAULT_WINDOWBITS
58087
58197
 
@@ -58104,23 +58214,12 @@ class PerMessageDeflate {
58104
58214
  this.#inflate[kLength] = 0
58105
58215
 
58106
58216
  this.#inflate.on('data', (data) => {
58107
- if (this.#aborted) {
58108
- return
58109
- }
58110
-
58111
58217
  this.#inflate[kLength] += data.length
58112
58218
 
58113
- if (this.#inflate[kLength] > this.#maxDecompressedSize) {
58114
- this.#aborted = true
58219
+ if (this.#maxPayloadSize > 0 && this.#inflate[kLength] > this.#maxPayloadSize) {
58220
+ callback(new MessageSizeExceededError())
58115
58221
  this.#inflate.removeAllListeners()
58116
- this.#inflate.destroy()
58117
58222
  this.#inflate = null
58118
-
58119
- if (this.#currentCallback) {
58120
- const cb = this.#currentCallback
58121
- this.#currentCallback = null
58122
- cb(new MessageSizeExceededError())
58123
- }
58124
58223
  return
58125
58224
  }
58126
58225
 
@@ -58133,14 +58232,13 @@ class PerMessageDeflate {
58133
58232
  })
58134
58233
  }
58135
58234
 
58136
- this.#currentCallback = callback
58137
58235
  this.#inflate.write(chunk)
58138
58236
  if (fin) {
58139
58237
  this.#inflate.write(tail)
58140
58238
  }
58141
58239
 
58142
58240
  this.#inflate.flush(() => {
58143
- if (this.#aborted || !this.#inflate) {
58241
+ if (!this.#inflate) {
58144
58242
  return
58145
58243
  }
58146
58244
 
@@ -58148,7 +58246,6 @@ class PerMessageDeflate {
58148
58246
 
58149
58247
  this.#inflate[kBuffer].length = 0
58150
58248
  this.#inflate[kLength] = 0
58151
- this.#currentCallback = null
58152
58249
 
58153
58250
  callback(null, full)
58154
58251
  })
@@ -58184,6 +58281,12 @@ const {
58184
58281
  const { WebsocketFrameSend } = __nccwpck_require__(3264)
58185
58282
  const { closeWebSocketConnection } = __nccwpck_require__(86897)
58186
58283
  const { PerMessageDeflate } = __nccwpck_require__(19469)
58284
+ const { MessageSizeExceededError } = __nccwpck_require__(68707)
58285
+
58286
+ function failWebsocketConnectionWithCode (ws, code, reason) {
58287
+ closeWebSocketConnection(ws, code, reason, Buffer.byteLength(reason))
58288
+ failWebsocketConnection(ws, reason)
58289
+ }
58187
58290
 
58188
58291
  // This code was influenced by ws released under the MIT license.
58189
58292
  // Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>
@@ -58192,6 +58295,7 @@ const { PerMessageDeflate } = __nccwpck_require__(19469)
58192
58295
 
58193
58296
  class ByteParser extends Writable {
58194
58297
  #buffers = []
58298
+ #fragmentsBytes = 0
58195
58299
  #byteOffset = 0
58196
58300
  #loop = false
58197
58301
 
@@ -58203,20 +58307,24 @@ class ByteParser extends Writable {
58203
58307
  /** @type {Map<string, PerMessageDeflate>} */
58204
58308
  #extensions
58205
58309
 
58206
- /** @type {{ maxDecompressedMessageSize?: number }} */
58207
- #options
58310
+ /** @type {number} */
58311
+ #maxFragments
58312
+
58313
+ /** @type {number} */
58314
+ #maxPayloadSize
58208
58315
 
58209
58316
  /**
58210
58317
  * @param {import('./websocket').WebSocket} ws
58211
58318
  * @param {Map<string, string>|null} extensions
58212
- * @param {{ maxDecompressedMessageSize?: number }} [options]
58319
+ * @param {{ maxFragments?: number, maxPayloadSize?: number }} [options]
58213
58320
  */
58214
58321
  constructor (ws, extensions, options = {}) {
58215
58322
  super()
58216
58323
 
58217
58324
  this.ws = ws
58218
58325
  this.#extensions = extensions == null ? new Map() : extensions
58219
- this.#options = options
58326
+ this.#maxFragments = options.maxFragments ?? 0
58327
+ this.#maxPayloadSize = options.maxPayloadSize ?? 0
58220
58328
 
58221
58329
  if (this.#extensions.has('permessage-deflate')) {
58222
58330
  this.#extensions.set('permessage-deflate', new PerMessageDeflate(extensions, options))
@@ -58235,6 +58343,19 @@ class ByteParser extends Writable {
58235
58343
  this.run(callback)
58236
58344
  }
58237
58345
 
58346
+ #validatePayloadLength () {
58347
+ if (
58348
+ this.#maxPayloadSize > 0 &&
58349
+ !isControlFrame(this.#info.opcode) &&
58350
+ this.#info.payloadLength + this.#fragmentsBytes > this.#maxPayloadSize
58351
+ ) {
58352
+ failWebsocketConnectionWithCode(this.ws, 1009, 'Payload size exceeds maximum allowed size')
58353
+ return false
58354
+ }
58355
+
58356
+ return true
58357
+ }
58358
+
58238
58359
  /**
58239
58360
  * Runs whenever a new chunk is received.
58240
58361
  * Callback is called whenever there are no more chunks buffering,
@@ -58323,6 +58444,10 @@ class ByteParser extends Writable {
58323
58444
  if (payloadLength <= 125) {
58324
58445
  this.#info.payloadLength = payloadLength
58325
58446
  this.#state = parserStates.READ_DATA
58447
+
58448
+ if (!this.#validatePayloadLength()) {
58449
+ return
58450
+ }
58326
58451
  } else if (payloadLength === 126) {
58327
58452
  this.#state = parserStates.PAYLOADLENGTH_16
58328
58453
  } else if (payloadLength === 127) {
@@ -58347,6 +58472,10 @@ class ByteParser extends Writable {
58347
58472
 
58348
58473
  this.#info.payloadLength = buffer.readUInt16BE(0)
58349
58474
  this.#state = parserStates.READ_DATA
58475
+
58476
+ if (!this.#validatePayloadLength()) {
58477
+ return
58478
+ }
58350
58479
  } else if (this.#state === parserStates.PAYLOADLENGTH_64) {
58351
58480
  if (this.#byteOffset < 8) {
58352
58481
  return callback()
@@ -58369,6 +58498,10 @@ class ByteParser extends Writable {
58369
58498
 
58370
58499
  this.#info.payloadLength = lower
58371
58500
  this.#state = parserStates.READ_DATA
58501
+
58502
+ if (!this.#validatePayloadLength()) {
58503
+ return
58504
+ }
58372
58505
  } else if (this.#state === parserStates.READ_DATA) {
58373
58506
  if (this.#byteOffset < this.#info.payloadLength) {
58374
58507
  return callback()
@@ -58381,42 +58514,58 @@ class ByteParser extends Writable {
58381
58514
  this.#state = parserStates.INFO
58382
58515
  } else {
58383
58516
  if (!this.#info.compressed) {
58384
- this.#fragments.push(body)
58517
+ if (!this.writeFragments(body)) {
58518
+ return
58519
+ }
58520
+
58521
+ if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
58522
+ failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message)
58523
+ return
58524
+ }
58385
58525
 
58386
58526
  // If the frame is not fragmented, a message has been received.
58387
58527
  // If the frame is fragmented, it will terminate with a fin bit set
58388
58528
  // and an opcode of 0 (continuation), therefore we handle that when
58389
58529
  // parsing continuation frames, not here.
58390
58530
  if (!this.#info.fragmented && this.#info.fin) {
58391
- const fullMessage = Buffer.concat(this.#fragments)
58392
- websocketMessageReceived(this.ws, this.#info.binaryType, fullMessage)
58393
- this.#fragments.length = 0
58531
+ websocketMessageReceived(this.ws, this.#info.binaryType, this.consumeFragments())
58394
58532
  }
58395
58533
 
58396
58534
  this.#state = parserStates.INFO
58397
58535
  } else {
58398
- this.#extensions.get('permessage-deflate').decompress(body, this.#info.fin, (error, data) => {
58399
- if (error) {
58400
- failWebsocketConnection(this.ws, error.message)
58401
- return
58402
- }
58536
+ this.#extensions.get('permessage-deflate').decompress(
58537
+ body,
58538
+ this.#info.fin,
58539
+ (error, data) => {
58540
+ if (error) {
58541
+ const code = error instanceof MessageSizeExceededError ? 1009 : 1007
58542
+ failWebsocketConnectionWithCode(this.ws, code, error.message)
58543
+ return
58544
+ }
58403
58545
 
58404
- this.#fragments.push(data)
58546
+ if (!this.writeFragments(data)) {
58547
+ return
58548
+ }
58549
+
58550
+ if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
58551
+ failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message)
58552
+ return
58553
+ }
58554
+
58555
+ if (!this.#info.fin) {
58556
+ this.#state = parserStates.INFO
58557
+ this.#loop = true
58558
+ this.run(callback)
58559
+ return
58560
+ }
58561
+
58562
+ websocketMessageReceived(this.ws, this.#info.binaryType, this.consumeFragments())
58405
58563
 
58406
- if (!this.#info.fin) {
58407
- this.#state = parserStates.INFO
58408
58564
  this.#loop = true
58565
+ this.#state = parserStates.INFO
58409
58566
  this.run(callback)
58410
- return
58411
58567
  }
58412
-
58413
- websocketMessageReceived(this.ws, this.#info.binaryType, Buffer.concat(this.#fragments))
58414
-
58415
- this.#loop = true
58416
- this.#state = parserStates.INFO
58417
- this.#fragments.length = 0
58418
- this.run(callback)
58419
- })
58568
+ )
58420
58569
 
58421
58570
  this.#loop = false
58422
58571
  break
@@ -58468,6 +58617,35 @@ class ByteParser extends Writable {
58468
58617
  return buffer
58469
58618
  }
58470
58619
 
58620
+ writeFragments (fragment) {
58621
+ if (
58622
+ this.#maxFragments > 0 &&
58623
+ this.#fragments.length === this.#maxFragments
58624
+ ) {
58625
+ failWebsocketConnectionWithCode(this.ws, 1008, 'Too many message fragments')
58626
+ return false
58627
+ }
58628
+
58629
+ this.#fragmentsBytes += fragment.length
58630
+ this.#fragments.push(fragment)
58631
+ return true
58632
+ }
58633
+
58634
+ consumeFragments () {
58635
+ const fragments = this.#fragments
58636
+
58637
+ if (fragments.length === 1) {
58638
+ this.#fragmentsBytes = 0
58639
+ return fragments.shift()
58640
+ }
58641
+
58642
+ const output = Buffer.concat(fragments, this.#fragmentsBytes)
58643
+ this.#fragments = []
58644
+ this.#fragmentsBytes = 0
58645
+
58646
+ return output
58647
+ }
58648
+
58471
58649
  parseCloseBody (data) {
58472
58650
  assert(data.length !== 1)
58473
58651
 
@@ -59112,9 +59290,6 @@ class WebSocket extends EventTarget {
59112
59290
  /** @type {SendQueue} */
59113
59291
  #sendQueue
59114
59292
 
59115
- /** @type {{ maxDecompressedMessageSize?: number }} */
59116
- #options
59117
-
59118
59293
  /**
59119
59294
  * @param {string} url
59120
59295
  * @param {string|string[]} protocols
@@ -59188,11 +59363,6 @@ class WebSocket extends EventTarget {
59188
59363
  // 10. Set this's url to urlRecord.
59189
59364
  this[kWebSocketURL] = new URL(urlRecord.href)
59190
59365
 
59191
- // Store options for later use (e.g., maxDecompressedMessageSize)
59192
- this.#options = {
59193
- maxDecompressedMessageSize: options.maxDecompressedMessageSize
59194
- }
59195
-
59196
59366
  // 11. Let client be this's relevant settings object.
59197
59367
  const client = environmentSettingsObject.settingsObject
59198
59368
 
@@ -59511,7 +59681,14 @@ class WebSocket extends EventTarget {
59511
59681
  // once this happens, the connection is open
59512
59682
  this[kResponse] = response
59513
59683
 
59514
- const parser = new ByteParser(this, parsedExtensions, this.#options)
59684
+ const webSocketOptions = this[kController]?.dispatcher?.webSocketOptions
59685
+ const maxFragments = webSocketOptions?.maxFragments
59686
+ const maxPayloadSize = webSocketOptions?.maxPayloadSize
59687
+
59688
+ const parser = new ByteParser(this, parsedExtensions, {
59689
+ maxFragments,
59690
+ maxPayloadSize
59691
+ })
59515
59692
  parser.on('drain', onParserDrain)
59516
59693
  parser.on('error', onParserError.bind(this))
59517
59694
 
@@ -59614,19 +59791,6 @@ webidl.converters.WebSocketInit = webidl.dictionaryConverter([
59614
59791
  {
59615
59792
  key: 'headers',
59616
59793
  converter: webidl.nullableConverter(webidl.converters.HeadersInit)
59617
- },
59618
- {
59619
- key: 'maxDecompressedMessageSize',
59620
- converter: webidl.nullableConverter((V) => {
59621
- V = webidl.converters['unsigned long long'](V)
59622
- if (V <= 0) {
59623
- throw webidl.errors.exception({
59624
- header: 'WebSocket constructor',
59625
- message: 'maxDecompressedMessageSize must be greater than 0'
59626
- })
59627
- }
59628
- return V
59629
- })
59630
59794
  }
59631
59795
  ])
59632
59796
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cypress/github-action",
3
- "version": "7.3.0",
3
+ "version": "7.4.1",
4
4
  "description": "GitHub Action for running Cypress end-to-end and component tests",
5
5
  "private": false,
6
6
  "main": "dist/index.js",
@@ -56,13 +56,13 @@
56
56
  "@eslint/js": "10.0.1",
57
57
  "@stylistic/eslint-plugin": "5.10.0",
58
58
  "@types/node": "25.4.0",
59
- "@vercel/ncc": "0.38.4",
60
- "eslint": "10.3.0",
61
- "eslint-plugin-cypress": "6.4.0",
59
+ "@vercel/ncc": "0.44.0",
60
+ "eslint": "10.4.0",
61
+ "eslint-plugin-cypress": "6.4.1",
62
62
  "globals": "17.6.0",
63
63
  "husky": "9.1.7",
64
64
  "markdown-link-check": "3.14.2",
65
- "prettier": "3.8.3"
65
+ "prettier": "3.8.4"
66
66
  },
67
67
  "publishConfig": {
68
68
  "access": "public"