follow-redirects 1.13.2 → 1.14.2

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/debug.js +2 -1
  2. package/index.js +54 -27
  3. package/package.json +1 -1
package/debug.js CHANGED
@@ -6,7 +6,8 @@ module.exports = function () {
6
6
  /* eslint global-require: off */
7
7
  debug = require("debug")("follow-redirects");
8
8
  }
9
- catch (error) {
9
+ catch (error) { /* */ }
10
+ if (typeof debug !== "function") {
10
11
  debug = function () { /* */ };
11
12
  }
12
13
  }
package/index.js CHANGED
@@ -7,8 +7,9 @@ var assert = require("assert");
7
7
  var debug = require("./debug");
8
8
 
9
9
  // Create handlers that pass events from native requests
10
+ var events = ["abort", "aborted", "connect", "error", "socket", "timeout"];
10
11
  var eventHandlers = Object.create(null);
11
- ["abort", "aborted", "connect", "error", "socket", "timeout"].forEach(function (event) {
12
+ events.forEach(function (event) {
12
13
  eventHandlers[event] = function (arg1, arg2, arg3) {
13
14
  this._redirectable.emit(event, arg1, arg2, arg3);
14
15
  };
@@ -61,6 +62,11 @@ function RedirectableRequest(options, responseCallback) {
61
62
  }
62
63
  RedirectableRequest.prototype = Object.create(Writable.prototype);
63
64
 
65
+ RedirectableRequest.prototype.abort = function () {
66
+ abortRequest(this._currentRequest);
67
+ this.emit("abort");
68
+ };
69
+
64
70
  // Writes buffered data to the current native request
65
71
  RedirectableRequest.prototype.write = function (data, encoding, callback) {
66
72
  // Writing is not allowed if end has been called
@@ -140,40 +146,58 @@ RedirectableRequest.prototype.removeHeader = function (name) {
140
146
 
141
147
  // Global timeout for all underlying requests
142
148
  RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
149
+ var self = this;
143
150
  if (callback) {
144
- this.once("timeout", callback);
151
+ this.on("timeout", callback);
152
+ }
153
+
154
+ function destroyOnTimeout(socket) {
155
+ socket.setTimeout(msecs);
156
+ socket.removeListener("timeout", socket.destroy);
157
+ socket.addListener("timeout", socket.destroy);
158
+ }
159
+
160
+ // Sets up a timer to trigger a timeout event
161
+ function startTimer(socket) {
162
+ if (self._timeout) {
163
+ clearTimeout(self._timeout);
164
+ }
165
+ self._timeout = setTimeout(function () {
166
+ self.emit("timeout");
167
+ clearTimer();
168
+ }, msecs);
169
+ destroyOnTimeout(socket);
145
170
  }
146
171
 
172
+ // Prevent a timeout from triggering
173
+ function clearTimer() {
174
+ clearTimeout(this._timeout);
175
+ if (callback) {
176
+ self.removeListener("timeout", callback);
177
+ }
178
+ if (!this.socket) {
179
+ self._currentRequest.removeListener("socket", startTimer);
180
+ }
181
+ }
182
+
183
+ // Start the timer when the socket is opened
147
184
  if (this.socket) {
148
- startTimer(this, msecs);
185
+ startTimer(this.socket);
149
186
  }
150
187
  else {
151
- var self = this;
152
- this._currentRequest.once("socket", function () {
153
- startTimer(self, msecs);
154
- });
188
+ this._currentRequest.once("socket", startTimer);
155
189
  }
156
190
 
191
+ this.on("socket", destroyOnTimeout);
157
192
  this.once("response", clearTimer);
158
193
  this.once("error", clearTimer);
159
194
 
160
195
  return this;
161
196
  };
162
197
 
163
- function startTimer(request, msecs) {
164
- clearTimeout(request._timeout);
165
- request._timeout = setTimeout(function () {
166
- request.emit("timeout");
167
- }, msecs);
168
- }
169
-
170
- function clearTimer() {
171
- clearTimeout(this._timeout);
172
- }
173
-
174
198
  // Proxy all other public ClientRequest methods
175
199
  [
176
- "abort", "flushHeaders", "getHeader",
200
+ "flushHeaders", "getHeader",
177
201
  "setNoDelay", "setSocketKeepAlive",
178
202
  ].forEach(function (method) {
179
203
  RedirectableRequest.prototype[method] = function (a, b) {
@@ -243,11 +267,8 @@ RedirectableRequest.prototype._performRequest = function () {
243
267
 
244
268
  // Set up event handlers
245
269
  request._redirectable = this;
246
- for (var event in eventHandlers) {
247
- /* istanbul ignore else */
248
- if (event) {
249
- request.on(event, eventHandlers[event]);
250
- }
270
+ for (var e = 0; e < events.length; e++) {
271
+ request.on(events[e], eventHandlers[events[e]]);
251
272
  }
252
273
 
253
274
  // End a redirected request
@@ -305,9 +326,7 @@ RedirectableRequest.prototype._processResponse = function (response) {
305
326
  if (location && this._options.followRedirects !== false &&
306
327
  statusCode >= 300 && statusCode < 400) {
307
328
  // Abort the current request
308
- this._currentRequest.removeAllListeners();
309
- this._currentRequest.on("error", noop);
310
- this._currentRequest.abort();
329
+ abortRequest(this._currentRequest);
311
330
  // Discard the remainder of the response to avoid waiting for data
312
331
  response.destroy();
313
332
 
@@ -499,6 +518,14 @@ function createErrorType(code, defaultMessage) {
499
518
  return CustomError;
500
519
  }
501
520
 
521
+ function abortRequest(request) {
522
+ for (var e = 0; e < events.length; e++) {
523
+ request.removeListener(events[e], eventHandlers[events[e]]);
524
+ }
525
+ request.on("error", noop);
526
+ request.abort();
527
+ }
528
+
502
529
  // Exports
503
530
  module.exports = wrap({ http: http, https: https });
504
531
  module.exports.wrap = wrap;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "follow-redirects",
3
- "version": "1.13.2",
3
+ "version": "1.14.2",
4
4
  "description": "HTTP and HTTPS modules that follow redirects.",
5
5
  "license": "MIT",
6
6
  "main": "index.js",