Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions .github/workflows/nodejs-16.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,25 @@ name: Node.js 16 CI

on:
push:
branches: [ master ]
branches: [master]
pull_request:
branches: [ master ]
branches: [master]

jobs:
build:

test:
runs-on: ubuntu-latest
concurrency:
group: typecheck-${{ github.workflow }}-#${{ github.event.pull_request.number || github.head_ref || github.ref }}
cancel-in-progress: true

steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '16.x'
node-version: 16
- run: npm install
- run: npm run ci
- run: npm run prepublishOnly
- run: node -v
- run: npm run test-node16
- run: npm run test-node16
88 changes: 78 additions & 10 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,85 @@ name: CI

on:
push:
branches: [ master ]
branches: [master]
pull_request:
branches: [ master ]
branches: [master]
merge_group:

jobs:
Job:
name: Node.js
uses: node-modules/github-actions/.github/workflows/node-test.yml@master
with:
os: 'ubuntu-latest, macos-latest, windows-latest'
version: '16, 18, 20, 22, 24'
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
typecheck:
runs-on: ubuntu-latest
concurrency:
group: typecheck-${{ github.workflow }}-#${{ github.event.pull_request.number || github.head_ref || github.ref }}
cancel-in-progress: true
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4

- name: Set up Node.js
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6
with:
node-version: '24'
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Run lint
run: pnpm run lint

- name: Check dedupe
run: pnpm dedupe --check

- name: Run typecheck
run: pnpm run typecheck

- name: Run format check
run: pnpm run fmtcheck

- name: Run build
run: pnpm run build

test:
strategy:
fail-fast: false
matrix:
os: ['ubuntu-latest', 'macos-latest', 'windows-latest']
node: ['18', '20', '22', '24']

name: Test (${{ matrix.os }}, ${{ matrix.node }})
runs-on: ${{ matrix.os }}

concurrency:
group: test-${{ github.workflow }}-#${{ github.event.pull_request.number || github.head_ref || github.ref }}-(${{ matrix.os }}, ${{ matrix.node }})
cancel-in-progress: true

permissions:
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4

- name: Set up Node.js
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6
with:
node-version: ${{ matrix.node }}
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Run tests
run: pnpm run ci

- name: Code Coverage
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5
with:
use_oidc: true
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Release

on:
push:
branches: [ master ]
branches: [master]

