Skip to content

Commit 71a6d74

Browse files
committed
Merge branch 'main' of github.com:nodejs/undici
2 parents 3ac3682 + 0f0f239 commit 71a6d74

21 files changed

+254
-54
lines changed

.github/workflows/bench.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
runs-on: ubuntu-latest
1313
steps:
1414
- name: Checkout Code
15-
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
15+
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
1616
with:
1717
persist-credentials: false
1818
ref: ${{ github.base_ref }}
@@ -34,7 +34,7 @@ jobs:
3434
runs-on: ubuntu-latest
3535
steps:
3636
- name: Checkout Code
37-
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
37+
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
3838
with:
3939
persist-credentials: false
4040
- name: Setup Node
@@ -55,7 +55,7 @@ jobs:
5555
runs-on: ubuntu-latest
5656
steps:
5757
- name: Checkout Code
58-
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
58+
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
5959
with:
6060
persist-credentials: false
6161
ref: ${{ github.base_ref }}
@@ -77,7 +77,7 @@ jobs:
7777
runs-on: ubuntu-latest
7878
steps:
7979
- name: Checkout Code
80-
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
80+
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
8181
with:
8282
persist-credentials: false
8383
- name: Setup Node

.github/workflows/codeql.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
egress-policy: audit
4747

4848
- name: Checkout repository
49-
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
49+
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
5050

5151
# Initializes the CodeQL tools for scanning.
5252
- name: Initialize CodeQL

.github/workflows/fuzz.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ubuntu-latest
1212

1313
steps:
14-
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
14+
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
1515
with:
1616
persist-credentials: false
1717

.github/workflows/nightly.yml

+26-12
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,40 @@ on:
55
schedule:
66
- cron: "0 10 * * *"
77

8+
permissions:
9+
contents: read
10+
811
jobs:
9-
test:
12+
test-linux:
13+
if: github.repository == 'nodejs/undici'
14+
uses: ./.github/workflows/test.yml
15+
with:
16+
node-version: 22-nightly
17+
runs-on: ubuntu-latest
18+
secrets: inherit
19+
20+
test-windows:
21+
if: github.repository == 'nodejs/undici'
22+
uses: ./.github/workflows/test.yml
23+
with:
24+
node-version: 22-nightly
25+
runs-on: windows-latest
26+
secrets: inherit
27+
28+
test-macos:
1029
if: github.repository == 'nodejs/undici'
11-
strategy:
12-
fail-fast: false
13-
max-parallel: 0
14-
matrix:
15-
runs-on:
16-
- ubuntu-latest
17-
- windows-latest
18-
- macos-latest
1930
uses: ./.github/workflows/test.yml
2031
with:
2132
node-version: 22-nightly
22-
runs-on: ${{ matrix.runs-on }}
33+
runs-on: macos-latest
2334
secrets: inherit
2435

2536
report-failure:
26-
if: failure()
27-
needs: test
37+
if: ${{ always() && (needs.test-linux.result == 'failure' && needs.test-windows.result == 'failure' && needs.test-macos.result == 'failure') }}
38+
needs:
39+
- test-linux
40+
- test-windows
41+
- test-macos
2842
runs-on: ubuntu-latest
2943
permissions:
3044
issues: write

.github/workflows/nodejs.yml

+75-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
egress-policy: audit
2424

2525
- name: Checkout
26-
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
26+
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
2727
with:
2828
persist-credentials: false
2929

@@ -35,7 +35,7 @@ jobs:
3535
runs-on: ubuntu-latest
3636
steps:
3737
- name: Checkout
38-
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
38+
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
3939
with:
4040
persist-credentials: false
4141

@@ -69,13 +69,84 @@ jobs:
6969
runs-on: ${{ matrix.runs-on }}
7070
secrets: inherit
7171

