superagent 3.6.0 → 3.7.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/.travis.yml +4 -4
- package/History.md +12 -0
- package/Makefile +1 -1
- package/Readme.md +23 -11
- package/docs/index.md +16 -6
- package/lib/client.js +8 -7
- package/lib/is-object.js +2 -0
- package/lib/node/agent.js +1 -0
- package/lib/node/index.js +33 -9
- package/lib/node/parsers/image.js +3 -1
- package/lib/node/parsers/index.js +2 -0
- package/lib/node/parsers/json.js +1 -0
- package/lib/node/parsers/text.js +2 -1
- package/lib/node/parsers/urlencoded.js +2 -1
- package/lib/node/response.js +1 -0
- package/lib/node/unzip.js +2 -1
- package/lib/request-base.js +17 -0
- package/lib/response-base.js +1 -0
- package/lib/should-retry.js +2 -0
- package/lib/utils.js +2 -1
- package/package.json +9 -9
- package/superagent.js +32 -7
- package/yarn.lock +831 -640
- package/.npmignore +0 -7
package/.travis.yml
CHANGED
package/History.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# 3.7.0 (2017-10-17)
|
|
2
|
+
|
|
3
|
+
* Limit maximum response size. Prevents zip bombs (Kornel)
|
|
4
|
+
* Catch and pass along errors in `.ok()` callback (Jeremy Ruppel)
|
|
5
|
+
* Fixed parsing of XHR headers without a newline (nsf)
|
|
6
|
+
|
|
7
|
+
# 3.6.2 (2017-10-02)
|
|
8
|
+
|
|
9
|
+
* Upgrade MIME type dependency to a newer, secure version
|
|
10
|
+
* Recognize PDF MIME as binary
|
|
11
|
+
* Fix for error in subsequent require() calls (Steven de Salas)
|
|
12
|
+
|
|
1
13
|
# 3.6.0 (2017-08-20)
|
|
2
14
|
|
|
3
15
|
* Support disabling TCP_NODELAY option (#1240) (xiamengyu)
|
package/Makefile
CHANGED
|
@@ -20,7 +20,7 @@ test-cov: lib-cov
|
|
|
20
20
|
SUPERAGENT_COV=1 $(MAKE) test REPORTER=html-cov > coverage.html
|
|
21
21
|
|
|
22
22
|
test-browser:
|
|
23
|
-
SAUCE_APPIUM_VERSION=1.
|
|
23
|
+
SAUCE_APPIUM_VERSION=1.7 ./node_modules/.bin/zuul -- $(BROWSERTESTS)
|
|
24
24
|
|
|
25
25
|
test-browser-local:
|
|
26
26
|
./node_modules/.bin/zuul --no-coverage --local 4000 -- $(BROWSERTESTS)
|
package/Readme.md
CHANGED
|
@@ -14,15 +14,15 @@ node:
|
|
|
14
14
|
$ npm install superagent
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Works with [browserify](https://github.com/substack/node-browserify) and
|
|
17
|
+
Works with [browserify](https://github.com/substack/node-browserify) and [webpack](https://github.com/visionmedia/superagent/wiki/SuperAgent-for-Webpack).
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
20
|
request
|
|
21
21
|
.post('/api/pet')
|
|
22
22
|
.send({ name: 'Manny', species: 'cat' }) // sends a JSON post body
|
|
23
23
|
.set('X-API-Key', 'foobar')
|
|
24
|
-
.set('
|
|
25
|
-
.end(
|
|
24
|
+
.set('accept', 'json')
|
|
25
|
+
.end((err, res) => {
|
|
26
26
|
// Calling the end function will send the request
|
|
27
27
|
});
|
|
28
28
|
```
|
|
@@ -33,27 +33,25 @@ Tested browsers:
|
|
|
33
33
|
|
|
34
34
|
- Latest Firefox, Chrome, Safari
|
|
35
35
|
- Latest Android, iPhone
|
|
36
|
-
- IE10 through latest. IE9 with polyfills.
|
|
37
|
-
|
|
38
|
-
Even though IE9 is supported, a polyfill for `window.FormData` is required for `.field()`.
|
|
36
|
+
- IE10 through latest. IE9 with polyfills. Even though IE9 is supported, a polyfill for `window.FormData` is required for `.field()`.
|
|
39
37
|
|
|
40
38
|
Node 4 or later is required.
|
|
41
39
|
|
|
42
|
-
|
|
40
|
+
## Plugins
|
|
43
41
|
|
|
44
42
|
SuperAgent is easily extended via plugins.
|
|
45
43
|
|
|
46
44
|
```js
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
const nocache = require('superagent-no-cache');
|
|
46
|
+
const request = require('superagent');
|
|
47
|
+
const prefix = require('superagent-prefix')('/static');
|
|
50
48
|
|
|
51
49
|
request
|
|
52
50
|
.get('/some-url')
|
|
53
51
|
.query({ action: 'edit', city: 'London' }) // query string
|
|
54
52
|
.use(prefix) // Prefixes *only* this request
|
|
55
53
|
.use(nocache) // Prevents caching of *only* this request
|
|
56
|
-
.end(
|
|
54
|
+
.end((err, res) => {
|
|
57
55
|
// Do something
|
|
58
56
|
});
|
|
59
57
|
```
|
|
@@ -77,6 +75,20 @@ Please prefix your plugin with `superagent-*` so that it can easily be found by
|
|
|
77
75
|
|
|
78
76
|
For SuperAgent extensions such as couchdb and oauth visit the [wiki](https://github.com/visionmedia/superagent/wiki).
|
|
79
77
|
|
|
78
|
+
## Upgrading from previous versions:
|
|
79
|
+
|
|
80
|
+
Our breaking changes are mostly in rarely used functionality and from stricter error handling.
|
|
81
|
+
|
|
82
|
+
* [2.x to 3.x](https://github.com/visionmedia/superagent/releases/tag/v3.0.0):
|
|
83
|
+
- Ensure you're running Node 4 or later. We dropped support for Node 0.x.
|
|
84
|
+
- Test code that calls `.send()` multiple times. Invalid calls to `.send()` will now throw instead of sending garbage.
|
|
85
|
+
* [1.x to 2.x](https://github.com/visionmedia/superagent/releases/tag/v2.0.0):
|
|
86
|
+
- If you use `.parse()` in the *browser* version, rename it to `.serialize()`.
|
|
87
|
+
- If you rely on `undefined` in query-string values being sent literally as the text "undefined", switch to checking for missing value instead. `?key=undefined` is now `?key` (without a value).
|
|
88
|
+
- If you use `.then()` in Internet Explorer, ensure that you have a polyfill that adds a global `Promise` object.
|
|
89
|
+
* 0.x to 1.x:
|
|
90
|
+
- Use `.end(function(err, res){})`. 1-argument version is no longer supported.
|
|
91
|
+
|
|
80
92
|
## Running node tests
|
|
81
93
|
|
|
82
94
|
Install dependencies:
|
package/docs/index.md
CHANGED
|
@@ -178,7 +178,7 @@ SuperAgent formats are extensible, however by default "json" and "form" are supp
|
|
|
178
178
|
.send({ name: 'tj' })
|
|
179
179
|
.send({ pet: 'tobi' })
|
|
180
180
|
.end(callback)
|
|
181
|
-
|
|
181
|
+
|
|
182
182
|
Sending a [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData) object is also supported. The following example will __POST__ the content of the HTML form identified by id="myForm":
|
|
183
183
|
|
|
184
184
|
request.post('/user')
|
|
@@ -467,6 +467,8 @@ The Node client allows you to pipe data to and from the request. For example pip
|
|
|
467
467
|
const req = request.post('/somewhere');
|
|
468
468
|
req.type('json');
|
|
469
469
|
stream.pipe(req);
|
|
470
|
+
|
|
471
|
+
Note that when you pipe to a request, superagent sends the piped data with [chunked transfer encoding](https://en.wikipedia.org/wiki/Chunked_transfer_encoding), which isn't supported by all servers (for instance, Python WSGI servers).
|
|
470
472
|
|
|
471
473
|
Or piping the response to a file:
|
|
472
474
|
|
|
@@ -478,20 +480,28 @@ Or piping the response to a file:
|
|
|
478
480
|
|
|
479
481
|
SuperAgent is also great for _building_ multipart requests for which it provides methods `.attach()` and `.field()`.
|
|
480
482
|
|
|
483
|
+
When you use `.field()` or `.attach()` you can't use `.send()` and you *must not* set `Content-Type` (the correct type will be set for you).
|
|
484
|
+
|
|
481
485
|
### Attaching files
|
|
482
486
|
|
|
483
|
-
|
|
487
|
+
To send a file use `.attach(name, [file], [options])`. You can attach multiple files by calling `.attach` multiple times. The arguments are:
|
|
488
|
+
|
|
489
|
+
* `name` — filed name in the form.
|
|
490
|
+
* `file` — either string with file path or `Blob`/`Buffer` object.
|
|
491
|
+
* `options` — (optional) either string with custom file name or `{filename: string}` object. In Node also `{contentType: 'mime/type'}` is supported. In browser create a `Blob` with an appropriate type instead.
|
|
492
|
+
|
|
493
|
+
<br>
|
|
484
494
|
|
|
485
495
|
request
|
|
486
496
|
.post('/upload')
|
|
487
|
-
.attach('
|
|
488
|
-
.attach('
|
|
489
|
-
.
|
|
497
|
+
.attach('image1', 'path/to/felix.jpeg')
|
|
498
|
+
.attach('image2', imageBuffer, 'luna.jpeg')
|
|
499
|
+
.field('caption', 'My cats')
|
|
490
500
|
.end(callback);
|
|
491
501
|
|
|
492
502
|
### Field values
|
|
493
503
|
|
|
494
|
-
Much like form fields in HTML, you can set field values with
|
|
504
|
+
Much like form fields in HTML, you can set field values with `.field(name, value)` and `.field({name: value})`. Suppose you want to upload a few images with your name and email, your request might look something like this:
|
|
495
505
|
|
|
496
506
|
request
|
|
497
507
|
.post('/upload')
|
package/lib/client.js
CHANGED
|
@@ -220,11 +220,12 @@ function parseHeader(str) {
|
|
|
220
220
|
var field;
|
|
221
221
|
var val;
|
|
222
222
|
|
|
223
|
-
lines.pop(); // trailing CRLF
|
|
224
|
-
|
|
225
223
|
for (var i = 0, len = lines.length; i < len; ++i) {
|
|
226
224
|
line = lines[i];
|
|
227
225
|
index = line.indexOf(':');
|
|
226
|
+
if (index === -1) { // could be empty line, just skip it
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
228
229
|
field = line.slice(0, index).toLowerCase();
|
|
229
230
|
val = trim(line.slice(index + 1));
|
|
230
231
|
fields[field] = val;
|
|
@@ -420,16 +421,16 @@ function Request(method, url) {
|
|
|
420
421
|
try {
|
|
421
422
|
if (!self._isResponseOK(res)) {
|
|
422
423
|
new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
|
|
423
|
-
new_err.original = err;
|
|
424
|
-
new_err.response = res;
|
|
425
|
-
new_err.status = res.status;
|
|
426
424
|
}
|
|
427
|
-
} catch(
|
|
428
|
-
new_err =
|
|
425
|
+
} catch(custom_err) {
|
|
426
|
+
new_err = custom_err; // ok() callback can throw
|
|
429
427
|
}
|
|
430
428
|
|
|
431
429
|
// #1000 don't catch errors from the callback to avoid double calling it
|
|
432
430
|
if (new_err) {
|
|
431
|
+
new_err.original = err;
|
|
432
|
+
new_err.response = res;
|
|
433
|
+
new_err.status = res.status;
|
|
433
434
|
self.callback(new_err, res);
|
|
434
435
|
} else {
|
|
435
436
|
self.callback(null, res);
|
package/lib/is-object.js
CHANGED
package/lib/node/agent.js
CHANGED
package/lib/node/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use strict';
|
|
1
2
|
|
|
2
3
|
/**
|
|
3
4
|
* Module dependencies.
|
|
@@ -70,7 +71,7 @@ exports.Response = Response;
|
|
|
70
71
|
|
|
71
72
|
mime.define({
|
|
72
73
|
'application/x-www-form-urlencoded': ['form', 'urlencoded', 'form-data']
|
|
73
|
-
});
|
|
74
|
+
}, true);
|
|
74
75
|
|
|
75
76
|
/**
|
|
76
77
|
* Protocol map.
|
|
@@ -675,16 +676,20 @@ Request.prototype.callback = function(err, res){
|
|
|
675
676
|
this.called = true;
|
|
676
677
|
|
|
677
678
|
if (!err) {
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
679
|
+
try {
|
|
680
|
+
if (this._isResponseOK(res)) {
|
|
681
|
+
return fn(err, res);
|
|
682
|
+
}
|
|
681
683
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
684
|
+
var msg = 'Unsuccessful HTTP response';
|
|
685
|
+
if (res) {
|
|
686
|
+
msg = http.STATUS_CODES[res.status] || msg;
|
|
687
|
+
}
|
|
688
|
+
err = new Error(msg);
|
|
689
|
+
err.status = res ? res.status : undefined;
|
|
690
|
+
} catch (new_err) {
|
|
691
|
+
err = new_err;
|
|
685
692
|
}
|
|
686
|
-
err = new Error(msg);
|
|
687
|
-
err.status = res ? res.status : undefined;
|
|
688
693
|
}
|
|
689
694
|
|
|
690
695
|
err.response = res;
|
|
@@ -845,6 +850,24 @@ Request.prototype._end = function() {
|
|
|
845
850
|
}
|
|
846
851
|
|
|
847
852
|
var parserHandlesEnd = false;
|
|
853
|
+
if (buffer) {
|
|
854
|
+
// Protectiona against zip bombs and other nuisance
|
|
855
|
+
let responseBytesLeft = self._maxResponseSize || 200000000;
|
|
856
|
+
res.on('data', function(buf) {
|
|
857
|
+
responseBytesLeft -= buf.byteLength || buf.length;
|
|
858
|
+
if (responseBytesLeft < 0) {
|
|
859
|
+
// This will propagate through error event
|
|
860
|
+
const err = Error("Maximum response size reached");
|
|
861
|
+
err.code = "ETOOLARGE";
|
|
862
|
+
// Parsers aren't required to observe error event,
|
|
863
|
+
// so would incorrectly report success
|
|
864
|
+
parserHandlesEnd = false;
|
|
865
|
+
// Will emit error event
|
|
866
|
+
res.destroy(err);
|
|
867
|
+
}
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
|
|
848
871
|
if (parser) {
|
|
849
872
|
try {
|
|
850
873
|
// Unbuffered parsers are supposed to emit response early,
|
|
@@ -890,6 +913,7 @@ Request.prototype._end = function() {
|
|
|
890
913
|
|
|
891
914
|
// terminating events
|
|
892
915
|
res.once('error', function(err){
|
|
916
|
+
parserHandlesEnd = false;
|
|
893
917
|
self.callback(err, null);
|
|
894
918
|
});
|
|
895
919
|
if (!parserHandlesEnd) res.once('end', function(){
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use strict';
|
|
1
2
|
|
|
2
3
|
exports['application/x-www-form-urlencoded'] = require('./urlencoded');
|
|
3
4
|
exports['application/json'] = require('./json');
|
|
@@ -5,4 +6,5 @@ exports.text = require('./text');
|
|
|
5
6
|
|
|
6
7
|
var binary = require('./image');
|
|
7
8
|
exports['application/octet-stream'] = binary;
|
|
9
|
+
exports['application/pdf'] = binary;
|
|
8
10
|
exports.image = binary;
|
package/lib/node/parsers/json.js
CHANGED
package/lib/node/parsers/text.js
CHANGED
package/lib/node/response.js
CHANGED
package/lib/node/unzip.js
CHANGED
package/lib/request-base.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Module of mixed-in functions shared between node and client code
|
|
3
5
|
*/
|
|
@@ -413,6 +415,21 @@ RequestBase.prototype.redirects = function(n){
|
|
|
413
415
|
return this;
|
|
414
416
|
};
|
|
415
417
|
|
|
418
|
+
/**
|
|
419
|
+
* Maximum size of buffered response body, in bytes. Counts uncompressed size.
|
|
420
|
+
* Default 200MB.
|
|
421
|
+
*
|
|
422
|
+
* @param {Number} n
|
|
423
|
+
* @return {Request} for chaining
|
|
424
|
+
*/
|
|
425
|
+
RequestBase.prototype.maxResponseSize = function(n){
|
|
426
|
+
if ('number' !== typeof n) {
|
|
427
|
+
throw TypeError("Invalid argument");
|
|
428
|
+
}
|
|
429
|
+
this._maxResponseSize = n;
|
|
430
|
+
return this;
|
|
431
|
+
};
|
|
432
|
+
|
|
416
433
|
/**
|
|
417
434
|
* Convert to a plain javascript object (not JSON string) of scalar properties.
|
|
418
435
|
* Note as this method is designed to return a useful non-this value,
|
package/lib/response-base.js
CHANGED
package/lib/should-retry.js
CHANGED
package/lib/utils.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "superagent",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"description": "elegant & feature rich browser / node HTTP with a fluent API",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"prepublish": "make all",
|
|
@@ -26,25 +26,25 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"component-emitter": "^1.2.0",
|
|
28
28
|
"cookiejar": "^2.1.0",
|
|
29
|
-
"debug": "^
|
|
29
|
+
"debug": "^3.1.0",
|
|
30
30
|
"extend": "^3.0.0",
|
|
31
|
-
"form-data": "^2.
|
|
31
|
+
"form-data": "^2.3.1",
|
|
32
32
|
"formidable": "^1.1.1",
|
|
33
33
|
"methods": "^1.1.1",
|
|
34
|
-
"mime": "^1.
|
|
35
|
-
"qs": "^6.
|
|
34
|
+
"mime": "^1.4.1",
|
|
35
|
+
"qs": "^6.5.1",
|
|
36
36
|
"readable-stream": "^2.0.5"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"Base64": "^1.0.1",
|
|
40
40
|
"basic-auth-connect": "^1.0.0",
|
|
41
|
-
"body-parser": "^1.
|
|
41
|
+
"body-parser": "^1.18.2",
|
|
42
42
|
"browserify": "^14.1.0",
|
|
43
43
|
"cookie-parser": "^1.4.3",
|
|
44
|
-
"express": "^4.
|
|
45
|
-
"express-session": "^1.15.
|
|
44
|
+
"express": "^4.16.0",
|
|
45
|
+
"express-session": "^1.15.6",
|
|
46
46
|
"marked": "^0.3.6",
|
|
47
|
-
"mocha": "^3.
|
|
47
|
+
"mocha": "^3.5.3",
|
|
48
48
|
"multer": "^1.3.0",
|
|
49
49
|
"should": "^11.2.0",
|
|
50
50
|
"should-http": "^0.1.1",
|
package/superagent.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.superagent = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
2
4
|
/**
|
|
3
5
|
* Check if `obj` is an object.
|
|
4
6
|
*
|
|
@@ -14,6 +16,8 @@ function isObject(obj) {
|
|
|
14
16
|
module.exports = isObject;
|
|
15
17
|
|
|
16
18
|
},{}],2:[function(require,module,exports){
|
|
19
|
+
'use strict';
|
|
20
|
+
|
|
17
21
|
/**
|
|
18
22
|
* Module of mixed-in functions shared between node and client code
|
|
19
23
|
*/
|
|
@@ -429,6 +433,21 @@ RequestBase.prototype.redirects = function(n){
|
|
|
429
433
|
return this;
|
|
430
434
|
};
|
|
431
435
|
|
|
436
|
+
/**
|
|
437
|
+
* Maximum size of buffered response body, in bytes. Counts uncompressed size.
|
|
438
|
+
* Default 200MB.
|
|
439
|
+
*
|
|
440
|
+
* @param {Number} n
|
|
441
|
+
* @return {Request} for chaining
|
|
442
|
+
*/
|
|
443
|
+
RequestBase.prototype.maxResponseSize = function(n){
|
|
444
|
+
if ('number' !== typeof n) {
|
|
445
|
+
throw TypeError("Invalid argument");
|
|
446
|
+
}
|
|
447
|
+
this._maxResponseSize = n;
|
|
448
|
+
return this;
|
|
449
|
+
};
|
|
450
|
+
|
|
432
451
|
/**
|
|
433
452
|
* Convert to a plain javascript object (not JSON string) of scalar properties.
|
|
434
453
|
* Note as this method is designed to return a useful non-this value,
|
|
@@ -636,6 +655,7 @@ RequestBase.prototype._setTimeouts = function() {
|
|
|
636
655
|
}
|
|
637
656
|
|
|
638
657
|
},{"./is-object":1}],3:[function(require,module,exports){
|
|
658
|
+
'use strict';
|
|
639
659
|
|
|
640
660
|
/**
|
|
641
661
|
* Module dependencies.
|
|
@@ -771,6 +791,8 @@ ResponseBase.prototype._setStatusProperties = function(status){
|
|
|
771
791
|
};
|
|
772
792
|
|
|
773
793
|
},{"./utils":5}],4:[function(require,module,exports){
|
|
794
|
+
'use strict';
|
|
795
|
+
|
|
774
796
|
var ERROR_CODES = [
|
|
775
797
|
'ECONNRESET',
|
|
776
798
|
'ETIMEDOUT',
|
|
@@ -796,6 +818,7 @@ module.exports = function shouldRetry(err, res) {
|
|
|
796
818
|
};
|
|
797
819
|
|
|
798
820
|
},{}],5:[function(require,module,exports){
|
|
821
|
+
'use strict';
|
|
799
822
|
|
|
800
823
|
/**
|
|
801
824
|
* Return the mime type for the given `str`.
|
|
@@ -864,6 +887,7 @@ exports.cleanHeader = function(header, shouldStripCookie){
|
|
|
864
887
|
}
|
|
865
888
|
return header;
|
|
866
889
|
};
|
|
890
|
+
|
|
867
891
|
},{}],6:[function(require,module,exports){
|
|
868
892
|
|
|
869
893
|
/**
|
|
@@ -1252,11 +1276,12 @@ function parseHeader(str) {
|
|
|
1252
1276
|
var field;
|
|
1253
1277
|
var val;
|
|
1254
1278
|
|
|
1255
|
-
lines.pop(); // trailing CRLF
|
|
1256
|
-
|
|
1257
1279
|
for (var i = 0, len = lines.length; i < len; ++i) {
|
|
1258
1280
|
line = lines[i];
|
|
1259
1281
|
index = line.indexOf(':');
|
|
1282
|
+
if (index === -1) { // could be empty line, just skip it
|
|
1283
|
+
continue;
|
|
1284
|
+
}
|
|
1260
1285
|
field = line.slice(0, index).toLowerCase();
|
|
1261
1286
|
val = trim(line.slice(index + 1));
|
|
1262
1287
|
fields[field] = val;
|
|
@@ -1452,16 +1477,16 @@ function Request(method, url) {
|
|
|
1452
1477
|
try {
|
|
1453
1478
|
if (!self._isResponseOK(res)) {
|
|
1454
1479
|
new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
|
|
1455
|
-
new_err.original = err;
|
|
1456
|
-
new_err.response = res;
|
|
1457
|
-
new_err.status = res.status;
|
|
1458
1480
|
}
|
|
1459
|
-
} catch(
|
|
1460
|
-
new_err =
|
|
1481
|
+
} catch(custom_err) {
|
|
1482
|
+
new_err = custom_err; // ok() callback can throw
|
|
1461
1483
|
}
|
|
1462
1484
|
|
|
1463
1485
|
// #1000 don't catch errors from the callback to avoid double calling it
|
|
1464
1486
|
if (new_err) {
|
|
1487
|
+
new_err.original = err;
|
|
1488
|
+
new_err.response = res;
|
|
1489
|
+
new_err.status = res.status;
|
|
1465
1490
|
self.callback(new_err, res);
|
|
1466
1491
|
} else {
|
|
1467
1492
|
self.callback(null, res);
|