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.

Files changed (3) hide show
  1. package/README.md +2 -0
  2. package/index.js +74 -53
  3. 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
- delete this._options;
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.0",
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.4.0",
51
- "concat-stream": "^1.5.2",
50
+ "bluebird": "^3.5.1",
51
+ "concat-stream": "^1.6.0",
52
52
  "coveralls": "^3.0.0",
53
- "eslint": "^4.14.0",
54
- "express": "^4.13.0",
55
- "mocha": "^4.0.1",
56
- "nyc": "^11.3.0"
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": {