Skip to content
This repository has been archived by the owner on Aug 11, 2021. It is now read-only.

Commit

Permalink
Support request gzip content.
Browse files Browse the repository at this point in the history
Current CDN almost support auto gzip text base content mirrors.
e.g.: http://registry.qiniudn.com/npm
It can save ~650kb through gzip 700kb json content to 38kb.
  • Loading branch information
fengmk2 committed Mar 1, 2014
1 parent effb4bc commit 93a5580
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 1 deletion.
19 changes: 18 additions & 1 deletion lib/request.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = regRequest

var url = require("url")
, zlib = require("zlib")
, fs = require("graceful-fs")
, rm = require("rimraf")
, asyncMap = require("slide").asyncMap
Expand Down Expand Up @@ -128,6 +129,7 @@ function makeRequest (method, remote, where, what, etag, nofollow, cb_) {
if (strict === undefined) strict = true
var opts = { url: remote
, method: method
, encoding: null // tell request let body be Buffer instance
, ca: this.conf.get('ca')
, localAddress: this.conf.get('local-address')
, cert: this.conf.get('cert')
Expand All @@ -140,6 +142,7 @@ function makeRequest (method, remote, where, what, etag, nofollow, cb_) {
}

headers.accept = "application/json"
headers['accept-encoding'] = 'gzip'

headers["user-agent"] = this.conf.get('user-agent') ||
'node/' + process.version
Expand Down Expand Up @@ -170,7 +173,7 @@ function makeRequest (method, remote, where, what, etag, nofollow, cb_) {
this.log.http(method, remote.href || "/")

var done = requestDone.call(this, method, where, cb)
var req = request(opts, done)
var req = request(opts, decodeResponseBody(done))

req.on("error", cb)
req.on("socket", function (s) {
Expand All @@ -182,6 +185,20 @@ function makeRequest (method, remote, where, what, etag, nofollow, cb_) {
}
}

function decodeResponseBody(cb) {
return function (er, response, data) {
if (er) return cb(er, response, data)

if (response.headers['content-encoding'] !== 'gzip') return cb(er, response, data)

zlib.gunzip(data, function (er, buf) {
if (er) return cb(er, response, data)

cb(null, response, buf)
})
}
}

// cb(er, parsed, raw, response)
function requestDone (method, where, cb) {
return function (er, response, data) {
Expand Down
47 changes: 47 additions & 0 deletions test/request-gzip-content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
var zlib = require('zlib')
var tap = require('tap')
var server = require('./fixtures/server.js')
var RC = require('../')
var pkg = {
_id: 'some-package-gzip@1.2.3',
name: 'some-package-gzip',
version: '1.2.3'
}

zlib.gzip(JSON.stringify(pkg), function (err, pkgGzip) {
var client = new RC({
cache: __dirname + '/fixtures/cache'
, 'fetch-retries': 1
, 'fetch-retry-mintimeout': 10
, 'fetch-retry-maxtimeout': 100
, registry: 'http://localhost:' + server.port })

tap.test('request gzip package content', function (t) {
server.expect('GET', '/some-package-gzip/1.2.3', function (req, res) {
res.statusCode = 200
res.setHeader('Content-Encoding', 'gzip');
res.setHeader('Content-Type', 'application/json');
res.end(pkgGzip)
})

client.get('/some-package-gzip/1.2.3', function (er, data, raw, res) {
if (er) throw er
t.deepEqual(data, pkg)
t.end()
})
})

tap.test('request wrong gzip package content', function (t) {
server.expect('GET', '/some-package-gzip-error/1.2.3', function (req, res) {
res.statusCode = 200
res.setHeader('Content-Encoding', 'gzip')
res.setHeader('Content-Type', 'application/json')
res.end(new Buffer('wrong gzip content'))
})

client.get('/some-package-gzip-error/1.2.3', function (er, data, raw, res) {
t.ok(er)
t.end()
})
})
});

0 comments on commit 93a5580

Please sign in to comment.