72+
test-without-intl:
73+
name: Test with Node.js ${{ matrix.version }} compiled --without-intl
74+
strategy:
75+
fail-fast: false
76+
max-parallel: 0
77+
matrix:
78+
version: [20, 21]
79+
runs-on: ubuntu-latest
80+
timeout-minutes: 120
81+
steps:
82+
- name: Checkout
83+
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
84+
with:
85+
persist-credentials: false
86+
87+
# Setup node, install deps, and build undici prior to building icu-less node and testing
88+
- name: Setup Node.js@${{ inputs.version }}
89+
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
90+
with:
91+
node-version: ${{ inputs.version }}
92+
93+
- name: Install dependencies
94+
run: npm install
95+
96+
- name: Build undici
97+
run: npm run build:node
98+
99+
- name: Determine latest release
100+
id: release
101+
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
102+
with:
103+
result-encoding: string
104+
script: |
105+
const req = await fetch('https://nodejs.org/download/release/index.json')
106+
const releases = await req.json()
107+
108+
const latest = releases.find((r) => r.version.startsWith('v${{ matrix.version }}'))
109+
return latest.version
110+
111+
- name: Download and extract source
112+
run: curl https://nodejs.org/download/release/${{ steps.release.outputs.result }}/node-${{ steps.release.outputs.result }}.tar.xz | tar xfJ -
113+
114+
- name: Install ninja
115+
run: sudo apt-get install ninja-build
116+
117+
- name: ccache
118+
uses: hendrikmuhs/ccache-action@faf867a11c028c0b483fb2ae72b6fc8f7d842714 #v1.2.12
119+
with:
120+
key: node${{ matrix.version }}
121+
122+
- name: Build node
123+
working-directory: ./node-${{ steps.release.outputs.result }}
124+
run: |
125+
export CC="ccache gcc"
126+
export CXX="ccache g++"
127+
./configure --without-intl --ninja --prefix=./final
128+
make
129+
make install
130+
echo "$(pwd)/final/bin" >> $GITHUB_PATH
131+
132+
- name: Print version information
133+
run: |
134+
echo OS: $(node -p "os.version()")
135+
echo Node.js: $(node --version)
136+
echo npm: $(npm --version)
137+
echo git: $(git --version)
138+
echo icu config: $(node -e "console.log(process.config)" | grep icu)
139+
140+
- name: Run tests
141+
run: npm run test:javascript:withoutintl
142+
72143
test-types:
73144
name: Test TypeScript types
74145
timeout-minutes: 15
75146
runs-on: ubuntu-latest
76147
steps:
77148
- name: Checkout
78-
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
149+
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
79150
with:
80151
persist-credentials: false
81152

@@ -97,12 +168,12 @@ jobs:
97168
- dependency-review
98169
- test
99170
- test-types
171+
- test-without-intl
100172
- lint
101173
runs-on: ubuntu-latest
102174
permissions:
103175
contents: write
104176
pull-requests: write
105-
actions: write
106177
steps:
107178
- name: Merge Dependabot PR
108179
uses: fastify/github-action-merge-dependabot@9e7bfb249c69139d7bdcd8d984f9665edd49020b # v3.10.1

