urllib 2.34.1 → 2.36.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.
package/History.md CHANGED
@@ -1,4 +1,35 @@
1
1
 
2
+ 2.36.1 / 2020-06-09
3
+ ==================
4
+
5
+ **others**
6
+ * [[`35eecc0`](http://github.com/node-modules/urllib/commit/35eecc021f55e324b2520f91a032a33517d94f29)] - chore: add type declaration for RequestOptions#keepHeaderCase (#345) (William <<willizm.cn@gmail.com>>)
7
+
8
+ 2.36.0 / 2020-06-08
9
+ ==================
10
+
11
+ **fixes**
12
+ * [[`15c4170`](http://github.com/node-modules/urllib/commit/15c4170beab4404b0576caa01e199f445c476b7d)] - fix: allow to keep origin header key case (#344) (TZ | 天猪 <<atian25@qq.com>>)
13
+
14
+ **others**
15
+ * [[`31c03b8`](http://github.com/node-modules/urllib/commit/31c03b853ae5db00c7223c0a1a545dfcf0b07aa5)] - chore: Update and rename LICENSE.txt to LICENSE (#343) (Yuxiang LIU <<david-khala@hotmail.com>>)
16
+
17
+ 2.35.0 / 2020-05-15
18
+ ==================
19
+
20
+ **features**
21
+ * [[`47c21bd`](http://github.com/node-modules/urllib/commit/47c21bd93648080589bdc6528d9e9cf3e0489951)] - feat: change header to lowercase (#337) (TZ | 天猪 <<atian25@qq.com>>)
22
+
23
+ **fixes**
24
+ * [[`8f2ca64`](http://github.com/node-modules/urllib/commit/8f2ca648608995d140d0ca3873ef728bdbd4ee41)] - fix: need to handle response data on close event (#340) (fengmk2 <<fengmk2@gmail.com>>)
25
+ * [[`175ad2b`](http://github.com/node-modules/urllib/commit/175ad2b3e17196626c701ef72396dd6932d14c7a)] - fix: res.socket is null in node-v14.x (#339) (hyj1991 <<yeekwanvong@gmail.com>>)
26
+
27
+ 2.34.2 / 2019-12-09
28
+ ==================
29
+
30
+ **fixes**
31
+ * [[`67d5b1c`](http://github.com/node-modules/urllib/commit/67d5b1c35dc302778aa4b992ea4998fe427e3cc8)] - fix: index.d.ts (#334) (Daniels.Sun <<better.sunjian@gmail.com>>)
32
+
2
33
  2.34.1 / 2019-09-02
3
34
  ==================
4
35
 
@@ -1,4 +1,4 @@
1
- This software is licensed under the MIT License.
1
+ MIT License
2
2
 
3
3
  Copyright(c) 2011 - 2014 fengmk2 and other contributors.
4
4
  Copyright(c) 2015 - present node-modules and other contributors.
@@ -10,13 +10,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
10
  copies of the Software, and to permit persons to whom the Software is
11
11
  furnished to do so, subject to the following conditions:
12
12
 
13
- The above copyright notice and this permission notice shall be included in
14
- all copies or substantial portions of the Software.
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
15
 
16
16
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
17
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
18
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
19
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
20
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- THE SOFTWARE.
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md CHANGED
@@ -130,6 +130,7 @@ httpclient.request('http://nodejs.org', function (err, body) {
130
130
  - ***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`.
131
131
  - **fixJSONCtlChars** Boolean - Fix the control characters (U+0000 through U+001F) before JSON parse response. Default is `false`.
132
132
  - ***headers*** Object - Request headers.
133
+ - ***keepHeaderCase*** Boolean - by default will convert header keys to lowercase
133
134
  - ***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.
134
135
  - ***auth*** String - `username:password` used in HTTP Basic Authorization.
135
136
  - ***digestAuth*** String - `username:password` used in HTTP [Digest Authorization](http://en.wikipedia.org/wiki/Digest_access_authentication).
package/lib/index.d.ts CHANGED
@@ -31,6 +31,11 @@ export interface RequestOptions {
31
31
  writeStream?: Writable;
32
32
  /** consume the writeStream, invoke the callback after writeStream close. */
33
33
  consumeWriteStream?: boolean;
34
+ /**
35
+ * The files will send with multipart/form-data format, base on formstream.
36
+ * If method not set, will use POST method by default.
37
+ */
38
+ files?: Array<Readable | Buffer | string> | object | Readable | Buffer | string;
34
39
  /** Type of request data.Could be json.If it's json, will auto set Content-Type: application/json header. */
35
40
  contentType?: string;
36
41
  /**
@@ -49,6 +54,8 @@ export interface RequestOptions {
49
54
  fixJSONCtlChars?: boolean;
50
55
  /** Request headers. */
51
56
  headers?: IncomingHttpHeaders;
57
+ /** by default will convert header keys to lowercase */
58
+ keepHeaderCase?: boolean;
52
59
  /**
53
60
  * Request timeout in milliseconds for connecting phase and response receiving phase.
54
61
  * Defaults to exports.
package/lib/urllib.js CHANGED
@@ -105,6 +105,7 @@ var SOCKET_RESPONSE_COUNT = '_URLLIB_SOCKET_RESPONSE_COUNT';
105
105
  * before JSON parse response. Default is `false`.
106
106
  * `fixJSONCtlChars` can be a function, will pass data to the first argument. e.g.: `data = fixJSONCtlChars(data)`
107
107
  * - {Object} [headers]: optional, request headers
108
+ * - {Boolean} [keepHeaderCase]: optional, by default will convert header keys to lowercase
108
109
  * - {Number|Array} [timeout]: request timeout(in milliseconds), default is `exports.TIMEOUTS containing connect timeout and response timeout`
109
110
  * - {Agent} [agent]: optional, http agent. Set `false` if you does not use agent.
110
111
  * - {Agent} [httpsAgent]: optional, https agent. Set `false` if you does not use agent.
@@ -196,6 +197,7 @@ exports.requestThunk = function requestThunk(url, args) {
196
197
  };
197
198
 
198
199
  function requestWithCallback(url, args, callback) {
200
+ var req;
199
201
  // requestWithCallback(url, callback)
200
202
  if (!url || (typeof url !== 'string' && typeof url !== 'object')) {
201
203
  var msg = util.format('expect request url to be a string or a http request options, but got %j', url);
@@ -299,12 +301,18 @@ function requestWithCallback(url, args, callback) {
299
301
  // https://github.com/nodejs/node/blob/archived-io.js-v0.12/lib/net.js#L952
300
302
  lookup: lookup,
301
303
  };
304
+
305
+ var originHeaderKeys = {};
302
306
  if (args.headers) {
303
307
  // only allow enumerable and ownProperty value of args.headers
304
308
  var names = utility.getOwnEnumerables(args.headers, true);
305
309
  for (var i = 0; i < names.length; i++) {
306
310
  var name = names[i];
307
- options.headers[name] = args.headers[name];
311
+ var key = name.toLowerCase();
312
+ if (key !== name) {
313
+ originHeaderKeys[key] = name;
314
+ }
315
+ options.headers[key] = args.headers[name];
308
316
  }
309
317
  }
310
318
 
@@ -386,7 +394,7 @@ function requestWithCallback(url, args, callback) {
386
394
  var formHeaderNames = utility.getOwnEnumerables(formHeaders, true);
387
395
  for (var i = 0; i < formHeaderNames.length; i++) {
388
396
  var name = formHeaderNames[i];
389
- options.headers[name] = formHeaders[name];
397
+ options.headers[name.toLowerCase()] = formHeaders[name];
390
398
  }
391
399
  debug('set multipart headers: %j, method: %s', formHeaders, options.method);
392
400
  args.stream = form;
@@ -399,7 +407,7 @@ function requestWithCallback(url, args, callback) {
399
407
  // read: GET, HEAD, use query string
400
408
  body = args.nestedQuerystring ? qs.stringify(body) : querystring.stringify(body);
401
409
  } else {
402
- var contentType = options.headers['Content-Type'] || options.headers['content-type'];
410
+ var contentType = options.headers['content-type'];
403
411
  // auto add application/x-www-form-urlencoded when using urlencode form request
404
412
  if (!contentType) {
405
413
  if (args.contentType === 'json') {
@@ -407,7 +415,7 @@ function requestWithCallback(url, args, callback) {
407
415
  } else {
408
416
  contentType = 'application/x-www-form-urlencoded';
409
417
  }
410
- options.headers['Content-Type'] = contentType;
418
+ options.headers['content-type'] = contentType;
411
419
  }
412
420
 
413
421
  if (parseContentType(contentType).type === 'application/json') {
@@ -433,13 +441,15 @@ function requestWithCallback(url, args, callback) {
433
441
  if (!Buffer.isBuffer(body)) {
434
442
  length = Buffer.byteLength(body);
435
443
  }
436
- requestSize = options.headers['Content-Length'] = length;
444
+ requestSize = length;
445
+
446
+ options.headers['content-length'] = length.toString();
437
447
  }
438
448
  }
439
449
 
440
450
  if (args.dataType === 'json') {
441
- if (!options.headers.Accept && !options.headers.accept) {
442
- options.headers.Accept = 'application/json';
451
+ if (!options.headers.accept) {
452
+ options.headers.accept = 'application/json';
443
453
  }
444
454
  }
445
455
 
@@ -447,6 +457,7 @@ function requestWithCallback(url, args, callback) {
447
457
  // you can use this hook to change every thing.
448
458
  args.beforeRequest(options);
449
459
  }
460
+
450
461
  var connectTimer = null;
451
462
  var responseTimer = null;
452
463
  var __err = null;
@@ -516,14 +527,14 @@ function requestWithCallback(url, args, callback) {
516
527
 
517
528
  // handle digest auth
518
529
  if (statusCode === 401 && headers['www-authenticate']
519
- && !options.headers.Authorization && args.digestAuth) {
530
+ && !options.headers.authorization && args.digestAuth) {
520
531
  var authenticate = headers['www-authenticate'];
521
532
  if (authenticate.indexOf('Digest ') >= 0) {
522
533
  debug('Request#%d %s: got digest auth header WWW-Authenticate: %s', reqId, url, authenticate);
523
- options.headers.Authorization = digestAuthHeader(options.method, options.path, authenticate, args.digestAuth);
524
- debug('Request#%d %s: auth with digest header: %s', reqId, url, options.headers.Authorization);
534
+ options.headers.authorization = digestAuthHeader(options.method, options.path, authenticate, args.digestAuth);
535
+ debug('Request#%d %s: auth with digest header: %s', reqId, url, options.headers.authorization);
525
536
  if (res.headers['set-cookie']) {
526
- options.headers.Cookie = res.headers['set-cookie'].join(';');
537
+ options.headers.cookie = res.headers['set-cookie'].join(';');
527
538
  }
528
539
  args.headers = options.headers;
529
540
  return exports.requestWithCallback(url, args, cb);
@@ -592,10 +603,11 @@ function requestWithCallback(url, args, callback) {
592
603
  if (serverSocketTimeout < freeSocketTimeout) {
593
604
  // https://github.com/node-modules/agentkeepalive/blob/master/lib/agent.js#L127
594
605
  // agentkeepalive@4
606
+ var socket = res.socket || (req && req.socket);
595
607
  if (agent.options && agent.options.freeSocketTimeout) {
596
- res.socket.freeSocketTimeout = serverSocketTimeout;
608
+ socket.freeSocketTimeout = serverSocketTimeout;
597
609
  } else {
598
- res.socket.freeSocketKeepAliveTimeout = serverSocketTimeout;
610
+ socket.freeSocketKeepAliveTimeout = serverSocketTimeout;
599
611
  }
600
612
  }
601
613
  }
@@ -637,9 +649,9 @@ function requestWithCallback(url, args, callback) {
637
649
  debug('Request#%d %s: `redirected` from %s to %s', reqId, options.path, url, newUrl);
638
650
  // make sure timer stop
639
651
  cancelResponseTimer();
640
- // should clean up headers.Host on `location: http://other-domain/url`
641
- if (options.headers.Host && PROTO_RE.test(location)) {
642
- options.headers.Host = null;
652
+ // should clean up headers.host on `location: http://other-domain/url`
653
+ if (options.headers.host && PROTO_RE.test(location)) {
654
+ options.headers.host = null;
643
655
  args.headers = options.headers;
644
656
  }
645
657
  // avoid done will be execute in the future change.
@@ -663,23 +675,20 @@ function requestWithCallback(url, args, callback) {
663
675
  if (options.headers['user-agent']) {
664
676
  delete options.headers['user-agent'];
665
677
  }
666
- if (options.headers['User-Agent']) {
667
- delete options.headers['User-Agent'];
668
- }
669
678
  } else {
670
679
  // need to set user-agent
671
- var hasAgentHeader = options.headers['User-Agent'] || options.headers['user-agent'];
680
+ var hasAgentHeader = options.headers['user-agent'];
672
681
  if (!hasAgentHeader) {
673
- options.headers['User-Agent'] = USER_AGENT;
682
+ options.headers['user-agent'] = USER_AGENT;
674
683
  }
675
684
  }
676
685
 
677
686
  if (args.gzip) {
678
687
  var isAcceptEncodingNull = (args.headers && (args.headers['Accept-Encoding'] === null || args.headers['accept-encoding'] === null));
679
688
  if (!isAcceptEncodingNull) {
680
- var hasAcceptEncodingHeader = options.headers['Accept-Encoding'] || options.headers['accept-encoding'];
689
+ var hasAcceptEncodingHeader = options.headers['accept-encoding'];
681
690
  if (!hasAcceptEncodingHeader) {
682
- options.headers['Accept-Encoding'] = 'gzip, deflate';
691
+ options.headers['accept-encoding'] = 'gzip, deflate';
683
692
  }
684
693
  }
685
694
  }
@@ -737,11 +746,6 @@ function requestWithCallback(url, args, callback) {
737
746
  return done(null, null, res);
738
747
  }
739
748
 
740
- res.on('close', function () {
741
- debug('Request#%d %s: `res close` event emit, total size %d, socket handled %s requests and %s responses',
742
- reqId, url, responseSize, socketHandledRequests, socketHandledResponses);
743
- });
744
-
745
749
  res.on('error', function () {
746
750
  debug('Request#%d %s: `res error` event emit, total size %d, socket handled %s requests and %s responses',
747
751
  reqId, url, responseSize, socketHandledRequests, socketHandledResponses);
@@ -843,10 +847,18 @@ function requestWithCallback(url, args, callback) {
843
847
  chunks.push(chunk);
844
848
  });
845
849
 
846
- res.on('end', function () {
850
+ var isEmitted = false;
851
+ function handleResponseCloseAndEnd(event) {
852
+ debug('Request#%d %s: `res %s` event emit, total size %d, socket handled %s requests and %s responses',
853
+ reqId, url, event, responseSize, socketHandledRequests, socketHandledResponses);
854
+ if (isEmitted) {
855
+ return;
856
+ }
857
+ isEmitted = true;
858
+
847
859
  var body = Buffer.concat(chunks, responseSize);
848
- debug('Request#%d %s: `res end` event emit, total size %d, _dumped: %s',
849
- reqId, url, responseSize, res._dumped);
860
+ debug('Request#%d %s: _dumped: %s',
861
+ reqId, url, res._dumped);
850
862
 
851
863
  if (__err) {
852
864
  // req.abort() after `res data` event emit.
@@ -898,6 +910,14 @@ function requestWithCallback(url, args, callback) {
898
910
 
899
911
  done(err, data, res);
900
912
  });
913
+ }
914
+
915
+ // node >= 14 only emit close if req abort
916
+ res.on('close', function () {
917
+ handleResponseCloseAndEnd('close');
918
+ });
919
+ res.on('end', function () {
920
+ handleResponseCloseAndEnd('end');
901
921
  });
902
922
  }
903
923
 
@@ -966,10 +986,27 @@ function requestWithCallback(url, args, callback) {
966
986
  }
967
987
  }
968
988
 
969
- var req;
970
989
  // request headers checker will throw error
971
990
  try {
972
- req = httplib.request(options, onResponse);
991
+ var finalOptions = options;
992
+
993
+ // restore origin header key
994
+ if (args.keepHeaderCase) {
995
+ var originKeys = Object.keys(originHeaderKeys);
996
+ if (originKeys.length) {
997
+ var finalHeaders = {};
998
+ var names = utility.getOwnEnumerables(options.headers, true);
999
+ for (var i = 0; i < names.length; i++) {
1000
+ var name = names[i];
1001
+ finalHeaders[originHeaderKeys[name] || name] = options.headers[name];
1002
+ }
1003
+
1004
+ finalOptions = Object.assign({}, options);
1005
+ finalOptions.headers = finalHeaders;
1006
+ }
1007
+ }
1008
+
1009
+ req = httplib.request(finalOptions, onResponse);
973
1010
  if (args.trace) {
974
1011
  req._callSite = {};
975
1012
  Error.captureStackTrace(req._callSite, requestWithCallback);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "urllib",
3
- "version": "2.34.1",
3
+ "version": "2.36.1",
4
4
  "description": "Help in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections, cookies and more.",
5
5
  "keywords": [
6
6
  "urllib",
@@ -58,6 +58,7 @@
58
58
  "busboy": "^0.2.14",
59
59
  "co": "*",
60
60
  "coffee": "1",
61
+ "egg-ci": "^1.15.0",
61
62
  "git-contributor": "^1.0.10",
62
63
  "http-proxy": "^1.16.2",
63
64
  "intelli-espower-loader": "^1.0.1",
@@ -69,6 +70,7 @@
69
70
  "pedding": "^1.1.0",
70
71
  "power-assert": "^1.4.2",
71
72
  "semver": "5",
73
+ "spy": "^1.0.0",
72
74
  "tar": "^4.4.8",
73
75
  "through2": "^2.0.3",
74
76
  "typescript": "^3.2.2"
@@ -76,5 +78,12 @@
76
78
  "engines": {
77
79
  "node": ">= 0.10.0"
78
80
  },
81
+ "ci": {
82
+ "type": "github",
83
+ "os": {
84
+ "github": "linux, windows, macos"
85
+ },
86
+ "version": "6, 8, 10, 12, 14"
87
+ },
79
88
  "license": "MIT"
80
89
  }