Installations
npm install urllib
Developer Guide
Typescript
Yes
Module System
ESM
Min. Node Version
>= 18.19.0
Node Version
18.20.5
NPM Version
10.8.2
Score
97.5
Supply Chain
98.5
Quality
95.2
Maintenance
100
Vulnerability
98.9
License
Releases
Contributors
Languages
TypeScript (99.08%)
JavaScript (0.92%)
Developer
node-modules
Download Statistics
Total Downloads
54,437,674
Last Day
34,960
Last Week
188,326
Last Month
951,935
Last Year
12,072,868
GitHub Statistics
732 Stars
688 Commits
124 Forks
37 Watching
11 Branches
58 Contributors
Package Meta Information
Latest Version
4.6.11
Package Id
urllib@4.6.11
Unpacked Size
410.30 kB
Size
81.61 kB
File Count
77
NPM Version
10.8.2
Node Version
18.20.5
Publised On
20 Dec 2024
Total Downloads
Cumulative downloads
Total Downloads
54,437,674
Last day
-16.2%
34,960
Compared to previous day
Last week
-20.7%
188,326
Compared to previous week
Last month
-1.8%
951,935
Compared to previous month
Last year
-25.3%
12,072,868
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dependencies
7
Dev Dependencies
24
urllib
Request HTTP URLs in a complex world — basic and digest authentication, redirections, timeout and more.
Install
1npm install urllib
Usage
TypeScript and ESM
1import { request } from 'urllib'; 2 3const { data, res } = await request('http://cnodejs.org/'); 4// result: { data: Buffer, res: Response } 5console.log('status: %s, body size: %d, headers: %j', res.status, data.length, res.headers);
CommonJS
1const { request } = require('urllib'); 2 3const { data, res } = await request('http://cnodejs.org/'); 4// result: { data: Buffer, res: Response } 5console.log('status: %s, body size: %d, headers: %j', res.status, data.length, res.headers);
API Doc
Method: async request(url[, options])
Arguments
- url String | Object - The URL to request, either a String or a Object that return by url.parse.
- options Object - Optional
- method String - Request method, defaults to
GET
. Could beGET
,POST
,DELETE
orPUT
. Alias 'type'. - data Object - Data to be sent. Will be stringify automatically.
- content String | Buffer - Manually set the content of payload. If set,
data
will be ignored. - stream stream.Readable - Stream to be pipe to the remote. If set,
data
andcontent
will be ignored. - writeStream 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 withdata
setnull
after finished writing. - files {Array<ReadStream|Buffer|String> | Object | ReadStream | Buffer | String - The files will send with
multipart/form-data
format, base onformstream
. Ifmethod
not set, will usePOST
method by default. - contentType String - Type of request data. Could be
json
(Notes: not useapplication/json
here). If it'sjson
, will auto setContent-Type: application/json
header. - dataType String - Type of response data. Could be
text
orjson
. If it'stext
, thecallback
eddata
would be a String. If it'sjson
, thedata
of callback would be a parsed JSON Object and will auto setAccept: application/json
header. Defaultcallback
eddata
would be aBuffer
. - 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 usetimeout: 5000
to tell urllib use same timeout on two phase or set them seperately such astimeout: [3000, 5000]
, which will set connecting timeout to 3s and response 5s. - keepAliveTimeout
number | null
- Default is4000
, 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 for more details. - auth String -
username:password
used in HTTP Basic Authorization. - digestAuth String -
username:password
used in HTTP Digest Authorization. - 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 your self. Default is
url.resolve(from, to)
. - beforeRequest Function - Before request hook, you can change every thing here.
- streaming Boolean - let you get the
res
object when request connected, defaultfalse
. aliascustomResponse
- compressed Boolean - Accept
gzip, br
response content and auto decode it, default isfalse
. - 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.
- method String - Request method, defaults to
Options: options.data
When making a request:
1await request('https://example.com', { 2 method: 'GET', 3 data: { 4 'a': 'hello', 5 'b': 'world', 6 }, 7});
For GET
request, data
will be stringify to query string, e.g. http://example.com/?a=hello&b=world
.
For others like POST
, PATCH
or PUT
request,
in defaults, the data
will be stringify into application/x-www-form-urlencoded
format
if content-type
header is not set.
If content-type
is application/json
, the data
will be JSON.stringify
to JSON data format.
Options: options.content
options.content
is useful when you wish to construct the request body by yourself,
for example making a content-type: application/json
request.
Notes that if you want to send a JSON body, you should stringify it yourself:
1await request('https://example.com', { 2 method: 'POST', 3 headers: { 4 'Content-Type': 'application/json', 5 }, 6 content: JSON.stringify({ 7 a: 'hello', 8 b: 'world', 9 }), 10});
It would make a HTTP request like:
1POST / HTTP/1.1 2host: example.com 3content-type: application/json 4 5{ 6 "a": "hello", 7 "b": "world" 8}
This exmaple can use options.data
with application/json
content type:
1await request('https://example.com', { 2 method: 'POST', 3 headers: { 4 'content-type': 'application/json' 5 }, 6 data: { 7 a: 'hello', 8 b: 'world', 9 } 10});
Options: options.files
Upload a file with a hello
field.
1await request('https://example.com/upload', { 2 method: 'POST', 3 files: __filename, 4 data: { 5 hello: 'hello urllib', 6 }, 7});
Upload multi files with a hello
field.
1await request('https://example.com/upload', { 2 method: 'POST', 3 files: [ 4 __filename, 5 fs.createReadStream(__filename), 6 Buffer.from('mock file content'), 7 ], 8 data: { 9 hello: 'hello urllib with multi files', 10 }, 11});
Custom file field name with uploadfile
.
1await request('https://example.com/upload', { 2 method: 'POST', 3 files: { 4 uploadfile: __filename, 5 }, 6});
Response Object
Response is normal object, it contains:
status
orstatusCode
: response status code.-1
meaning some network error likeENOTFOUND
-2
meaning ConnectionTimeoutError
headers
: response http headers, default is{}
size
: response sizeaborted
: response was aborted or notrt
: total request and response time in ms.timing
: timing object if timing enable.socket
: socket info
Run test with debug log
1NODE_DEBUG=urllib:* npm test
Request with HTTP2
Create a HttpClient with options.allowH2 = true
1import { HttpClient } from 'urllib'; 2 3const httpClient = new HttpClient({ 4 allowH2: true, 5}); 6 7const response = await httpClient.request('https://node.js.org'); 8console.log(response.status); 9console.log(response.headers);
Mocking Request
export from undici
1import { strict as assert } from 'assert'; 2import { MockAgent, setGlobalDispatcher, request } from 'urllib'; 3 4const mockAgent = new MockAgent(); 5setGlobalDispatcher(mockAgent); 6 7const mockPool = mockAgent.get('http://localhost:7001'); 8 9mockPool.intercept({ 10 path: '/foo', 11 method: 'POST', 12}).reply(400, { 13 message: 'mock 400 bad request', 14}); 15 16const response = await request('http://localhost:7001/foo', { 17 method: 'POST', 18 dataType: 'json', 19}); 20assert.equal(response.status, 400); 21assert.deepEqual(response.data, { message: 'mock 400 bad request' });
Request through a http proxy
export from undici
1import { ProxyAgent, request } from 'urllib'; 2 3const proxyAgent = new ProxyAgent('http://my.proxy.com:8080'); 4const response = await request('https://www.npmjs.com/package/urllib', { 5 dispatcher: proxyAgent, 6}); 7console.log(response.status, response.headers);
Benchmarks
undici@6.19.2
1Node.js v18.20.3 2 3┌─────────┬───────────────────────┬─────────┬────────────────────┬─────────────┬─────────────────────────┐ 4│ (index) │ Tests │ Samples │ Result │ Tolerance │ Difference with slowest │ 5├─────────┼───────────────────────┼─────────┼────────────────────┼─────────────┼─────────────────────────┤ 6│ 0 │ 'urllib2 - request' │ 10 │ '321.53 req/sec' │ '± 0.38 %' │ '-' │ 7│ 1 │ 'http - no keepalive' │ 10 │ '607.77 req/sec' │ '± 0.80 %' │ '+ 89.02 %' │ 8│ 2 │ 'got' │ 101 │ '7929.51 req/sec' │ '± 4.46 %' │ '+ 2366.15 %' │ 9│ 3 │ 'node-fetch' │ 40 │ '8651.95 req/sec' │ '± 2.99 %' │ '+ 2590.84 %' │ 10│ 4 │ 'request' │ 101 │ '8864.09 req/sec' │ '± 7.81 %' │ '+ 2656.82 %' │ 11│ 5 │ 'undici - fetch' │ 101 │ '9607.01 req/sec' │ '± 4.23 %' │ '+ 2887.87 %' │ 12│ 6 │ 'axios' │ 55 │ '10378.80 req/sec' │ '± 2.94 %' │ '+ 3127.91 %' │ 13│ 7 │ 'superagent' │ 75 │ '11286.74 req/sec' │ '± 2.90 %' │ '+ 3410.29 %' │ 14│ 8 │ 'http - keepalive' │ 60 │ '11288.96 req/sec' │ '± 2.95 %' │ '+ 3410.98 %' │ 15│ 9 │ 'urllib4 - request' │ 101 │ '11352.65 req/sec' │ '± 10.20 %' │ '+ 3430.79 %' │ 16│ 10 │ 'urllib3 - request' │ 40 │ '13831.19 req/sec' │ '± 2.89 %' │ '+ 4201.64 %' │ 17│ 11 │ 'undici - pipeline' │ 60 │ '14562.44 req/sec' │ '± 2.91 %' │ '+ 4429.06 %' │ 18│ 12 │ 'undici - request' │ 70 │ '19630.64 req/sec' │ '± 2.87 %' │ '+ 6005.32 %' │ 19│ 13 │ 'undici - stream' │ 55 │ '20843.50 req/sec' │ '± 2.90 %' │ '+ 6382.54 %' │ 20│ 14 │ 'undici - dispatch' │ 55 │ '21233.10 req/sec' │ '± 2.82 %' │ '+ 6503.70 %' │ 21└─────────┴───────────────────────┴─────────┴────────────────────┴─────────────┴─────────────────────────┘ 22 23Node.js v20.15.0 24 25┌─────────┬───────────────────────┬─────────┬────────────────────┬────────────┬─────────────────────────┐ 26│ (index) │ Tests │ Samples │ Result │ Tolerance │ Difference with slowest │ 27├─────────┼───────────────────────┼─────────┼────────────────────┼────────────┼─────────────────────────┤ 28│ 0 │ 'urllib2 - request' │ 10 │ '332.91 req/sec' │ '± 1.13 %' │ '-' │ 29│ 1 │ 'http - no keepalive' │ 10 │ '615.50 req/sec' │ '± 2.25 %' │ '+ 84.88 %' │ 30│ 2 │ 'got' │ 55 │ '7658.39 req/sec' │ '± 2.98 %' │ '+ 2200.42 %' │ 31│ 3 │ 'node-fetch' │ 30 │ '7832.96 req/sec' │ '± 2.96 %' │ '+ 2252.86 %' │ 32│ 4 │ 'axios' │ 40 │ '8607.27 req/sec' │ '± 2.79 %' │ '+ 2485.44 %' │ 33│ 5 │ 'request' │ 35 │ '8703.49 req/sec' │ '± 2.84 %' │ '+ 2514.35 %' │ 34│ 6 │ 'undici - fetch' │ 65 │ '9971.24 req/sec' │ '± 2.96 %' │ '+ 2895.15 %' │ 35│ 7 │ 'superagent' │ 30 │ '11006.46 req/sec' │ '± 2.90 %' │ '+ 3206.11 %' │ 36│ 8 │ 'http - keepalive' │ 55 │ '11610.14 req/sec' │ '± 2.87 %' │ '+ 3387.44 %' │ 37│ 9 │ 'urllib3 - request' │ 25 │ '13873.38 req/sec' │ '± 2.96 %' │ '+ 4067.27 %' │ 38│ 10 │ 'urllib4 - request' │ 25 │ '14291.36 req/sec' │ '± 2.92 %' │ '+ 4192.82 %' │ 39│ 11 │ 'undici - pipeline' │ 45 │ '14617.69 req/sec' │ '± 2.84 %' │ '+ 4290.85 %' │ 40│ 12 │ 'undici - dispatch' │ 101 │ '18716.29 req/sec' │ '± 3.97 %' │ '+ 5521.98 %' │ 41│ 13 │ 'undici - request' │ 101 │ '19165.16 req/sec' │ '± 3.25 %' │ '+ 5656.81 %' │ 42│ 14 │ 'undici - stream' │ 30 │ '21816.28 req/sec' │ '± 2.99 %' │ '+ 6453.15 %' │ 43└─────────┴───────────────────────┴─────────┴────────────────────┴────────────┴─────────────────────────┘ 44 45Node.js v22.3.0 46 47┌─────────┬───────────────────────┬─────────┬────────────────────┬────────────┬─────────────────────────┐ 48│ (index) │ Tests │ Samples │ Result │ Tolerance │ Difference with slowest │ 49├─────────┼───────────────────────┼─────────┼────────────────────┼────────────┼─────────────────────────┤ 50│ 0 │ 'urllib2 - request' │ 15 │ '297.46 req/sec' │ '± 2.65 %' │ '-' │ 51│ 1 │ 'http - no keepalive' │ 10 │ '598.25 req/sec' │ '± 1.94 %' │ '+ 101.12 %' │ 52│ 2 │ 'axios' │ 30 │ '8487.94 req/sec' │ '± 2.91 %' │ '+ 2753.52 %' │ 53│ 3 │ 'got' │ 50 │ '10054.46 req/sec' │ '± 2.89 %' │ '+ 3280.16 %' │ 54│ 4 │ 'request' │ 45 │ '10306.02 req/sec' │ '± 2.87 %' │ '+ 3364.73 %' │ 55│ 5 │ 'node-fetch' │ 55 │ '11160.02 req/sec' │ '± 2.87 %' │ '+ 3651.83 %' │ 56│ 6 │ 'superagent' │ 80 │ '11302.28 req/sec' │ '± 2.85 %' │ '+ 3699.66 %' │ 57│ 7 │ 'undici - fetch' │ 60 │ '11357.87 req/sec' │ '± 2.89 %' │ '+ 3718.35 %' │ 58│ 8 │ 'http - keepalive' │ 60 │ '13782.10 req/sec' │ '± 2.97 %' │ '+ 4533.34 %' │ 59│ 9 │ 'urllib4 - request' │ 70 │ '15965.62 req/sec' │ '± 2.88 %' │ '+ 5267.40 %' │ 60│ 10 │ 'urllib3 - request' │ 55 │ '16010.37 req/sec' │ '± 2.90 %' │ '+ 5282.45 %' │ 61│ 11 │ 'undici - pipeline' │ 35 │ '17969.37 req/sec' │ '± 2.95 %' │ '+ 5941.03 %' │ 62│ 12 │ 'undici - dispatch' │ 101 │ '18765.50 req/sec' │ '± 3.01 %' │ '+ 6208.68 %' │ 63│ 13 │ 'undici - request' │ 85 │ '20091.12 req/sec' │ '± 2.95 %' │ '+ 6654.33 %' │ 64│ 14 │ 'undici - stream' │ 45 │ '21599.12 req/sec' │ '± 2.81 %' │ '+ 7161.30 %' │ 65└─────────┴───────────────────────┴─────────┴────────────────────┴────────────┴─────────────────────────┘
License
Contributors
Made with contributors-img.
No vulnerabilities found.
Reason
30 commit(s) and 5 issue activity found in the last 90 days -- score normalized to 10
Reason
no binaries found in the repo
Reason
no dangerous workflow patterns detected
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
Found 7/30 approved changesets -- score normalized to 2
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/nodejs-16.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/node-modules/urllib/nodejs-16.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/nodejs-16.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/node-modules/urllib/nodejs-16.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pkg.pr.new.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/node-modules/urllib/pkg.pr.new.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pkg.pr.new.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/node-modules/urllib/pkg.pr.new.yml/master?enable=pin
- Warn: npmCommand not pinned by hash: .github/workflows/nodejs-16.yml:21
- Warn: npmCommand not pinned by hash: .github/workflows/pkg.pr.new.yml:19
- Info: 0 out of 4 GitHub-owned GitHubAction dependencies pinned
- Info: 0 out of 2 npmCommand dependencies pinned
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/nodejs-16.yml:1
- Warn: no topLevel permission defined: .github/workflows/nodejs.yml:1
- Warn: no topLevel permission defined: .github/workflows/pkg.pr.new.yml:1
- Warn: no topLevel permission defined: .github/workflows/release.yml:1
- Info: no jobLevel write permissions found
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 16 are checked with a SAST tool
Score
5
/10
Last Scanned on 2025-01-27
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn MoreGathering detailed insights and metrics for urllib