Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Support request gzip content. #40

Merged
merged 1 commit into from

7 participants

@fengmk2

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.

image

@fengmk2 fengmk2 Support request gzip content.
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.
93a5580
@fengmk2

If no gzip content support, $ npm info npm was very slow outside of US regions, e.g. in China.
image

@haosdent

+1

@rlidwka

+1

@aleafs

+1

@A-limon

+1

@fengmk2 fengmk2 referenced this pull request in cnpm/cnpmjs.org
Closed

gzip json reponse support #241

@finian

+1

@fengmk2

@isaacs any suggestions?

@isaacs isaacs merged commit 93a5580 into npm:master
@fengmk2
@fengmk2 fengmk2 deleted the fengmk2:request-gzip-content branch
@rlidwka rlidwka referenced this pull request in rlidwka/sinopia
Closed

need to support gzip #54

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 1, 2014
  1. @fengmk2

    Support request gzip content.

    fengmk2 authored
    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.
This page is out of date. Refresh to see the latest.
Showing with 65 additions and 1 deletion.
  1. +18 −1 lib/request.js
  2. +47 −0 test/request-gzip-content.js
View
19 lib/request.js
@@ -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
@@ -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')
@@ -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
@@ -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) {
@@ -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) {
View
47 test/request-gzip-content.js
@@ -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()
+ })
+ })
+});
Something went wrong with that request. Please try again.