From cef2daacb55882dac46b8007fe14142fa29bfaed Mon Sep 17 00:00:00 2001 From: Vsevolod Strukchinsky Date: Sun, 9 Nov 2014 12:05:30 +0500 Subject: [PATCH] Read response stream even if status is not 200 --- .gitignore | 1 + index.js | 62 +++++++++++++++------------------------------------- package.json | 7 ++++-- readme.md | 2 +- test.js | 1 + 5 files changed, 26 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index 3c3629e..ba2a97b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +coverage diff --git a/index.js b/index.js index 3ca348b..ce2b974 100644 --- a/index.js +++ b/index.js @@ -5,33 +5,9 @@ var urlLib = require('url'); var zlib = require('zlib'); var PassThrough = require('stream').PassThrough; var assign = require('object-assign'); +var read = require('read-all-stream'); -function read(res, encoding, cb) { - if (!cb) { - cb = encoding; - encoding = undefined; - } - - var chunks = []; - var len = 0; - - res.on('data', function (chunk) { - chunks.push(chunk); - len += chunk.length; - }); - - res.once('end', function () { - var data = Buffer.concat(chunks, len); - - if (encoding !== null) { - data = data.toString(encoding || 'utf8'); - } - - cb(null, data, res); - }); -} - -function got (url, opts, cb) { +module.exports = function (url, opts, cb) { if (typeof opts === 'function') { // if `cb` has been specified but `opts` has not cb = opts; @@ -70,9 +46,12 @@ function got (url, opts, cb) { var fn = parsedUrl.protocol === 'https:' ? https : http; var arg = assign({}, parsedUrl, opts); - fn.get(arg, function (res) { + fn.get(arg, function (response) { + var statusCode = response.statusCode; + var res = response; + // redirect - if (res.statusCode < 400 && res.statusCode >= 300 && res.headers.location) { + if (statusCode < 400 && statusCode >= 300 && res.headers.location) { if (++redirectCount > 10) { cb(new Error('Redirected 10 times. Aborting.'), undefined, res); return; @@ -82,37 +61,32 @@ function got (url, opts, cb) { return; } - if (res.statusCode < 200 || res.statusCode > 299) { - var err = new Error('Couldn\'t connect to ' + url + '.'); - err.code = res.statusCode; - cb(err, undefined, res); - return; - } - if (['gzip', 'deflate'].indexOf(res.headers['content-encoding']) !== -1) { var unzip = zlib.createUnzip(); res.pipe(unzip); res = unzip; } + if (statusCode < 200 || statusCode > 299) { + read(res, encoding, function (error, data) { + var err = error || new Error('Couldn\'t connect to ' + url + '.'); + err.code = statusCode; + cb(err, data, response); + }); + return; + } + // pipe the response to the proxy if in proxy mode if (proxy) { res.on('error', proxy.emit.bind(proxy, 'error')).pipe(proxy); return; } - res.once('error', cb); - - read(res, encoding, cb); - + read(res, encoding, cb, response); }).once('error', cb); }; get(url, opts, cb); return proxy; -} - -got.read = read; - -module.exports = got; +}; diff --git a/package.json b/package.json index 72a8d8e..30c567d 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "node": ">=0.10.0" }, "scripts": { - "test": "mocha" + "test": "mocha", + "coverage": "istanbul cover _mocha -- -R spec" }, "files": [ "index.js" @@ -31,9 +32,11 @@ "simple" ], "dependencies": { - "object-assign": "^1.0.0" + "object-assign": "^1.0.0", + "read-all-stream": "^0.1.0" }, "devDependencies": { + "istanbul": "^0.3.2", "mocha": "*" } } diff --git a/readme.md b/readme.md index 4de0d85..bfb52d2 100644 --- a/readme.md +++ b/readme.md @@ -61,7 +61,7 @@ Encoding to be used on `setEncoding` of the response data. If null, the body is ###### err -`Error` object with `code` property. If error happens, callback will receive `undefined` as `data` and bare [response](http://nodejs.org/api/http.html#http_http_incomingmessage) object, which can be destroyed or queried for data. +`Error` object with `code` property. ###### data diff --git a/test.js b/test.js index d31d9ef..36ea558 100644 --- a/test.js +++ b/test.js @@ -32,6 +32,7 @@ it('should should return status code as error code and response object when not got('http://sindresorhus.com/sfsadfasdfadsga', function (err, data, res) { assert.ok(res.headers); assert.strictEqual(err.code, 404); + assert.ok(//.test(data)); done(); }); });