From f6e7a85555bbd1a70babf62b4d0c0ec674f3d2f5 Mon Sep 17 00:00:00 2001 From: plessbd Date: Fri, 24 Feb 2012 23:05:29 -0500 Subject: [PATCH 01/14] Updates redirect handling tested against http://jigsaw.w3.org/HTTP/300/ --- lib/node/index.js | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/lib/node/index.js b/lib/node/index.js index 76f773854..40ae0e195 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -1,4 +1,3 @@ - /*! * superagent * Copyright (c) 2011 TJ Holowaychuk @@ -124,6 +123,8 @@ function Request(method, url) { this.writable = true; this._redirects = 0; this.redirects(5); + this._redirectData = false; + this._redirectAuth = false; this._buffer = true; this.attachments = []; this.on('response', function(res){ @@ -169,6 +170,33 @@ Request.prototype.redirects = function(n){ return this; }; +/** + * Set if redirects should forward data. + * + * @param {boolean} bool + * @return {Request} for chaining + * @api public + */ + +Request.prototype.redirectData = function(bool){ + this._redirectData = bool; + return this; +}; + +/** + * Set the if redirects should forward Auth, + * when redirected in the same domain. + * + * @param {boolean} bool + * @return {Request} for chaining + * @api public + */ + +Request.prototype.redirectAuth = function(bool){ + this._redirectAuth = bool; + return this; +}; + /** * Return a new `Part` for this request. * @@ -379,9 +407,20 @@ Request.prototype.preventBuffer = function(){ Request.prototype.redirect = function(res){ var url = res.headers.location; + var auth = this.req._headers.authorization; + var reqHost = this.req._headers.host; delete this.req; - this.emit('redirect', res); this.url = url; + if(res.statusCode !== 303 && this._redirectData && this.method !== 'HEAD' && this.method !== 'GET' ){ + this.send(this._data); + } + else{ + this.method = 'GET'; + this._data = null; + } + if(this._redirectAuth === true && url.indexOf(reqHost) !== -1){ + this.set('Authorization',auth); + } this.end(this.callback); return this; }; From a377e1ad5a068ce2d11c50d637af4083fd20822b Mon Sep 17 00:00:00 2001 From: plessbd Date: Fri, 24 Feb 2012 23:14:18 -0500 Subject: [PATCH 02/14] put back in this.emit('redirect', res); and fixed some spacing --- lib/node/index.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/node/index.js b/lib/node/index.js index 40ae0e195..72928f52d 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -179,8 +179,8 @@ Request.prototype.redirects = function(n){ */ Request.prototype.redirectData = function(bool){ - this._redirectData = bool; - return this; + this._redirectData = bool; + return this; }; /** @@ -193,8 +193,8 @@ Request.prototype.redirectData = function(bool){ */ Request.prototype.redirectAuth = function(bool){ - this._redirectAuth = bool; - return this; + this._redirectAuth = bool; + return this; }; /** @@ -407,6 +407,7 @@ Request.prototype.preventBuffer = function(){ Request.prototype.redirect = function(res){ var url = res.headers.location; + this.emit('redirect', res); var auth = this.req._headers.authorization; var reqHost = this.req._headers.host; delete this.req; From 6c1ad8069c86b1cebe16d7a7f3c6857aa456b521 Mon Sep 17 00:00:00 2001 From: TJ Holowaychuk Date: Thu, 20 Sep 2012 18:07:18 -0700 Subject: [PATCH 03/14] Release 0.9.4 --- History.md | 6 ++++++ component.json | 2 +- package.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/History.md b/History.md index 95fda18cc..5aaf4fc41 100644 --- a/History.md +++ b/History.md @@ -1,4 +1,10 @@ +0.9.4 / 2012-09-20 +================== + + * fix `Buffer` responses [TooTallNate] + * fix `res.type` when a "type" param is present [TooTallNate] + 0.9.3 / 2012-09-18 ================== diff --git a/component.json b/component.json index 0c1ebd161..b66812db5 100644 --- a/component.json +++ b/component.json @@ -2,7 +2,7 @@ "name": "superagent", "repo": "visionmedia/superagent", "description": "awesome http requests", - "version": "0.9.3", + "version": "0.9.4", "keywords": ["http", "ajax", "request", "agent"], "main": "lib/superagent.js" } \ No newline at end of file diff --git a/package.json b/package.json index a56736978..cc70a9427 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superagent", - "version": "0.9.3", + "version": "0.9.4", "description": "elegant & feature rich browser / node HTTP with a fluent API", "keywords": [ "http", From 876aeefa78e186821f4658f1c30973b3f3ba1f01 Mon Sep 17 00:00:00 2001 From: TJ Holowaychuk Date: Thu, 20 Sep 2012 18:27:01 -0700 Subject: [PATCH 04/14] remove wtf isFunction() helper --- lib/superagent.js | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/lib/superagent.js b/lib/superagent.js index c951b5a0a..298db6a16 100644 --- a/lib/superagent.js +++ b/lib/superagent.js @@ -46,18 +46,6 @@ ? function(s) { return s.trim(); } : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; - /** - * Check if `obj` is a function. - * - * @param {Mixed} obj - * @return {Boolean} - * @api private - */ - - function isFunction(obj) { - return 'function' == typeof obj; - } - /** * Check if `obj` is an object. * @@ -668,7 +656,7 @@ request.get = function(url, data, fn){ var req = request('GET', url); - if (isFunction(data)) fn = data, data = null; + if ('function' == typeof data) fn = data, data = null; if (data) req.query(data); if (fn) req.end(fn); return req; @@ -686,7 +674,7 @@ request.head = function(url, data, fn){ var req = request('HEAD', url); - if (isFunction(data)) fn = data, data = null; + if ('function' == typeof data) fn = data, data = null; if (data) req.send(data); if (fn) req.end(fn); return req; From 4aa89d6cfbdad6e7b93594f5a19186260f861d46 Mon Sep 17 00:00:00 2001 From: TJ Holowaychuk Date: Thu, 20 Sep 2012 18:27:17 -0700 Subject: [PATCH 05/14] refactor isObject() --- lib/superagent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/superagent.js b/lib/superagent.js index 298db6a16..43a157277 100644 --- a/lib/superagent.js +++ b/lib/superagent.js @@ -55,7 +55,7 @@ */ function isObject(obj) { - return null != obj && 'object' == typeof obj; + return obj === Object(obj); } /** From c8d6d5b9a828dfa7ac48f37b46bc631f6f10c22e Mon Sep 17 00:00:00 2001 From: TJ Holowaychuk Date: Thu, 20 Sep 2012 19:04:59 -0700 Subject: [PATCH 06/14] add text "parser" --- lib/node/index.js | 8 +++----- lib/node/parsers/index.js | 1 + lib/node/parsers/json.js | 6 +++--- lib/node/parsers/text.js | 7 +++++++ lib/node/parsers/urlencoded.js | 6 +++--- test/node/exports.js | 2 +- 6 files changed, 18 insertions(+), 12 deletions(-) create mode 100644 lib/node/parsers/text.js diff --git a/lib/node/index.js b/lib/node/index.js index 493eff255..b7ed7ff68 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -653,12 +653,10 @@ Request.prototype.end = function(fn){ // buffered response if (buffer) { - res.text = ''; - res.setEncoding('utf8'); - res.on('data', function(chunk){ res.text += chunk; }); + var parse = 'text' == type + ? exports.parse.text + : exports.parse[utils.type(res.headers['content-type'] || '')]; - // parser - var parse = exports.parse[utils.type(res.headers['content-type'] || '')]; if (parse) { parse(res, function(err, obj){ // TODO: handle error diff --git a/lib/node/parsers/index.js b/lib/node/parsers/index.js index 0f69526b8..b47550e7e 100644 --- a/lib/node/parsers/index.js +++ b/lib/node/parsers/index.js @@ -1,3 +1,4 @@ exports['application/x-www-form-urlencoded'] = require('./urlencoded'); exports['application/json'] = require('./json'); +exports.text = require('./text'); diff --git a/lib/node/parsers/json.js b/lib/node/parsers/json.js index 8c100d932..ba244f269 100644 --- a/lib/node/parsers/json.js +++ b/lib/node/parsers/json.js @@ -1,11 +1,11 @@ module.exports = function(res, fn){ - var buf = ''; + res.text = ''; res.setEncoding('utf8'); - res.on('data', function(chunk){ buf += chunk; }); + res.on('data', function(chunk){ res.text += chunk; }); res.on('end', function(){ try { - fn(null, JSON.parse(buf)); + fn(null, JSON.parse(res.text)); } catch (err) { fn(err); } diff --git a/lib/node/parsers/text.js b/lib/node/parsers/text.js new file mode 100644 index 000000000..03575c698 --- /dev/null +++ b/lib/node/parsers/text.js @@ -0,0 +1,7 @@ + +module.exports = function(res, fn){ + res.text = ''; + res.setEncoding('utf8'); + res.on('data', function(chunk){ res.text += chunk; }); + res.on('end', fn); +}; \ No newline at end of file diff --git a/lib/node/parsers/urlencoded.js b/lib/node/parsers/urlencoded.js index 1859ed660..245c665f4 100644 --- a/lib/node/parsers/urlencoded.js +++ b/lib/node/parsers/urlencoded.js @@ -6,12 +6,12 @@ var qs = require('qs'); module.exports = function(res, fn){ - var buf = ''; + res.text = ''; res.setEncoding('ascii'); - res.on('data', function(chunk){ buf += chunk; }); + res.on('data', function(chunk){ res.text += chunk; }); res.on('end', function(){ try { - fn(null, qs.parse(buf)); + fn(null, qs.parse(res.text)); } catch (err) { fn(err); } diff --git a/test/node/exports.js b/test/node/exports.js index d1871dc0a..46d487775 100644 --- a/test/node/exports.js +++ b/test/node/exports.js @@ -18,6 +18,6 @@ describe('exports', function(){ it('should expose .parse', function(){ Object.keys(request.parse) - .should.eql(['application/x-www-form-urlencoded', 'application/json']); + .should.eql(['application/x-www-form-urlencoded', 'application/json', 'text']); }) }) \ No newline at end of file From 3fe9fcd14dca735bdfa49744dfd895352220a492 Mon Sep 17 00:00:00 2001 From: plessbd Date: Fri, 21 Sep 2012 06:14:07 -0300 Subject: [PATCH 07/14] Update lib/node/index.js fixed style issues --- lib/node/index.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/node/index.js b/lib/node/index.js index 72928f52d..7249fc7e4 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -412,15 +412,16 @@ Request.prototype.redirect = function(res){ var reqHost = this.req._headers.host; delete this.req; this.url = url; - if(res.statusCode !== 303 && this._redirectData && this.method !== 'HEAD' && this.method !== 'GET' ){ + var seeOther = 303 == res.statusCode; + var idempotent = 'HEAD' == this.method || 'GET' == this.method; + if (!seeOther && !idempotent && this._redirectData) this.send(this._data); - } - else{ + } else { this.method = 'GET'; this._data = null; } - if(this._redirectAuth === true && url.indexOf(reqHost) !== -1){ - this.set('Authorization',auth); + if (this._redirectAuth && ~url.indexOf(host)) { + this.set('Authorization', auth); } this.end(this.callback); return this; From efc2d7971b079d113d4b63e37a751f51d08655dd Mon Sep 17 00:00:00 2001 From: plessbd Date: Fri, 24 Feb 2012 23:05:29 -0500 Subject: [PATCH 08/14] Updates redirect handling tested against http://jigsaw.w3.org/HTTP/300/ --- lib/node/index.js | 48 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/lib/node/index.js b/lib/node/index.js index b7ed7ff68..d711ba59b 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -1,4 +1,3 @@ - /*! * superagent * Copyright (c) 2011 TJ Holowaychuk @@ -126,6 +125,9 @@ function Request(method, url) { this.writable = true; this._redirects = 0; this.redirects(5); + this._redirectData = false; + this._redirectAuth = false; + this._buffer = true; this.attachments = []; this.cookies = ''; this._redirectList = []; @@ -173,6 +175,33 @@ Request.prototype.redirects = function(n){ return this; }; +/** + * Set if redirects should forward data. + * + * @param {boolean} bool + * @return {Request} for chaining + * @api public + */ + +Request.prototype.redirectData = function(bool){ + this._redirectData = bool; + return this; +}; + +/** + * Set the if redirects should forward Auth, + * when redirected in the same domain. + * + * @param {boolean} bool + * @return {Request} for chaining + * @api public + */ + +Request.prototype.redirectAuth = function(bool){ + this._redirectAuth = bool; + return this; +}; + /** * Return a new `Part` for this request. * @@ -429,6 +458,7 @@ Request.prototype.clearTimeout = function(){ Request.prototype.redirect = function(res){ var url = res.headers.location; +<<<<<<< HEAD if (!~url.indexOf('://')) { if (0 != url.indexOf('//')) { @@ -445,7 +475,21 @@ Request.prototype.redirect = function(res){ this.url = url; this._redirectList.push(url); this.emit('redirect', res); - this.end(this._callback); + var auth = this.req._headers.authorization; + var reqHost = this.req._headers.host; + delete this.req; + this.url = url; + if(res.statusCode !== 303 && this._redirectData && this.method !== 'HEAD' && this.method !== 'GET' ){ + this.send(this._data); + } + else{ + this.method = 'GET'; + this._data = null; + } + if(this._redirectAuth === true && url.indexOf(reqHost) !== -1){ + this.set('Authorization',auth); + } + this.end(this.callback); return this; }; From 9087fb0b91957985219a7eb24a2563aeaa6aac28 Mon Sep 17 00:00:00 2001 From: plessbd Date: Fri, 24 Feb 2012 23:14:18 -0500 Subject: [PATCH 09/14] put back in this.emit('redirect', res); and fixed some spacing --- lib/node/index.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/node/index.js b/lib/node/index.js index d711ba59b..bad103ee9 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -184,8 +184,8 @@ Request.prototype.redirects = function(n){ */ Request.prototype.redirectData = function(bool){ - this._redirectData = bool; - return this; + this._redirectData = bool; + return this; }; /** @@ -198,8 +198,8 @@ Request.prototype.redirectData = function(bool){ */ Request.prototype.redirectAuth = function(bool){ - this._redirectAuth = bool; - return this; + this._redirectAuth = bool; + return this; }; /** @@ -458,6 +458,7 @@ Request.prototype.clearTimeout = function(){ Request.prototype.redirect = function(res){ var url = res.headers.location; +<<<<<<< HEAD <<<<<<< HEAD if (!~url.indexOf('://')) { From 94330e67fd54c45c359fab780b3afe43118a350a Mon Sep 17 00:00:00 2001 From: plessbd Date: Fri, 21 Sep 2012 06:14:07 -0300 Subject: [PATCH 10/14] Update lib/node/index.js fixed style issues --- lib/node/index.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/node/index.js b/lib/node/index.js index bad103ee9..e8fa5edec 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -480,15 +480,16 @@ Request.prototype.redirect = function(res){ var reqHost = this.req._headers.host; delete this.req; this.url = url; - if(res.statusCode !== 303 && this._redirectData && this.method !== 'HEAD' && this.method !== 'GET' ){ + var seeOther = 303 == res.statusCode; + var idempotent = 'HEAD' == this.method || 'GET' == this.method; + if (!seeOther && !idempotent && this._redirectData) this.send(this._data); - } - else{ + } else { this.method = 'GET'; this._data = null; } - if(this._redirectAuth === true && url.indexOf(reqHost) !== -1){ - this.set('Authorization',auth); + if (this._redirectAuth && ~url.indexOf(host)) { + this.set('Authorization', auth); } this.end(this.callback); return this; From 0923e7011397ec11c412a956d24f5f875ee616e5 Mon Sep 17 00:00:00 2001 From: plessbd Date: Sat, 22 Sep 2012 19:04:05 -0300 Subject: [PATCH 11/14] Update lib/node/index.js --- lib/node/index.js | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/lib/node/index.js b/lib/node/index.js index 0f82e3609..3c0414f7c 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -458,6 +458,10 @@ Request.prototype.clearTimeout = function(){ Request.prototype.redirect = function(res){ var url = res.headers.location; + var auth = this.req._headers.authorization; + var reqHost = this.req._headers.host; + var seeOther = 303 == res.statusCode; + var idempotent = 'HEAD' == this.method || 'GET' == this.method; if (!~url.indexOf('://')) { if (0 != url.indexOf('//')) { @@ -465,31 +469,26 @@ Request.prototype.redirect = function(res){ } url = this.protocol + url; } - - delete this.req; - this.method = 'HEAD' == this.method - ? this.method - : 'GET'; - this._data = null; this.url = url; - this._redirectList.push(url); - this.emit('redirect', res); - var auth = this.req._headers.authorization; - var reqHost = this.req._headers.host; + delete this.req; - this.url = url; - var seeOther = 303 == res.statusCode; - var idempotent = 'HEAD' == this.method || 'GET' == this.method; - if (!seeOther && !idempotent && this._redirectData) - this.send(this._data); - } else { - this.method = 'GET'; - this._data = null; - } + if (this._redirectAuth && ~url.indexOf(host)) { this.set('Authorization', auth); } - this.end(this.callback); + + if (!seeOther && !idempotent && this._redirectData) { + this.type('json'); + } else { + this.method = 'HEAD' == this.method + ? this.method + : 'GET'; + this._data = null; + } + + this._redirectList.push(url); + this.emit('redirect', res); + this.end(this._callback); return this; }; From e85d1e96eec8164f474ed4aab2dc9445d7a889c7 Mon Sep 17 00:00:00 2001 From: plessbd Date: Sat, 22 Sep 2012 19:55:01 -0300 Subject: [PATCH 12/14] Update test/node/redirects.js added tests for redirect with data and authorization --- test/node/redirects.js | 60 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/test/node/redirects.js b/test/node/redirects.js index 0a0dd7739..225c338ab 100644 --- a/test/node/redirects.js +++ b/test/node/redirects.js @@ -5,7 +5,7 @@ var EventEmitter = require('events').EventEmitter , assert = require('assert') , app = express() , should = require('should'); - +app.use(express.bodyParser()); app.get('/', function(req, res){ res.redirect('/movies'); }); @@ -21,11 +21,25 @@ app.get('/movies/all', function(req, res){ app.get('/movies/all/0', function(req, res){ res.send('first movie page'); }); - app.post('/movie', function(req, res){ res.redirect('/movies/all/0'); }); - +app.post('/addmovie', function(req, res){ + res.redirect('/movies/add'); +}); +app.post('/movies/add', function(req, res){ + res.send('movie '+req.body.name+' added'); +}); +app.get('/private', function(req, res){ + res.redirect('/authed'); +}); +app.get('/authed', function(req, res){ + if (req.get('authorization')) { + res.send('authed'); + } else { + res.send('not authed'); + } +}); app.get('/tobi', function(req, res){ res.send('tobi'); }); @@ -118,5 +132,45 @@ describe('request', function(){ done(); }); }) + it('should redirect as POST if user specified', function(done){ + var redirects = []; + request + .post('http://localhost:3003/addmovie') + .send({ name: 'Methos' }) + .redirectData(true) + .redirects(2) + .on('redirect', function(res){ + redirects.push(res.headers.location); + }) + .end(function(res){ + var arr = []; + arr.push('//localhost:3003/movies/add'); + redirects.should.eql(arr); + res.text.should.equal('movie Methos added'); + done(); + }); + }) + }) + + describe('with Authorization', function(){ + it('should not redirect Authorization header',function(done){ + request + .get('http://localhost:3003/private') + .set('Authorization', 'Basic dXNlcm5hbWU6cGFzcw==') + .end(function(res){ + res.text.should.equal('not authed'); + done(); + }); + }) + it('should redirect Authorization header if specified',function(done){ + request + .get('http://localhost:3003/private') + .set('Authorization', 'Basic dXNlcm5hbWU6cGFzcw==') + .redirectAuth(true) + .end(function(res){ + res.text.should.equal('authed'); + done(); + }); + }) }) }) \ No newline at end of file From cfd9bafbd3ab327995a0be4f2cf57f2a119449d0 Mon Sep 17 00:00:00 2001 From: plessbd Date: Sat, 22 Sep 2012 19:56:03 -0300 Subject: [PATCH 13/14] Update lib/node/index.js fixed variable name --- lib/node/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node/index.js b/lib/node/index.js index 3c0414f7c..4f768c832 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -473,7 +473,7 @@ Request.prototype.redirect = function(res){ delete this.req; - if (this._redirectAuth && ~url.indexOf(host)) { + if (this._redirectAuth && ~url.indexOf(reqHost)) { this.set('Authorization', auth); } From ded98e0d5341109b98718b079b3589f5399d1e9e Mon Sep 17 00:00:00 2001 From: plessbd Date: Sat, 22 Sep 2012 20:07:47 -0300 Subject: [PATCH 14/14] Update lib/node/index.js changed to send(this_data) rather than just setting the content type, just in case. --- lib/node/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node/index.js b/lib/node/index.js index 4f768c832..d90111b34 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -478,7 +478,7 @@ Request.prototype.redirect = function(res){ } if (!seeOther && !idempotent && this._redirectData) { - this.type('json'); + this.send(this._data); } else { this.method = 'HEAD' == this.method ? this.method