urllib 2.38.0 → 3.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +116 -205
- package/package.json +56 -56
- package/src/HttpClient.ts +274 -0
- package/src/Request.ts +116 -0
- package/src/Response.ts +20 -0
- package/src/cjs/HttpClient.d.ts +31 -0
- package/src/cjs/HttpClient.js +270 -0
- package/src/cjs/HttpClient.js.map +1 -0
- package/src/cjs/Request.d.ts +117 -0
- package/src/cjs/Request.js +3 -0
- package/src/cjs/Request.js.map +1 -0
- package/src/cjs/Response.d.ts +20 -0
- package/src/cjs/Response.js +3 -0
- package/src/cjs/Response.js.map +1 -0
- package/src/cjs/index.d.ts +27 -0
- package/src/cjs/index.js +18 -0
- package/src/cjs/index.js.map +1 -0
- package/src/cjs/package.json +3 -0
- package/src/esm/HttpClient.d.ts +31 -0
- package/src/esm/HttpClient.js +266 -0
- package/src/esm/HttpClient.js.map +1 -0
- package/src/esm/Request.d.ts +117 -0
- package/src/esm/Request.js +2 -0
- package/src/esm/Request.js.map +1 -0
- package/src/esm/Response.d.ts +20 -0
- package/src/esm/Response.js +2 -0
- package/src/esm/Response.js.map +1 -0
- package/src/esm/index.d.ts +27 -0
- package/src/esm/index.js +13 -0
- package/src/esm/index.js.map +1 -0
- package/src/esm/package.json +3 -0
- package/src/index.ts +17 -0
- package/History.md +0 -792
- package/lib/detect_proxy_agent.js +0 -31
- package/lib/get_proxy_from_uri.js +0 -81
- package/lib/httpclient.js +0 -61
- package/lib/httpclient2.js +0 -83
- package/lib/index.d.ts +0 -279
- package/lib/index.js +0 -21
- package/lib/index.test-d.ts +0 -10
- package/lib/urllib.js +0 -1305
package/README.md
CHANGED
@@ -21,63 +21,29 @@ and digest authentication, redirections, cookies, timeout and more.
|
|
21
21
|
## Install
|
22
22
|
|
23
23
|
```bash
|
24
|
-
|
24
|
+
npm install urllib --save
|
25
25
|
```
|
26
26
|
|
27
27
|
## Usage
|
28
28
|
|
29
|
-
###
|
29
|
+
### TypeScript and ESM
|
30
30
|
|
31
31
|
```js
|
32
|
-
|
32
|
+
import { request } from 'urllib';
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
}
|
38
|
-
console.log(res.statusCode);
|
39
|
-
console.log(res.headers);
|
40
|
-
// data is Buffer instance
|
41
|
-
console.log(data.toString());
|
42
|
-
});
|
34
|
+
const { data, res } = await request('http://cnodejs.org/');
|
35
|
+
// result: { data: Buffer, res: Response }
|
36
|
+
console.log('status: %s, body size: %d, headers: %j', res.statusCode, data.length, res.headers);
|
43
37
|
```
|
44
38
|
|
45
|
-
###
|
46
|
-
|
47
|
-
If you've installed [bluebird][bluebird],
|
48
|
-
[bluebird][bluebird] will be used.
|
49
|
-
`urllib` does not install [bluebird][bluebird] for you.
|
50
|
-
|
51
|
-
Otherwise, if you're using a node that has native v8 Promises (v0.11.13+),
|
52
|
-
then that will be used.
|
53
|
-
|
54
|
-
Otherwise, this library will crash the process and exit,
|
55
|
-
so you might as well install [bluebird][bluebird] as a dependency!
|
39
|
+
### CommonJS
|
56
40
|
|
57
41
|
```js
|
58
|
-
|
42
|
+
const { request } = require('urllib');
|
59
43
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
}).catch(function (err) {
|
64
|
-
console.error(err);
|
65
|
-
});
|
66
|
-
```
|
67
|
-
|
68
|
-
### co & generator
|
69
|
-
|
70
|
-
If you are using [co](https://github.com/visionmedia/co) or [koa](https://github.com/koajs/koa):
|
71
|
-
|
72
|
-
```js
|
73
|
-
var co = require('co');
|
74
|
-
var urllib = require('urllib');
|
75
|
-
|
76
|
-
co(function* () {
|
77
|
-
var result = yield urllib.requestThunk('http://nodejs.org');
|
78
|
-
console.log('status: %s, body size: %d, headers: %j',
|
79
|
-
result.status, result.data.length, result.headers);
|
80
|
-
})();
|
44
|
+
const { data, res } = await request('http://cnodejs.org/');
|
45
|
+
// result: { data: Buffer, res: Response }
|
46
|
+
console.log('status: %s, body size: %d, headers: %j', res.statusCode, data.length, res.headers);
|
81
47
|
```
|
82
48
|
|
83
49
|
## Global `response` event
|
@@ -85,9 +51,10 @@ co(function* () {
|
|
85
51
|
You should create a urllib instance first.
|
86
52
|
|
87
53
|
```js
|
88
|
-
|
54
|
+
import { HttpClient } from 'urllib';
|
89
55
|
|
90
|
-
httpclient
|
56
|
+
const httpclient = new HttpClient();
|
57
|
+
httpclient.on('response', (info) => {
|
91
58
|
error: err,
|
92
59
|
ctx: args.ctx,
|
93
60
|
req: {
|
@@ -98,89 +65,83 @@ httpclient.on('response', function (info) {
|
|
98
65
|
res: res
|
99
66
|
});
|
100
67
|
|
101
|
-
httpclient.request('
|
102
|
-
|
103
|
-
});
|
68
|
+
const { data, res } = await httpclient.request('https://nodejs.org');
|
69
|
+
console.log('status: %s, body size: %d, headers: %j', res.statusCode, data.length, res.headers);
|
104
70
|
```
|
105
71
|
|
106
72
|
## API Doc
|
107
73
|
|
108
|
-
### Method: `
|
74
|
+
### Method: `async request(url[, options])`
|
109
75
|
|
110
76
|
#### Arguments
|
111
77
|
|
112
78
|
- **url** String | Object - The URL to request, either a String or a Object that return by [url.parse](http://nodejs.org/api/url.html#url_url_parse_urlstr_parsequerystring_slashesdenotehost).
|
113
79
|
- ***options*** Object - Optional
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
80
|
+
- ***method*** String - Request method, defaults to `GET`. Could be `GET`, `POST`, `DELETE` or `PUT`. Alias 'type'.
|
81
|
+
- ***data*** Object - Data to be sent. Will be stringify automatically.
|
82
|
+
- ***dataAsQueryString*** Boolean - Force convert `data` to query string.
|
83
|
+
- ***content*** String | [Buffer](http://nodejs.org/api/buffer.html) - Manually set the content of payload. If set, `data` will be ignored.
|
84
|
+
- ***stream*** [stream.Readable](http://nodejs.org/api/stream.html#stream_class_stream_readable) - Stream to be pipe to the remote. If set, `data` and `content` will be ignored.
|
85
|
+
- ***writeStream*** [stream.Writable](http://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.
|
86
|
+
- ***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.
|
87
|
+
- ***consumeWriteStream*** [true] - consume the writeStream, invoke the callback after writeStream close.
|
88
|
+
- ***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.
|
89
|
+
- ***nestedQuerystring*** Boolean - urllib default use querystring to stringify form data which don't support nested object, will use [qs](https://github.com/ljharb/qs) instead of querystring to support nested object by set this option to true.
|
90
|
+
- ***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`.
|
91
|
+
- **fixJSONCtlChars** Boolean - Fix the control characters (U+0000 through U+001F) before JSON parse response. Default is `false`.
|
92
|
+
- ***headers*** Object - Request headers.
|
93
|
+
- ***keepHeaderCase*** Boolean - by default will convert header keys to lowercase
|
94
|
+
- ***timeout*** Number | Array - Request timeout in milliseconds for connecting phase and response receiving phase. Defaults to `exports.TIMEOUT`, both are 5s. You can use `timeout: 5000` to tell urllib use same timeout on two phase or set them seperately such as `timeout: [3000, 5000]`, which will set connecting timeout to 3s and response 5s.
|
95
|
+
- ***auth*** String - `username:password` used in HTTP Basic Authorization.
|
96
|
+
- ***digestAuth*** String - `username:password` used in HTTP [Digest Authorization](http://en.wikipedia.org/wiki/Digest_access_authentication).
|
97
|
+
- ***agent*** [http.Agent](http://nodejs.org/api/http.html#http_class_http_agent) - HTTP Agent object.
|
132
98
|
Set `false` if you does not use agent.
|
133
|
-
|
99
|
+
- ***httpsAgent*** [https.Agent](http://nodejs.org/api/https.html#https_class_https_agent) - HTTPS Agent object.
|
134
100
|
Set `false` if you does not use agent.
|
135
|
-
|
101
|
+
- ***ca*** String | Buffer | Array - An array of strings or Buffers of trusted certificates.
|
136
102
|
If this is omitted several well known "root" CAs will be used, like VeriSign.
|
137
103
|
These are used to authorize connections.
|
138
104
|
**Notes**: This is necessary only if the server uses the self-signed certificate
|
139
|
-
|
105
|
+
- ***rejectUnauthorized*** Boolean - If true, the server certificate is verified against the list of supplied CAs.
|
140
106
|
An 'error' event is emitted if verification fails. Default: true.
|
141
|
-
|
107
|
+
- ***pfx*** String | Buffer - A string or Buffer containing the private key,
|
142
108
|
certificate and CA certs of the server in PFX or PKCS12 format.
|
143
|
-
|
109
|
+
- ***key*** String | Buffer - A string or Buffer containing the private key of the client in PEM format.
|
144
110
|
**Notes**: This is necessary only if using the client certificate authentication
|
145
|
-
|
111
|
+
- ***cert*** String | Buffer - A string or Buffer containing the certificate key of the client in PEM format.
|
146
112
|
**Notes**: This is necessary only if using the client certificate authentication
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
- ***callback(err, data, res)*** Function - Optional callback.
|
164
|
-
- **err** Error - Would be `null` if no error accured.
|
165
|
-
- **data** Buffer | Object - The data responsed. Would be a Buffer if `dataType` is set to `text` or an JSON parsed into Object if it's set to `json`.
|
166
|
-
- **res** [http.IncomingMessage](http://nodejs.org/api/http.html#http_http_incomingmessage) - The response.
|
113
|
+
- ***passphrase*** String - A string of passphrase for the private key or pfx.
|
114
|
+
- ***ciphers*** String - A string describing the ciphers to use or exclude.
|
115
|
+
- ***secureProtocol*** String - The SSL method to use, e.g. SSLv3_method to force SSL version 3.
|
116
|
+
- ***followRedirect*** Boolean - follow HTTP 3xx responses as redirects. defaults to false.
|
117
|
+
- ***maxRedirects*** Number - The maximum number of redirects to follow, defaults to 10.
|
118
|
+
- ***formatRedirectUrl*** Function - Format the redirect url by your self. Default is `url.resolve(from, to)`.
|
119
|
+
- ***beforeRequest*** Function - Before request hook, you can change every thing here.
|
120
|
+
- ***streaming*** Boolean - let you get the `res` object when request connected, default `false`. alias `customResponse`
|
121
|
+
- ***gzip*** Boolean - Accept gzip response content and auto decode it, default is `false`.
|
122
|
+
- ***timing*** Boolean - Enable timing or not, default is `false`.
|
123
|
+
- ***enableProxy*** Boolean - Enable proxy request, default is `false`.
|
124
|
+
- ***proxy*** String | Object - proxy agent uri or options, default is `null`.
|
125
|
+
- ***lookup*** Function - Custom DNS lookup function, default is `dns.lookup`. Require node >= 4.0.0(for http protocol) and node >=8(for https protocol)
|
126
|
+
- ***checkAddress*** Function: optional, check request address to protect from SSRF and similar attacks. It receive tow arguments(`ip` and `family`) and should return true or false to identified the address is legal or not. It rely on `lookup` and have the same version requirement.
|
127
|
+
- ***trace*** Boolean - Enable capture stack include call site of library entrance, default is `false`.
|
128
|
+
- ***socketPath*** String - optional Unix Domain Socket. (Refer to [Node.js Document](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_http_request_options_callback))
|
167
129
|
|
168
130
|
#### Returns
|
169
131
|
|
170
|
-
|
171
|
-
|
172
|
-
Calling `.abort()` method of the request stream can cancel the request.
|
132
|
+
- **data** Buffer | Object - The data responsed. Would be a Buffer if `dataType` is set to `text` or an JSON parsed into Object if it's set to `json`.
|
133
|
+
- **res** [http.IncomingMessage](http://nodejs.org/api/http.html#http_http_incomingmessage) - The response.
|
173
134
|
|
174
135
|
#### Options: `options.data`
|
175
136
|
|
176
137
|
When making a request:
|
177
138
|
|
178
139
|
```js
|
179
|
-
|
140
|
+
await request('https://example.com', {
|
180
141
|
method: 'GET',
|
181
142
|
data: {
|
182
143
|
'a': 'hello',
|
183
|
-
'b': 'world'
|
144
|
+
'b': 'world',
|
184
145
|
}
|
185
146
|
});
|
186
147
|
```
|
@@ -201,14 +162,14 @@ for example making a `Content-Type: application/json` request.
|
|
201
162
|
Notes that if you want to send a JSON body, you should stringify it yourself:
|
202
163
|
|
203
164
|
```js
|
204
|
-
|
165
|
+
await request('https://example.com', {
|
205
166
|
method: 'POST',
|
206
167
|
headers: {
|
207
168
|
'Content-Type': 'application/json'
|
208
169
|
},
|
209
170
|
content: JSON.stringify({
|
210
171
|
a: 'hello',
|
211
|
-
b: 'world'
|
172
|
+
b: 'world',
|
212
173
|
})
|
213
174
|
});
|
214
175
|
```
|
@@ -229,14 +190,14 @@ Content-Type: application/json
|
|
229
190
|
This exmaple can use `options.data` with `application/json` content type:
|
230
191
|
|
231
192
|
```js
|
232
|
-
|
193
|
+
await request('https://example.com', {
|
233
194
|
method: 'POST',
|
234
195
|
headers: {
|
235
196
|
'Content-Type': 'application/json'
|
236
197
|
},
|
237
198
|
data: {
|
238
199
|
a: 'hello',
|
239
|
-
b: 'world'
|
200
|
+
b: 'world',
|
240
201
|
}
|
241
202
|
});
|
242
203
|
```
|
@@ -246,24 +207,20 @@ urllib.request('http://example.com', {
|
|
246
207
|
Upload a file with a `hello` field.
|
247
208
|
|
248
209
|
```js
|
249
|
-
|
250
|
-
|
251
|
-
var req = urllib.request('http://my.server.com/upload', {
|
210
|
+
await request('https://example.com/upload', {
|
211
|
+
method: 'POST',
|
252
212
|
files: __filename,
|
253
213
|
data: {
|
254
214
|
hello: 'hello urllib',
|
255
215
|
},
|
256
|
-
}, function (err, data, res) {
|
257
|
-
// upload finished
|
258
216
|
});
|
259
217
|
```
|
260
218
|
|
261
219
|
Upload multi files with a `hello` field.
|
262
220
|
|
263
221
|
```js
|
264
|
-
|
265
|
-
|
266
|
-
var req = urllib.request('http://my.server.com/upload', {
|
222
|
+
await request('https://example.com/upload', {
|
223
|
+
method: 'POST',
|
267
224
|
files: [
|
268
225
|
__filename,
|
269
226
|
fs.createReadStream(__filename),
|
@@ -272,22 +229,17 @@ var req = urllib.request('http://my.server.com/upload', {
|
|
272
229
|
data: {
|
273
230
|
hello: 'hello urllib with multi files',
|
274
231
|
},
|
275
|
-
}, function (err, data, res) {
|
276
|
-
// upload finished
|
277
232
|
});
|
278
233
|
```
|
279
234
|
|
280
235
|
Custom file field name with `uploadfile`.
|
281
236
|
|
282
237
|
```js
|
283
|
-
|
284
|
-
|
285
|
-
var req = urllib.request('http://my.server.com/upload', {
|
238
|
+
await request('https://example.com/upload', {
|
239
|
+
method: 'POST',
|
286
240
|
files: {
|
287
241
|
uploadfile: __filename,
|
288
242
|
},
|
289
|
-
}, function (err, data, res) {
|
290
|
-
// upload finished
|
291
243
|
});
|
292
244
|
```
|
293
245
|
|
@@ -296,19 +248,16 @@ var req = urllib.request('http://my.server.com/upload', {
|
|
296
248
|
Uploads a file with [formstream](https://github.com/node-modules/formstream):
|
297
249
|
|
298
250
|
```js
|
299
|
-
|
300
|
-
var formstream = require('formstream');
|
251
|
+
import formstream from 'formstream';
|
301
252
|
|
302
|
-
|
253
|
+
const form = formstream();
|
303
254
|
form.file('file', __filename);
|
304
255
|
form.field('hello', '你好urllib');
|
305
256
|
|
306
|
-
|
257
|
+
await request('https://example.com/upload', {
|
307
258
|
method: 'POST',
|
308
259
|
headers: form.headers(),
|
309
|
-
stream: form
|
310
|
-
}, function (err, data, res) {
|
311
|
-
// upload finished
|
260
|
+
stream: form,
|
312
261
|
});
|
313
262
|
```
|
314
263
|
|
@@ -316,19 +265,19 @@ var req = urllib.request('http://my.server.com/upload', {
|
|
316
265
|
|
317
266
|
Response is normal object, it contains:
|
318
267
|
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
268
|
+
- `status` or `statusCode`: response status code.
|
269
|
+
- `-1` meaning some network error like `ENOTFOUND`
|
270
|
+
- `-2` meaning ConnectionTimeoutError
|
271
|
+
- `statusMessage`: response status message.
|
272
|
+
- `headers`: response http headers, default is `{}`
|
273
|
+
- `size`: response size
|
274
|
+
- `aborted`: response was aborted or not
|
275
|
+
- `rt`: total request and response time in ms.
|
276
|
+
- `timing`: timing object if timing enable.
|
277
|
+
- `remoteAddress`: http server ip address
|
278
|
+
- `remotePort`: http server ip port
|
279
|
+
- `socketHandledRequests`: socket already handled request count
|
280
|
+
- `socketHandledResponses`: socket already handled response count
|
332
281
|
|
333
282
|
#### Response: `res.aborted`
|
334
283
|
|
@@ -336,30 +285,30 @@ If the underlaying connection was terminated before `response.end()` was called,
|
|
336
285
|
`res.aborted` should be `true`.
|
337
286
|
|
338
287
|
```js
|
339
|
-
|
288
|
+
import { createServer } from 'http';
|
289
|
+
|
290
|
+
createServer((req, res) => {
|
340
291
|
req.resume();
|
341
|
-
req.on('end',
|
292
|
+
req.on('end', () => {
|
342
293
|
res.write('foo haha\n');
|
343
|
-
setTimeout(
|
294
|
+
setTimeout(() => {
|
344
295
|
res.write('foo haha 2');
|
345
|
-
setTimeout(
|
296
|
+
setTimeout(() => {
|
346
297
|
res.socket.end();
|
347
298
|
}, 300);
|
348
299
|
}, 200);
|
349
300
|
return;
|
350
301
|
});
|
351
|
-
}).listen(
|
302
|
+
}).listen(2022);
|
352
303
|
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
done();
|
357
|
-
});
|
304
|
+
const { data, res } = await request('http://127.0.0.1:2022/socket.end');
|
305
|
+
assert.equal(data.toString(), 'foo haha\nfoo haha 2');
|
306
|
+
assert(res.aborted);
|
358
307
|
```
|
359
308
|
|
360
309
|
### HttpClient2
|
361
310
|
|
362
|
-
HttpClient2
|
311
|
+
HttpClient2 base on HttpClient.
|
363
312
|
|
364
313
|
#### Options
|
365
314
|
|
@@ -373,47 +322,10 @@ options extends from urllib, besides below
|
|
373
322
|
|
374
323
|
It's not supported by using retry and writeStream, because the retry request can't stop the stream which is consuming.
|
375
324
|
|
376
|
-
## Proxy
|
377
|
-
|
378
|
-
Support both `http` and `https` protocol.
|
379
|
-
|
380
|
-
**Notice: Only support on Node.js >= 4.0.0**
|
381
|
-
|
382
|
-
### Programming
|
383
|
-
|
384
|
-
```js
|
385
|
-
urllib.request('https://twitter.com/', {
|
386
|
-
enableProxy: true,
|
387
|
-
proxy: 'http://localhost:8008',
|
388
|
-
}, (err, data, res) => {
|
389
|
-
console.log(res.status, res.headers);
|
390
|
-
});
|
391
|
-
```
|
392
|
-
|
393
|
-
### System environment variable
|
394
|
-
|
395
|
-
- http
|
396
|
-
|
397
|
-
```bash
|
398
|
-
HTTP_PROXY=http://localhost:8008
|
399
|
-
http_proxy=http://localhost:8008
|
400
|
-
```
|
401
|
-
|
402
|
-
- https
|
403
|
-
|
404
|
-
```bash
|
405
|
-
HTTP_PROXY=http://localhost:8008
|
406
|
-
http_proxy=http://localhost:8008
|
407
|
-
HTTPS_PROXY=https://localhost:8008
|
408
|
-
https_proxy=https://localhost:8008
|
409
|
-
```
|
410
|
-
|
411
|
-
```bash
|
412
|
-
$ http_proxy=http://localhost:8008 node index.js
|
413
|
-
```
|
414
|
-
|
415
325
|
### Trace
|
326
|
+
|
416
327
|
If set trace true, error stack will contains full call stack, like
|
328
|
+
|
417
329
|
```
|
418
330
|
Error: connect ECONNREFUSED 127.0.0.1:11
|
419
331
|
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1113:14)
|
@@ -429,28 +341,28 @@ When open the trace, urllib may have poor perfomance, please consider carefully.
|
|
429
341
|
|
430
342
|
## TODO
|
431
343
|
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
* [√] Support `Accept-Encoding=gzip` by `options.gzip = true`
|
440
|
-
* [√] Support [Digest access authentication](http://en.wikipedia.org/wiki/Digest_access_authentication)
|
344
|
+
- ❎ Support Proxy
|
345
|
+
- ✅ Upload file like form upload
|
346
|
+
- ✅ Auto redirect handle
|
347
|
+
- ✅ https & self-signed certificate
|
348
|
+
- ✅ Connection timeout & Response timeout
|
349
|
+
- ✅ Support `Accept-Encoding=gzip` by default
|
350
|
+
- ✅ Support [Digest access authentication](http://en.wikipedia.org/wiki/Digest_access_authentication)
|
441
351
|
|
442
352
|
<!-- GITCONTRIBUTOR_START -->
|
443
353
|
|
444
354
|
## Contributors
|
445
355
|
|
446
|
-
|[<img src="https://
|
356
|
+
|[<img src="https://avatars.githubusercontent.com/u/156269?v=4" width="100px;"/><br/><sub><b>fengmk2</b></sub>](https://github.com/fengmk2)<br/>|[<img src="https://avatars.githubusercontent.com/u/985607?v=4" width="100px;"/><br/><sub><b>dead-horse</b></sub>](https://github.com/dead-horse)<br/>|[<img src="https://avatars.githubusercontent.com/u/288288?v=4" width="100px;"/><br/><sub><b>xingrz</b></sub>](https://github.com/xingrz)<br/>|[<img src="https://avatars.githubusercontent.com/u/360661?v=4" width="100px;"/><br/><sub><b>popomore</b></sub>](https://github.com/popomore)<br/>|[<img src="https://avatars.githubusercontent.com/u/327019?v=4" width="100px;"/><br/><sub><b>JacksonTian</b></sub>](https://github.com/JacksonTian)<br/>|[<img src="https://avatars.githubusercontent.com/u/543405?v=4" width="100px;"/><br/><sub><b>ibigbug</b></sub>](https://github.com/ibigbug)<br/>|
|
447
357
|
| :---: | :---: | :---: | :---: | :---: | :---: |
|
448
|
-
|[<img src="https://
|
449
|
-
|[<img src="https://
|
450
|
-
|[<img src="https://
|
451
|
-
[<img src="https://
|
358
|
+
|[<img src="https://avatars.githubusercontent.com/u/14790466?v=4" width="100px;"/><br/><sub><b>greenkeeperio-bot</b></sub>](https://github.com/greenkeeperio-bot)<br/>|[<img src="https://avatars.githubusercontent.com/u/227713?v=4" width="100px;"/><br/><sub><b>atian25</b></sub>](https://github.com/atian25)<br/>|[<img src="https://avatars.githubusercontent.com/u/5381764?v=4" width="100px;"/><br/><sub><b>paambaati</b></sub>](https://github.com/paambaati)<br/>|[<img src="https://avatars.githubusercontent.com/u/1433247?v=4" width="100px;"/><br/><sub><b>denghongcai</b></sub>](https://github.com/denghongcai)<br/>|[<img src="https://avatars.githubusercontent.com/u/2842176?v=4" width="100px;"/><br/><sub><b>XadillaX</b></sub>](https://github.com/XadillaX)<br/>|[<img src="https://avatars.githubusercontent.com/u/1147375?v=4" width="100px;"/><br/><sub><b>alsotang</b></sub>](https://github.com/alsotang)<br/>|
|
359
|
+
|[<img src="https://avatars.githubusercontent.com/u/546535?v=4" width="100px;"/><br/><sub><b>leoner</b></sub>](https://github.com/leoner)<br/>|[<img src="https://avatars.githubusercontent.com/u/19908330?v=4" width="100px;"/><br/><sub><b>hyj1991</b></sub>](https://github.com/hyj1991)<br/>|[<img src="https://avatars.githubusercontent.com/u/1747852?v=4" width="100px;"/><br/><sub><b>isayme</b></sub>](https://github.com/isayme)<br/>|[<img src="https://avatars.githubusercontent.com/u/252317?v=4" width="100px;"/><br/><sub><b>cyjake</b></sub>](https://github.com/cyjake)<br/>|[<img src="https://avatars.githubusercontent.com/u/5856440?v=4" width="100px;"/><br/><sub><b>whxaxes</b></sub>](https://github.com/whxaxes)<br/>|[<img src="https://avatars.githubusercontent.com/u/309219?v=4" width="100px;"/><br/><sub><b>chadxz</b></sub>](https://github.com/chadxz)<br/>|
|
360
|
+
|[<img src="https://avatars.githubusercontent.com/u/5139554?v=4" width="100px;"/><br/><sub><b>danielwpz</b></sub>](https://github.com/danielwpz)<br/>|[<img src="https://avatars.githubusercontent.com/u/5127897?v=4" width="100px;"/><br/><sub><b>danielsss</b></sub>](https://github.com/danielsss)<br/>|[<img src="https://avatars.githubusercontent.com/u/3367820?v=4" width="100px;"/><br/><sub><b>Jeff-Tian</b></sub>](https://github.com/Jeff-Tian)<br/>|[<img src="https://avatars.githubusercontent.com/u/32407?v=4" width="100px;"/><br/><sub><b>jedahan</b></sub>](https://github.com/jedahan)<br/>|[<img src="https://avatars.githubusercontent.com/u/17075261?v=4" width="100px;"/><br/><sub><b>nick-ng</b></sub>](https://github.com/nick-ng)<br/>|[<img src="https://avatars.githubusercontent.com/u/1706595?v=4" width="100px;"/><br/><sub><b>rishavsharan</b></sub>](https://github.com/rishavsharan)<br/>|
|
361
|
+
|[<img src="https://avatars.githubusercontent.com/u/1886161?v=4" width="100px;"/><br/><sub><b>willizm</b></sub>](https://github.com/willizm)<br/>|[<img src="https://avatars.githubusercontent.com/u/7227589?v=4" width="100px;"/><br/><sub><b>davidkhala</b></sub>](https://github.com/davidkhala)<br/>|[<img src="https://avatars.githubusercontent.com/u/535479?v=4" width="100px;"/><br/><sub><b>aleafs</b></sub>](https://github.com/aleafs)<br/>|[<img src="https://avatars.githubusercontent.com/u/3689968?v=4" width="100px;"/><br/><sub><b>Amunu</b></sub>](https://github.com/Amunu)<br/>|[<img src="https://avatars.githubusercontent.com/in/9426?v=4" width="100px;"/><br/><sub><b>azure-pipelines[bot]</b></sub>](https://github.com/apps/azure-pipelines)<br/>|[<img src="https://avatars.githubusercontent.com/u/1281323?v=4" width="100px;"/><br/><sub><b>changzhiwin</b></sub>](https://github.com/changzhiwin)<br/>|
|
362
|
+
|[<img src="https://avatars.githubusercontent.com/u/929503?v=4" width="100px;"/><br/><sub><b>yuzhigang33</b></sub>](https://github.com/yuzhigang33)<br/>|[<img src="https://avatars.githubusercontent.com/u/981128?v=4" width="100px;"/><br/><sub><b>fishbar</b></sub>](https://github.com/fishbar)<br/>|[<img src="https://avatars.githubusercontent.com/u/1207064?v=4" width="100px;"/><br/><sub><b>gxcsoccer</b></sub>](https://github.com/gxcsoccer)<br/>|[<img src="https://avatars.githubusercontent.com/u/6897780?v=4" width="100px;"/><br/><sub><b>killagu</b></sub>](https://github.com/killagu)<br/>|[<img src="https://avatars.githubusercontent.com/u/17476119?v=4" width="100px;"/><br/><sub><b>mars-coder</b></sub>](https://github.com/mars-coder)<br/>|[<img src="https://avatars.githubusercontent.com/u/929179?v=4" width="100px;"/><br/><sub><b>rockdai</b></sub>](https://github.com/rockdai)<br/>|
|
363
|
+
[<img src="https://avatars.githubusercontent.com/u/2196373?v=4" width="100px;"/><br/><sub><b>dickeylth</b></sub>](https://github.com/dickeylth)<br/>|[<img src="https://avatars.githubusercontent.com/u/13050025?v=4" width="100px;"/><br/><sub><b>aladdin-add</b></sub>](https://github.com/aladdin-add)<br/>
|
452
364
|
|
453
|
-
This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `
|
365
|
+
This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Fri Mar 25 2022 00:05:23 GMT+0800`.
|
454
366
|
|
455
367
|
<!-- GITCONTRIBUTOR_END -->
|
456
368
|
|
@@ -458,5 +370,4 @@ This project follows the git-contributor [spec](https://github.com/xudafeng/git-
|
|
458
370
|
|
459
371
|
[MIT](LICENSE)
|
460
372
|
|
461
|
-
|
462
373
|
[bluebird]: https://github.com/petkaantonov/bluebird
|