.github/workflows/publish-undici-types.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
publish:
1414
runs-on: ubuntu-latest
1515
steps:
16-
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
16+
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
1717
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
1818
with:
1919
node-version: lts/*

.github/workflows/scorecard.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929

3030
steps:
3131
- name: "Checkout code"
32-
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
32+
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
3333
with:
3434
persist-credentials: false
3535

.github/workflows/test.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@ on:
1010
required: true
1111
type: string
1212

13+
permissions:
14+
contents: read
15+
1316
jobs:
1417
test:
1518
name: Test with Node.js ${{ inputs.node-version }} on ${{ inputs.runs-on }}
1619
timeout-minutes: 15
1720
runs-on: ${{ inputs.runs-on }}
1821
steps:
1922
- name: Checkout
20-
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
23+
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
2124
with:
2225
persist-credentials: false
2326

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ An HTTP/1.1 client, written from scratch for Node.js.
77
> Undici means eleven in Italian. 1.1 -> 11 -> Eleven -> Undici.
88
It is also a Stranger Things reference.
99

10+
## How to get involved
11+
1012
Have a question about using Undici? Open a [Q&A Discussion](https://github.com/nodejs/undici/discussions/new) or join our official OpenJS [Slack](https://openjs-foundation.slack.com/archives/C01QF9Q31QD) channel.
1113

14+
Looking to contribute? Start by reading the [contributing guide](./CONTRIBUTING.md)
15+
1216
## Install
1317

1418
```

lib/dispatcher/client-h2.js

+12
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,18 @@ function writeH2 (client, request) {
405405
const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers
406406
request.onResponseStarted()
407407

408+
// Due to the stream nature, it is possible we face a race condition
409+
// where the stream has been assigned, but the request has been aborted
410+
// the request remains in-flight and headers hasn't been received yet
411+
// for those scenarios, best effort is to destroy the stream immediately
412+
// as there's no value to keep it open.
413+
if (request.aborted || request.completed) {
414+
const err = new RequestAbortedError()
415+
errorRequest(client, request, err)
416+
util.destroy(stream, err)
417+
return
418+
}
419+
408420
if (request.onHeaders(Number(statusCode), parseH2Headers(realHeaders), stream.resume.bind(stream), '') === false) {
409421
stream.pause()
410422
}

lib/mock/pending-interceptors-formatter.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
const { Transform } = require('node:stream')
44
const { Console } = require('node:console')
55

6+
const PERSISTENT = process.versions.icu ? '✅' : 'Y '
7+
const NOT_PERSISTENT = process.versions.icu ? '❌' : 'N '
8+
69
/**
710
* Gets the output of `console.table(…)` as a string.
811
*/
@@ -29,7 +32,7 @@ module.exports = class PendingInterceptorsFormatter {
2932
Origin: origin,
3033
Path: path,
3134
'Status code': statusCode,
32-
Persistent: persist ? '✅' : '❌',
35+
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
3336
Invocations: timesInvoked,
3437
Remaining: persist ? Infinity : times - timesInvoked
3538
}))

lib/web/fetch/data-url.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ const encoder = new TextEncoder()
88
* @see https://mimesniff.spec.whatwg.org/#http-token-code-point
99
*/
1010
const HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/
11-
const HTTP_WHITESPACE_REGEX = /[\u000A|\u000D|\u0009|\u0020]/ // eslint-disable-line
11+
const HTTP_WHITESPACE_REGEX = /[\u000A\u000D\u0009\u0020]/ // eslint-disable-line
1212
const ASCII_WHITESPACE_REPLACE_REGEX = /[\u0009\u000A\u000C\u000D\u0020]/g // eslint-disable-line
1313
/**
1414
* @see https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point
1515
*/
16-
const HTTP_QUOTED_STRING_TOKENS = /[\u0009|\u0020-\u007E|\u0080-\u00FF]/ // eslint-disable-line
16+
const HTTP_QUOTED_STRING_TOKENS = /[\u0009\u0020-\u007E\u0080-\u00FF]/ // eslint-disable-line
1717

1818
// https://fetch.spec.whatwg.org/#data-url-processor
1919
/** @param {URL} dataURL */

lib/web/fetch/headers.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const {
1212
} = require('./util')
1313
const { webidl } = require('./webidl')
1414
const assert = require('node:assert')
15-
const util = require('util')
15+
const util = require('node:util')
1616

1717
const kHeadersMap = Symbol('headers map')
1818
const kHeadersSortedMap = Symbol('headers map sorted')