jobs:
release:
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,3 @@ test/fixtures/ts-esm/*.js
.eslintcache
.tshy*
.idea/
pnpm-lock.yaml
18 changes: 18 additions & 0 deletions .oxfmtrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"printWidth": 120,
"singleQuote": true,
"ignorePatterns": ["CHANGELOG.md", "pnpm-lock.yaml"],
"experimentalSortImports": {
"groups": [
["type-import"],
["type-builtin", "value-builtin"],
["type-external", "value-external", "type-internal", "value-internal"],
["type-parent", "type-sibling", "type-index", "value-parent", "value-sibling", "value-index"],
["ts-equals-import"],
["unknown"]
],
"newlinesBetween": true,
"order": "asc"
}
}
6 changes: 2 additions & 4 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
"env": {
"node": true
},
"extends": [
"./node_modules/@eggjs/oxlint-config/.oxlintrc.json"
],
"extends": ["./node_modules/@eggjs/oxlint-config/.oxlintrc.json"],
"categories": {
"correctness": "allow",
"suspicious": "allow",
Expand Down Expand Up @@ -126,4 +124,4 @@
"arrow-body-style": "allow",
"prefer-destructuring": "allow"
}
}
}
48 changes: 24 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,30 +56,30 @@ console.log('status: %s, body size: %d, headers: %j', res.status, data.length, r
#### Arguments

- **url** String | Object - The URL to request, either a String or a Object that return by [url.parse](https://nodejs.org/api/url.html#url_url_parse_urlstr_parsequerystring_slashesdenotehost).
- ***options*** Object - Optional
- ***method*** String - Request method, defaults to `GET`. Could be `GET`, `POST`, `DELETE` or `PUT`. Alias 'type'.
- ***data*** Object - Data to be sent. Will be stringify automatically.
- ***content*** String | [Buffer](https://nodejs.org/api/buffer.html) - Manually set the content of payload. If set, `data` will be ignored.
- ***stream*** [stream.Readable](https://nodejs.org/api/stream.html#stream_class_stream_readable) - Stream to be pipe to the remote. If set, `data` and `content` will be ignored.
- ***writeStream*** [stream.Writable](https://nodejs.org/api/stream.html#stream_class_stream_writable) - A writable stream to be piped by the response stream. Responding data will be write to this stream and `callback` will be called with `data` set `null` after finished writing.
- ***files*** {Array<ReadStream|Buffer|String> | Object | ReadStream | Buffer | String - The files will send with `multipart/form-data` format, base on `formstream`. If `method` not set, will use `POST` method by default.
- ***contentType*** String - Type of request data. Could be `json` (**Notes**: not use `application/json` here). If it's `json`, will auto set `Content-Type: application/json` header.
- ***dataType*** String - Type of response data. Could be `text` or `json`. If it's `text`, the `callback`ed `data` would be a String. If it's `json`, the `data` of callback would be a parsed JSON Object and will auto set `Accept: application/json` header. Default `callback`ed `data` would be a `Buffer`.
- ***fixJSONCtlChars*** Boolean - Fix the control characters (U+0000 through U+001F) before JSON parse response. Default is `false`.
- ***headers*** Object - Request headers.
- ***timeout*** Number | Array - Request timeout in milliseconds for connecting phase and response receiving phase. Default is `5000`. You can use `timeout: 5000` to tell urllib use same timeout on two phase or set them separately such as `timeout: [3000, 5000]`, which will set connecting timeout to 3s and response 5s.
- ***keepAliveTimeout*** `number | null` - Default is `4000`, 4 seconds - The timeout after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. See [MDN: HTTP - Headers - Keep-Alive directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive#directives) for more details.
- ***auth*** String - `username:password` used in HTTP Basic Authorization.
- ***digestAuth*** String - `username:password` used in HTTP [Digest Authorization](https://en.wikipedia.org/wiki/Digest_access_authentication).
- ***followRedirect*** Boolean - follow HTTP 3xx responses as redirects. defaults to true.
- ***maxRedirects*** Number - The maximum number of redirects to follow, defaults to 10.
- ***formatRedirectUrl*** Function - Format the redirect url by yourself. Default is `url.resolve(from, to)`.
- ***beforeRequest*** Function - Before request hook, you can change every thing here.
- ***streaming*** Boolean - lets you get the `res` object when request connected, default `false`. alias `customResponse`
- ***compressed*** Boolean - Accept `gzip, br` response content and auto decode it, default is `false`.
- ***timing*** Boolean - Enable timing or not, default is `true`.
- ***socketPath*** String | null - request a unix socket service, default is `null`.
- ***highWaterMark*** Number - default is `67108864`, 64 KiB.
- **_options_** Object - Optional
- **_method_** String - Request method, defaults to `GET`. Could be `GET`, `POST`, `DELETE` or `PUT`. Alias 'type'.
- **_data_** Object - Data to be sent. Will be stringify automatically.
- **_content_** String | [Buffer](https://nodejs.org/api/buffer.html) - Manually set the content of payload. If set, `data` will be ignored.
- **_stream_** [stream.Readable](https://nodejs.org/api/stream.html#stream_class_stream_readable) - Stream to be pipe to the remote. If set, `data` and `content` will be ignored.
- **_writeStream_** [stream.Writable](https://nodejs.org/api/stream.html#stream_class_stream_writable) - A writable stream to be piped by the response stream. Responding data will be write to this stream and `callback` will be called with `data` set `null` after finished writing.
- **_files_** {Array<ReadStream|Buffer|String> | Object | ReadStream | Buffer | String - The files will send with `multipart/form-data` format, base on `formstream`. If `method` not set, will use `POST` method by default.
- **_contentType_** String - Type of request data. Could be `json` (**Notes**: not use `application/json` here). If it's `json`, will auto set `Content-Type: application/json` header.
- **_dataType_** String - Type of response data. Could be `text` or `json`. If it's `text`, the `callback`ed `data` would be a String. If it's `json`, the `data` of callback would be a parsed JSON Object and will auto set `Accept: application/json` header. Default `callback`ed `data` would be a `Buffer`.
- **_fixJSONCtlChars_** Boolean - Fix the control characters (U+0000 through U+001F) before JSON parse response. Default is `false`.
- **_headers_** Object - Request headers.
- **_timeout_** Number | Array - Request timeout in milliseconds for connecting phase and response receiving phase. Default is `5000`. You can use `timeout: 5000` to tell urllib use same timeout on two phase or set them separately such as `timeout: [3000, 5000]`, which will set connecting timeout to 3s and response 5s.
- **_keepAliveTimeout_** `number | null` - Default is `4000`, 4 seconds - The timeout after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by _keep-alive_ hints from the server. See [MDN: HTTP - Headers - Keep-Alive directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive#directives) for more details.
- **_auth_** String - `username:password` used in HTTP Basic Authorization.
- **_digestAuth_** String - `username:password` used in HTTP [Digest Authorization](https://en.wikipedia.org/wiki/Digest_access_authentication).
- **_followRedirect_** Boolean - follow HTTP 3xx responses as redirects. defaults to true.
- **_maxRedirects_** Number - The maximum number of redirects to follow, defaults to 10.
- **_formatRedirectUrl_** Function - Format the redirect url by yourself. Default is `url.resolve(from, to)`.
- **_beforeRequest_** Function - Before request hook, you can change every thing here.
- **_streaming_** Boolean - lets you get the `res` object when request connected, default `false`. alias `customResponse`
- **_compressed_** Boolean - Accept `gzip, br` response content and auto decode it, default is `false`.
- **_timing_** Boolean - Enable timing or not, default is `true`.
- **_socketPath_** String | null - request a unix socket service, default is `null`.
- **_highWaterMark_** Number - default is `67108864`, 64 KiB.

#### Options: `options.data`

Expand Down
24 changes: 14 additions & 10 deletions examples/h2-other-side-closed-exit-0-fetch.cjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
const { fetch, setGlobalDispatcher, Agent } = require('..');

setGlobalDispatcher(new Agent({
allowH2: true,
}));
setGlobalDispatcher(
new Agent({
allowH2: true,
}),
);

async function main() {
for (let i = 0; i < 100; i++) {
Expand All @@ -21,13 +23,15 @@ async function main() {
}
}

main().then(() => {
console.log('main end');
}).catch(err => {
console.error('main error throw: %s', err);
// console.error(err);
process.exit(1);
});
main()
.then(() => {
console.log('main end');
})
.catch((err) => {
console.error('main error throw: %s', err);
// console.error(err);
process.exit(1);
});

process.on('beforeExit', (...args) => {
console.error('beforeExit', args);
Expand Down
24 changes: 14 additions & 10 deletions examples/h2-other-side-closed-exit-0.cjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
const { request, Agent, setGlobalDispatcher } = require('undici');

setGlobalDispatcher(new Agent({
allowH2: true,
}));
setGlobalDispatcher(
new Agent({
allowH2: true,
}),
);

async function main() {
for (let i = 0; i < 100; i++) {
Expand All @@ -21,13 +23,15 @@ async function main() {
}
}

main().then(() => {
console.log('main end');
}).catch(err => {
console.error('main error throw: %s', err);
// console.error(err);
process.exit(1);
});
main()
.then(() => {
console.log('main end');
})
.catch((err) => {
console.error('main error throw: %s', err);
// console.error(err);
process.exit(1);
});

process.on('beforeExit', (...args) => {
console.error('beforeExit', args);
Expand Down
11 changes: 6 additions & 5 deletions examples/httpclient.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,20 @@ function tryHttpclient(HttpClient, name) {
timing: true,
};
const urllib = new HttpClient();
urllib.on('response', function(info) {
urllib.on('response', function (info) {
// console.log(name, httpAgent, httpAgent.getCurrentStatus());
// console.log(name, httpsAgent, httpsAgent.getCurrentStatus());
console.log('response', name, info.res);
});
urllib.request('https://nodejs.org', options)
.then(function() {
urllib
.request('https://nodejs.org', options)
.then(function () {
return urllib.request('https://nodejs.org', options);
})
.then(function() {
.then(function () {
return urllib.request('https://nodejs.org/en/', options);
})
.catch(function(err) {
.catch(function (err) {
console.error('catch', err);
});
}
16 changes: 9 additions & 7 deletions examples/longruning.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ async function main() {
}
}

main().then(() => {
console.log('main end');
}).catch(err => {
console.error('main error throw: %s', err);
console.error(err);
process.exit(1);
});
main()
.then(() => {
console.log('main end');
})
.catch((err) => {
console.error('main error throw: %s', err);
console.error(err);
process.exit(1);
});

// process.on('uncaughtException', (...args) => {
// console.error('uncaughtException', args);
Expand Down
18 changes: 10 additions & 8 deletions examples/search_github.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

var urllib = require('../');

urllib.request('https://api.github.com/legacy/user/search/location:china', {
dataType: 'json',
timing: true,
timeout: 10000,
}).then(response => {
console.log(response);
console.log(response.data);
});
urllib
.request('https://api.github.com/legacy/user/search/location:china', {
dataType: 'json',
timing: true,
timeout: 10000,
})
.then((response) => {
console.log(response);
console.log(response.data);
});

// var https = require('https');

Expand Down
11 changes: 9 additions & 2 deletions examples/timing.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,15 @@ async function request(index) {
// dataType: 'json',
});
console.log('---------------------------');
console.log('No#%d: %s, content size: %d, requestUrls: %o, socket: %o, rt: %o',
index, res.statusCode, res.data.length, res.res.requestUrls, res.res.socket, res.res.rt);
console.log(
'No#%d: %s, content size: %d, requestUrls: %o, socket: %o, rt: %o',
index,
res.statusCode,
res.data.length,
res.res.requestUrls,
res.res.socket,
res.res.rt,
);
console.log(res.res.timing);
// console.log(res.res.timing, res.headers);
// console.log(res.data);
Expand Down
Loading
Loading