Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

follow-redirects

Package Overview
Dependencies
Maintainers
3
Versions
68
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

follow-redirects - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

171

index.js

@@ -1,4 +0,169 @@

module.exports = require('./create')({
http: require('http'),
https: require('https')
'use strict';
var url = require('url');
var assert = require('assert');
var http = require('http');
var https = require('https');
var Writable = require('stream').Writable;
var debug = require('debug')('follow-redirects');
var nativeProtocols = {'http:': http, 'https:': https};
var publicApi = module.exports = {
maxRedirects: 21
};
// Wrapper around the native request
function RequestProxy() {
Writable.call(this);
}
RequestProxy.prototype = Object.create(Writable.prototype);
RequestProxy.prototype.abort = function () {
this._request.abort();
};
RequestProxy.prototype.end = function (data, encoding, callback) {
this._request.end(data, encoding, callback);
};
RequestProxy.prototype.flushHeaders = function () {
this._request.flushHeaders();
};
RequestProxy.prototype.setNoDelay = function (noDelay) {
this._request.setNoDelay(noDelay);
};
RequestProxy.prototype.setSocketKeepAlive = function (enable, initialDelay) {
this._request.setSocketKeepAlive(enable, initialDelay);
};
RequestProxy.prototype.setTimeout = function (timeout, callback) {
this._request.setSocketKeepAlive(timeout, callback);
};
RequestProxy.prototype._write = function (chunk, encoding, callback) {
this._request.write(chunk, encoding, callback);
};
function execute(options, callback) {
var fetchedUrls = [];
var requestProxy = new RequestProxy();
if (callback) {
requestProxy.on('response', callback);
}
cb();
return requestProxy;
function cb(res) {
// skip the redirection logic on the first call.
if (res) {
var fetchedUrl = url.format(options);
fetchedUrls.unshift(fetchedUrl);
if (!isRedirect(res)) {
res.fetchedUrls = fetchedUrls;
requestProxy.emit('response', res);
return;
}
// need to use url.resolve() in case location is a relative URL
var redirectUrl = url.resolve(fetchedUrl, res.headers.location);
debug('redirecting to', redirectUrl);
extend(options, url.parse(redirectUrl));
}
if (fetchedUrls.length > options.maxRedirects) {
var err = new Error('Max redirects exceeded.');
requestProxy.emit('error', err);
return;
}
options.nativeProtocol = nativeProtocols[options.protocol];
options.defaultRequest = defaultMakeRequest;
var req = (options.makeRequest || defaultMakeRequest)(options, cb, res);
requestProxy._request = req;
mirrorEvent(req, 'abort');
mirrorEvent(req, 'aborted');
mirrorEvent(req, 'error');
return req;
}
function defaultMakeRequest(options, cb, res) {
if (res && res.statusCode !== 307) {
// This is a redirect, so use only GET methods, except for status 307,
// which must honor the previous request method.
options.method = 'GET';
}
var req = options.nativeProtocol.request(options, cb);
if (res) {
// We leave the user to call `end` on the first request
req.end();
}
return req;
}
// send events through the proxy
function mirrorEvent(req, event) {
req.on(event, function (arg) {
requestProxy.emit(event, arg);
});
}
}
// returns a safe copy of options (or a parsed url object if options was a string).
// validates that the supplied callback is a function
function parseOptions(options, wrappedProtocol) {
if (typeof options === 'string') {
options = url.parse(options);
options.maxRedirects = publicApi.maxRedirects;
} else {
options = extend({
maxRedirects: publicApi.maxRedirects,
protocol: wrappedProtocol
}, options);
}
assert.equal(options.protocol, wrappedProtocol, 'protocol mismatch');
debug('options', options);
return options;
}
// copies source's own properties onto destination and returns destination
function extend(destination, source) {
var keys = Object.keys(source);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
destination[key] = source[key];
}
return destination;
}
// to redirect the result must have
// a statusCode between 300-399
// and a `Location` header
function isRedirect(res) {
return (res.statusCode >= 300 && res.statusCode <= 399 &&
'location' in res.headers);
}
Object.keys(nativeProtocols).forEach(function (wrappedProtocol) {
var scheme = wrappedProtocol.substr(0, wrappedProtocol.length - 1);
var nativeProtocol = nativeProtocols[wrappedProtocol];
var protocol = publicApi[scheme] = Object.create(nativeProtocol);
protocol.request = function (options, callback) {
return execute(parseOptions(options, wrappedProtocol), callback);
};
// see https://github.com/joyent/node/blob/master/lib/http.js#L1623
protocol.get = function (options, callback) {
var req = execute(parseOptions(options, wrappedProtocol), callback);
req.end();
return req;
};
});

13

package.json
{
"name": "follow-redirects",
"version": "0.2.0",
"version": "0.3.0",
"description": "HTTP and HTTPS modules that follow redirects.",

@@ -41,4 +41,3 @@ "main": "index.js",

"dependencies": {
"debug": "^2.2.0",
"stream-consume": "^0.1.0"
"debug": "^2.2.0"
},

@@ -50,6 +49,6 @@ "devDependencies": {

"express": "^4.13.0",
"mocha": "^2.2.5",
"nyc": "^6.4.4",
"semver": "~5.1.0",
"xo": "^0.15.1"
"mocha": "^3.1.2",
"nyc": "^8.3.1",
"semver": "^5.3.0",
"xo": "^0.17.0"
},

@@ -56,0 +55,0 @@ "license": "MIT",

@@ -5,2 +5,3 @@ ## Follow Redirects

[![npm version](https://badge.fury.io/js/follow-redirects.svg)](https://www.npmjs.com/package/follow-redirects)
[![Build Status](https://travis-ci.org/olalonde/follow-redirects.svg?branch=master)](https://travis-ci.org/olalonde/follow-redirects)

@@ -7,0 +8,0 @@ [![Coverage Status](https://coveralls.io/repos/olalonde/follow-redirects/badge.svg?branch=master)](https://coveralls.io/r/olalonde/follow-redirects?branch=master)

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc