| //Based on follow-redirects v0.0.x |
| |
| var nativeHttps = require('https'), |
| nativeHttp = require('http'), |
| url = require('url'), |
| util = require('./util'); |
| |
| var maxRedirects = module.exports.maxRedirects = 5; |
| |
| var protocols = { |
| https: nativeHttps, |
| http: nativeHttp |
| }; |
| |
| for (var protocol in protocols) { |
| var h = function() {}; |
| h.prototype = protocols[protocol]; |
| h = new h(); |
| |
| h.request = function(h) { |
| return function(options, callback, redirectOptions) { |
| |
| redirectOptions = redirectOptions || {}; |
| |
| var max = (typeof options === 'object' && 'maxRedirects' in options) ? options.maxRedirects : exports.maxRedirects; |
| |
| var redirect = util.extend({ |
| count: 0, |
| max: max, |
| clientRequest: null, |
| userCallback: callback |
| }, redirectOptions); |
| |
| if (redirect.count > redirect.max) { |
| var err = new Error('Max redirects exceeded. To allow more redirects, pass options.maxRedirects property.'); |
| redirect.clientRequest.emit('error', err); |
| return redirect.clientRequest; |
| } |
| |
| redirect.count++; |
| |
| var reqUrl; |
| if (typeof options === 'string') { |
| reqUrl = options; |
| } else { |
| reqUrl = url.format(util.extend({ |
| protocol: protocol |
| }, options)); |
| } |
| |
| var clientRequest = Object.getPrototypeOf(h).request(options, redirectCallback(reqUrl, redirect)); |
| |
| if (!redirect.clientRequest) redirect.clientRequest = clientRequest; |
| |
| function redirectCallback(reqUrl, redirect) { |
| return function(res) { |
| if (res.statusCode < 300 || res.statusCode > 399) { |
| return redirect.userCallback(res); |
| } |
| |
| if (!('location' in res.headers)) { |
| return redirect.userCallback(res); |
| } |
| |
| var redirectUrl = url.resolve(reqUrl, res.headers.location); |
| |
| var proto = url.parse(redirectUrl).protocol; |
| proto = proto.substr(0, proto.length - 1); |
| return module.exports[proto].get(redirectUrl, redirectCallback(reqUrl, redirect), redirect); |
| }; |
| } |
| |
| return clientRequest; |
| }; |
| }(h); |
| |
| // see https://github.com/joyent/node/blob/master/lib/http.js#L1623 |
| h.get = function(h) { |
| return function(options, cb, redirectOptions) { |
| var req = h.request(options, cb, redirectOptions); |
| req.end(); |
| return req; |
| }; |
| }(h); |
| |
| module.exports[protocol] = h; |
| } |