diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7dccd97 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results + +node_modules +npm-debug.log \ No newline at end of file diff --git a/index.js b/index.js index 57dd3bc..543650e 100644 --- a/index.js +++ b/index.js @@ -3,7 +3,7 @@ var nativeHttps = require('https'), url = require('url'), _ = require('underscore'); -var maxRedirects = module.exports.maxRedirects = 5; +var maxRedirects = module.exports.maxRedirects = 1; var protocols = { https: nativeHttps, @@ -19,24 +19,24 @@ for (var protocol in protocols) { module.exports[protocol] = h; - h.get = function (options, callback, redirectOptions) { - var self = this, - userCallback = callback, - reqUrl; + h.request = function (options, callback, redirectOptions) { + + redirectOptions = redirectOptions || {}; var redirect = _.extend({ count: 0, max: options.maxRedirects || maxRedirects, - clientRequest: null + clientRequest: null, + userCallback: callback }, redirectOptions); /** * Emit error if too many redirects */ if (redirect.count > redirect.max) { - var err = new Error('Max redirects exceeded. To allow more redirects, set maxRedirects property.'); + var err = new Error('Max redirects exceeded. To allow more redirects, pass options.maxRedirects property.'); redirect.clientRequest.emit('error', err); - return; + return redirect.clientRequest; } redirect.count++; @@ -44,88 +44,59 @@ for (var protocol in protocols) { /** * Parse URL from options */ + var reqUrl; if (typeof options === 'string') { reqUrl = options; } else { - var urlFormat = _.extend({}, options); - urlFormat.protocol = protocol; - reqUrl = url.format(urlFormat); - console.log(reqUrl); + reqUrl = url.format(_.extend({ protocol: protocol }, options)); } /* * Build client request */ - var clientRequest = this.__proto__.get(options, redirectCallback); + var clientRequest = this.__proto__.request(options, redirectCallback(reqUrl, redirect)); - // save clientRequest to our redirectOptions so we can emit errors later + // Save user's clientRequest so we can emit errors later if (!redirect.clientRequest) redirect.clientRequest = clientRequest; /** * ClientRequest callback for redirects */ - function redirectCallback(res) { - // status must be 300-399 for redirects - if (res.statusCode < 300 || res.statusCode > 399) { - return userCallback(res); - } - // no `Location:` header => nowhere to redirect - if (!('location' in res.headers)) { - return userCallback(res); - } - // need to use url.resolve() in case location is a relative URL - var redirectUrl = url.resolve(reqUrl, res.headers['location']); - // we need to call the right api (http vs https) depending on protocol - var proto = url.parse(redirectUrl).protocol; - proto = proto.substr(0, proto.length - 1); - return module.exports[proto].get(redirectUrl, redirectCallback, redirect); + function redirectCallback (reqUrl, redirect) { + return function (res) { + // status must be 300-399 for redirects + if (res.statusCode < 300 || res.statusCode > 399) { + //console.log('[' + res.statusCode + '] callback user on url ' + reqUrl); + return redirect.userCallback(res); + } + + // no `Location:` header => nowhere to redirect + if (!('location' in res.headers)) { + //console.log('[no location header] callback user on url ' + reqUrl); + return redirect.userCallback(res); + } + + // save the original clientRequest to our redirectOptions so we can emit errors later + + // need to use url.resolve() in case location is a relative URL + var redirectUrl = url.resolve(reqUrl, res.headers['location']); + // we need to call the right api (http vs https) depending on protocol + var proto = url.parse(redirectUrl).protocol; + proto = proto.substr(0, proto.length - 1); + console.log('Redirecting from ' + reqUrl + ' to ' + redirectUrl); + return module.exports[proto].get(redirectUrl, redirectCallback(reqUrl, redirect), redirect); + }; } return clientRequest; - }; + } - //h.request = function () { - //console.log('oops'); - //} + // see https://github.com/joyent/node/blob/master/lib/http.js#L1623 + h.get = function (options, cb, redirectOptions) { + var req = this.request(options, cb, redirectOptions); + req.end(); + return req; + }; } - -//function resolve (opts, url) { - - //var redirectCount = 0, maxRedirects = 5; - //function get(fileUrl) { - //https.get(fileUrl, function(res) { - //console.log(fileUrl); - //if (res.statusCode >= 400) { - //return fn(new Error('URL ' + url + ' returns statusCode ' + res.statusCode + '.')); - //} - //// Follow redirects - //if (res.headers['location']) { - //if (redirectCount == maxRedirects) - //return fn(new Error('Maximum redirects reached.')); - - //var redirectUrl = url.resolve(fileUrl, res.headers['location']); - //redirectCount++; - //return get(redirectUrl); - //} - //var contentType = res.headers['content-type'], - //contentLength = res.headers['content-length']; - - //headers = utils.merge({ - //'Content-Length': contentLength, - //'Content-Type': contentType - //}, headers); - - //var req = self.putStream(res, filename, headers, fn); - //req.on('progress', emitter.emit.bind(emitter, 'progress')); - - //}).on('error', function(err) { - //fn(err); - //}); - //} - //get(fileUrl); - - -//} - diff --git a/test/index.js b/test/index.js index a1ed7d2..4dd236c 100644 --- a/test/index.js +++ b/test/index.js @@ -3,8 +3,10 @@ var https = require('../').https, nativeHttps = require('https'), nativeHttp = require('http'); +require('colors'); + var urls = [ - 'http://bit.ly/900913', + //'http://bit.ly/900913', { type: 'https', host: 'bitly.com', @@ -21,7 +23,7 @@ var libs = { follow: http }, https: { - native: nativeHttps, + //native: nativeHttps, follow: https } }; @@ -37,9 +39,13 @@ urls.forEach(function (url) { } for (var key in libs[proto]) { var lib = libs[proto][key]; + /** + * Test .get + */ + console.log((proto + '.' + 'get(' + url + ')').blue); lib.get(url, function(res) { - console.log("statusCode: ", res.statusCode); - console.log("headers: ", res.headers); + console.log('statusCode: ', res.statusCode); + console.log('headers: ', res.headers); res.on('data', function(d) { process.stdout.write(d); @@ -48,5 +54,24 @@ urls.forEach(function (url) { }).on('error', function(e) { console.error(e); }); + + /** + * Test .request + */ + //console.log((proto + '.' + 'request(' + url + ')').blue); + //var req = http.request(url, function(res) { + ////console.log('STATUS: ' + res.statusCode); + ////console.log('HEADERS: ' + JSON.stringify(res.headers)); + //res.setEncoding('utf8'); + //res.on('data', function (chunk) { + //console.log('BODY: ' + chunk); + //}); + //}); + + //req.on('error', function(e) { + //console.log('problem with request: ' + e.message); + //}); + + //req.end(); }; });