package.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,13 @@
6969
"lint:fix": "standard --fix | snazzy",
7070
"test": "npm run test:javascript && cross-env NODE_V8_COVERAGE= npm run test:typescript",
7171
"test:javascript": "node scripts/generate-pem && npm run test:unit && npm run test:node-fetch && npm run test:fetch && npm run test:cookies && npm run test:eventsource && npm run test:wpt && npm run test:websocket && npm run test:node-test && npm run test:jest",
72+
"test:javascript:withoutintl": "node scripts/generate-pem && npm run test:unit && npm run test:node-fetch && npm run test:fetch:nobuild && npm run test:cookies && npm run test:eventsource:nobuild && npm run test:wpt:withoutintl && npm run test:node-test",
7273
"test:cookies": "borp -p \"test/cookie/*.js\"",
7374
"test:node-fetch": "borp -p \"test/node-fetch/**/*.js\"",
74-
"test:eventsource": "npm run build:node && borp --expose-gc -p \"test/eventsource/*.js\"",
75-
"test:fetch": "npm run build:node && borp --expose-gc -p \"test/fetch/*.js\" && borp -p \"test/webidl/*.js\" && borp -p \"test/busboy/*.js\"",
75+
"test:eventsource": "npm run build:node && npm run test:eventsource:nobuild",
76+
"test:eventsource:nobuild": "borp --expose-gc -p \"test/eventsource/*.js\"",
77+
"test:fetch": "npm run build:node && npm run test:fetch:nobuild",
78+
"test:fetch:nobuild": "borp --expose-gc -p \"test/fetch/*.js\" && borp -p \"test/webidl/*.js\" && borp -p \"test/busboy/*.js\"",
7679
"test:jest": "cross-env NODE_V8_COVERAGE= jest",
7780
"test:unit": "borp --expose-gc -p \"test/*.js\"",
7881
"test:node-test": "borp -p \"test/node-test/**/*.js\"",
@@ -81,6 +84,7 @@
8184
"test:typescript": "tsd && tsc --skipLibCheck test/imports/undici-import.ts",
8285
"test:websocket": "borp -p \"test/websocket/*.js\"",
8386
"test:wpt": "node test/wpt/start-fetch.mjs && node test/wpt/start-FileAPI.mjs && node test/wpt/start-mimesniff.mjs && node test/wpt/start-xhr.mjs && node test/wpt/start-websockets.mjs && node test/wpt/start-cacheStorage.mjs && node test/wpt/start-eventsource.mjs",
87+
"test:wpt:withoutintl": "node test/wpt/start-fetch.mjs && node test/wpt/start-mimesniff.mjs && node test/wpt/start-xhr.mjs && node test/wpt/start-cacheStorage.mjs && node test/wpt/start-eventsource.mjs",
8488
"coverage": "npm run coverage:clean && cross-env NODE_V8_COVERAGE=./coverage/tmp npm run test:javascript && npm run coverage:report",
8589
"coverage:ci": "npm run coverage:clean && cross-env NODE_V8_COVERAGE=./coverage/tmp npm run test:javascript && npm run coverage:report:ci",
8690
"coverage:clean": "node ./scripts/clean-coverage.js",

test/connect-timeout.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const assert = require('node:assert')
99
// Using describe instead of test to avoid the timeout
1010
describe('prioritize socket errors over timeouts', async () => {
1111
const t = tspl({ ...assert, after: () => {} }, { plan: 1 })
12-
const client = new Pool('http://foobar.bar:1234', { connectTimeout: 1 })
12+
const client = new Pool('http://foorbar.invalid:1234', { connectTimeout: 1 })
1313

1414
client.request({ method: 'GET', path: '/foobar' })
1515
.then(() => t.fail())

test/fetch/headers-inspect-custom.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const { Headers } = require('../../lib/web/fetch/headers')
44
const { test } = require('node:test')
55
const assert = require('node:assert')
6-
const util = require('util')
6+
const util = require('node:util')
77

88
test('Headers class custom inspection', () => {
99
const headers = new Headers()

test/fetch/request-inspect-custom.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
'use strict'
22

33
const { describe, it } = require('node:test')
4-
const assert = require('assert')
5-
const util = require('util')
4+
const assert = require('node:assert')
5+
const util = require('node:util')
66
const { Request } = require('../../')
77

88
describe('Request custom inspection', () => {

0 commit comments

Comments
 (0)