From 48a0a9a2f2d56a41b058b09b3e39c0eeb4b75236 Mon Sep 17 00:00:00 2001 From: David Frank Date: Wed, 28 Jan 2015 22:56:25 +0800 Subject: [PATCH] xml encoding detection, response size limit --- CHANGELOG.md | 7 ++++++- lib/response.js | 28 +++++++++++++++++----------- test/server.js | 34 +++++++++++++++++++++++----------- test/test.js | 30 ++++++++++++++++++++++++++---- 4 files changed, 72 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8d197a..32b023a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,12 @@ Changelog # 1.x release -## v1.0.2 (master) +## v1.0.3 (master) + +- Fix: response size limit should reject large chunk +- Enhance: added character encoding detection for xml, such as rss/atom feed (encoding in DTD) + +## v1.0.2 - Fix: added res.ok per spec change diff --git a/lib/response.js b/lib/response.js index c116e8e..ce1bfeb 100644 --- a/lib/response.js +++ b/lib/response.js @@ -74,15 +74,11 @@ Response.prototype._decode = function() { return new Response.Promise(function(resolve, reject) { self.body.on('data', function(chunk) { - if (self._abort) { + if (self._abort || chunk === null) { return; } - if (chunk === null) { - return; - } - - if (self.size && self._bytes > self.size) { + if (self.size && self._bytes + chunk.length > self.size) { self._abort = true; reject(new Error('content size at ' + self.url + ' over limit: ' + self.size)); return; @@ -115,27 +111,37 @@ Response.prototype._convert = function(encoding) { encoding = encoding || 'utf-8'; var charset = 'utf-8'; - var res; + var res, str; // header if (this.headers.has('content-type')) { res = /charset=(.*)/i.exec(this.headers.get('content-type')); } - // html5 + // no charset in content type, peek at response body if (!res && this._raw.length > 0) { - res = / 0) { - res = /日本語', 'Shift_JIS')); } + if (p === '/encoding/euc-jp') { + res.statusCode = 200; + res.setHeader('Content-Type', 'text/xml'); + res.end(convert('日本語', 'EUC-JP')); + } + if (p === '/encoding/utf8') { res.statusCode = 200; res.end('中文'); diff --git a/test/test.js b/test/test.js index 11817f6..fc64c1b 100644 --- a/test/test.js +++ b/test/test.js @@ -428,10 +428,10 @@ describe('node-fetch', function() { }); }); - it('should support maximum response size', function() { - url = base + '/long'; + it('should support maximum response size, multiple chunk', function() { + url = base + '/size/chunk'; opts = { - size: 1 + size: 5 }; return fetch(url, opts).then(function(res) { expect(res.status).to.equal(200); @@ -440,7 +440,29 @@ describe('node-fetch', function() { }); }); - it('should support encoding decode, conte-type detect', function() { + it('should support maximum response size, single chunk', function() { + url = base + '/size/long'; + opts = { + size: 5 + }; + return fetch(url, opts).then(function(res) { + expect(res.status).to.equal(200); + expect(res.headers.get('content-type')).to.equal('text/plain'); + return expect(res.text()).to.eventually.be.rejectedWith(Error); + }); + }); + + it('should support encoding decode, xml dtd detect', function() { + url = base + '/encoding/euc-jp'; + return fetch(url).then(function(res) { + expect(res.status).to.equal(200); + return res.text().then(function(result) { + expect(result).to.equal('日本語'); + }); + }); + }); + + it('should support encoding decode, content-type detect', function() { url = base + '/encoding/shift-jis'; return fetch(url).then(function(res) { expect(res.status).to.equal(200);