follow-redirects 1.3.0 → 1.5.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.
Potentially problematic release.
This version of follow-redirects might be problematic. Click here for more details.
- package/README.md +2 -0
- package/index.js +74 -53
- package/package.json +7 -7
package/README.md
CHANGED
@@ -79,6 +79,8 @@ the following per-request options are supported:
|
|
79
79
|
|
80
80
|
- `agents` (default: `undefined`) – sets the `agent` option per protocol, since HTTP and HTTPS use different agents. Example value: `{ http: new http.Agent(), https: new https.Agent() }`
|
81
81
|
|
82
|
+
- `trackRedirects` (default: `false`) – whether to store the redirected response details into the `redirects` array on the response object.
|
83
|
+
|
82
84
|
|
83
85
|
### Advanced usage
|
84
86
|
By default, `follow-redirects` will use the Node.js default implementations
|
package/index.js
CHANGED
@@ -21,8 +21,10 @@ var eventHandlers = Object.create(null);
|
|
21
21
|
function RedirectableRequest(options, responseCallback) {
|
22
22
|
// Initialize the request
|
23
23
|
Writable.call(this);
|
24
|
+
options.headers = options.headers || {};
|
24
25
|
this._options = options;
|
25
26
|
this._redirectCount = 0;
|
27
|
+
this._redirects = [];
|
26
28
|
this._requestBodyLength = 0;
|
27
29
|
this._requestBodyBuffers = [];
|
28
30
|
|
@@ -54,6 +56,64 @@ function RedirectableRequest(options, responseCallback) {
|
|
54
56
|
}
|
55
57
|
RedirectableRequest.prototype = Object.create(Writable.prototype);
|
56
58
|
|
59
|
+
// Writes buffered data to the current native request
|
60
|
+
RedirectableRequest.prototype.write = function (data, encoding, callback) {
|
61
|
+
if (!(typeof data === "string" || typeof data === "object" && ("length" in data))) {
|
62
|
+
throw new Error("data should be a string, Buffer or Uint8Array");
|
63
|
+
}
|
64
|
+
if (this._requestBodyLength + data.length <= this._options.maxBodyLength) {
|
65
|
+
this._requestBodyLength += data.length;
|
66
|
+
this._requestBodyBuffers.push({ data: data, encoding: encoding });
|
67
|
+
this._currentRequest.write(data, encoding, callback);
|
68
|
+
}
|
69
|
+
else {
|
70
|
+
this.emit("error", new Error("Request body larger than maxBodyLength limit"));
|
71
|
+
this.abort();
|
72
|
+
}
|
73
|
+
};
|
74
|
+
|
75
|
+
// Ends the current native request
|
76
|
+
RedirectableRequest.prototype.end = function (data, encoding, callback) {
|
77
|
+
var currentRequest = this._currentRequest;
|
78
|
+
if (!data) {
|
79
|
+
currentRequest.end(null, null, callback);
|
80
|
+
}
|
81
|
+
else {
|
82
|
+
this.write(data, encoding, function () {
|
83
|
+
currentRequest.end(null, null, callback);
|
84
|
+
});
|
85
|
+
}
|
86
|
+
};
|
87
|
+
|
88
|
+
// Sets a header value on the current native request
|
89
|
+
RedirectableRequest.prototype.setHeader = function (name, value) {
|
90
|
+
this._options.headers[name] = value;
|
91
|
+
this._currentRequest.setHeader(name, value);
|
92
|
+
};
|
93
|
+
|
94
|
+
// Clears a header value on the current native request
|
95
|
+
RedirectableRequest.prototype.removeHeader = function (name) {
|
96
|
+
delete this._options.headers[name];
|
97
|
+
this._currentRequest.removeHeader(name);
|
98
|
+
};
|
99
|
+
|
100
|
+
// Proxy all other public ClientRequest methods
|
101
|
+
[
|
102
|
+
"abort", "flushHeaders", "getHeader",
|
103
|
+
"setNoDelay", "setSocketKeepAlive", "setTimeout",
|
104
|
+
].forEach(function (method) {
|
105
|
+
RedirectableRequest.prototype[method] = function (a, b) {
|
106
|
+
return this._currentRequest[method](a, b);
|
107
|
+
};
|
108
|
+
});
|
109
|
+
|
110
|
+
// Proxy all public ClientRequest properties
|
111
|
+
["aborted", "connection", "socket"].forEach(function (property) {
|
112
|
+
Object.defineProperty(RedirectableRequest.prototype, property, {
|
113
|
+
get: function () { return this._currentRequest[property]; },
|
114
|
+
});
|
115
|
+
});
|
116
|
+
|
57
117
|
// Executes the next native request (initial or redirect)
|
58
118
|
RedirectableRequest.prototype._performRequest = function () {
|
59
119
|
// Load the native protocol
|
@@ -100,6 +160,15 @@ RedirectableRequest.prototype._performRequest = function () {
|
|
100
160
|
|
101
161
|
// Processes a response from the current native request
|
102
162
|
RedirectableRequest.prototype._processResponse = function (response) {
|
163
|
+
// Store the redirected response
|
164
|
+
if (this._options.trackRedirects) {
|
165
|
+
this._redirects.push({
|
166
|
+
url: this._currentUrl,
|
167
|
+
headers: response.headers,
|
168
|
+
statusCode: response.statusCode,
|
169
|
+
});
|
170
|
+
}
|
171
|
+
|
103
172
|
// RFC7231§6.4: The 3xx (Redirection) class of status code indicates
|
104
173
|
// that further action needs to be taken by the user agent in order to
|
105
174
|
// fulfill the request. If a Location header field is provided,
|
@@ -151,66 +220,18 @@ RedirectableRequest.prototype._processResponse = function (response) {
|
|
151
220
|
Object.assign(this._options, url.parse(redirectUrl));
|
152
221
|
this._isRedirect = true;
|
153
222
|
this._performRequest();
|
223
|
+
|
224
|
+
// Discard the remainder of the response to avoid waiting for data
|
225
|
+
response.destroy();
|
154
226
|
}
|
155
227
|
else {
|
156
228
|
// The response is not a redirect; return it as-is
|
157
229
|
response.responseUrl = this._currentUrl;
|
230
|
+
response.redirects = this._redirects;
|
158
231
|
this.emit("response", response);
|
159
232
|
|
160
233
|
// Clean up
|
161
|
-
|
162
|
-
delete this._requestBodyBuffers;
|
163
|
-
}
|
164
|
-
};
|
165
|
-
|
166
|
-
// Aborts the current native request
|
167
|
-
RedirectableRequest.prototype.abort = function () {
|
168
|
-
this._currentRequest.abort();
|
169
|
-
};
|
170
|
-
|
171
|
-
// Flushes the headers of the current native request
|
172
|
-
RedirectableRequest.prototype.flushHeaders = function () {
|
173
|
-
this._currentRequest.flushHeaders();
|
174
|
-
};
|
175
|
-
|
176
|
-
// Sets the noDelay option of the current native request
|
177
|
-
RedirectableRequest.prototype.setNoDelay = function (noDelay) {
|
178
|
-
this._currentRequest.setNoDelay(noDelay);
|
179
|
-
};
|
180
|
-
|
181
|
-
// Sets the socketKeepAlive option of the current native request
|
182
|
-
RedirectableRequest.prototype.setSocketKeepAlive = function (enable, initialDelay) {
|
183
|
-
this._currentRequest.setSocketKeepAlive(enable, initialDelay);
|
184
|
-
};
|
185
|
-
|
186
|
-
// Sets the timeout option of the current native request
|
187
|
-
RedirectableRequest.prototype.setTimeout = function (timeout, callback) {
|
188
|
-
this._currentRequest.setTimeout(timeout, callback);
|
189
|
-
};
|
190
|
-
|
191
|
-
// Writes buffered data to the current native request
|
192
|
-
RedirectableRequest.prototype.write = function (data, encoding, callback) {
|
193
|
-
if (this._requestBodyLength + data.length <= this._options.maxBodyLength) {
|
194
|
-
this._requestBodyLength += data.length;
|
195
|
-
this._requestBodyBuffers.push({ data: data, encoding: encoding });
|
196
|
-
this._currentRequest.write(data, encoding, callback);
|
197
|
-
}
|
198
|
-
else {
|
199
|
-
this.emit("error", new Error("Request body larger than maxBodyLength limit"));
|
200
|
-
this.abort();
|
201
|
-
}
|
202
|
-
};
|
203
|
-
|
204
|
-
// Ends the current native request
|
205
|
-
RedirectableRequest.prototype.end = function (data, encoding, callback) {
|
206
|
-
var currentRequest = this._currentRequest;
|
207
|
-
if (!data) {
|
208
|
-
currentRequest.end(null, null, callback);
|
209
|
-
}
|
210
|
-
else {
|
211
|
-
this.write(data, encoding, function () {
|
212
|
-
currentRequest.end(null, null, callback);
|
213
|
-
});
|
234
|
+
this._requestBodyBuffers = [];
|
214
235
|
}
|
215
236
|
};
|
216
237
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "follow-redirects",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.5.1",
|
4
4
|
"description": "HTTP and HTTPS modules that follow redirects.",
|
5
5
|
"main": "index.js",
|
6
6
|
"engines": {
|
@@ -47,13 +47,13 @@
|
|
47
47
|
"debug": "^3.1.0"
|
48
48
|
},
|
49
49
|
"devDependencies": {
|
50
|
-
"bluebird": "^3.
|
51
|
-
"concat-stream": "^1.
|
50
|
+
"bluebird": "^3.5.1",
|
51
|
+
"concat-stream": "^1.6.0",
|
52
52
|
"coveralls": "^3.0.0",
|
53
|
-
"eslint": "^4.
|
54
|
-
"express": "^4.
|
55
|
-
"mocha": "^
|
56
|
-
"nyc": "^11.
|
53
|
+
"eslint": "^4.19.1",
|
54
|
+
"express": "^4.16.2",
|
55
|
+
"mocha": "^5.0.0",
|
56
|
+
"nyc": "^11.8.0"
|
57
57
|
},
|
58
58
|
"license": "MIT",
|
59
59
|
"nyc": {
|