From e61c7fa32bdc54ef4474a071da686c70e512b009 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Mon, 21 May 2018 14:50:54 +0800 Subject: [PATCH] feat: support pass through querystring to tgz url (#1334) and allow bucket query params on tgz download --- controllers/registry/package/download.js | 19 ++----- lib/common.js | 3 + servers/registry.js | 6 +- .../registry/package/download.test.js | 24 ++++---- .../controllers/registry/package/list.test.js | 57 ++++++++++--------- 5 files changed, 52 insertions(+), 57 deletions(-) diff --git a/controllers/registry/package/download.js b/controllers/registry/package/download.js index 9462c13dd..2b8be17b7 100644 --- a/controllers/registry/package/download.js +++ b/controllers/registry/package/download.js @@ -1,17 +1,5 @@ -/**! - * Copyright(c) cnpm and other contributors. - * MIT Licensed - * - * Authors: - * fengmk2 (http://fengmk2.com) - */ - 'use strict'; -/** - * Module dependencies. - */ - var debug = require('debug')('cnpmjs.org:controllers:registry:download'); var mime = require('mime'); var utility = require('utility'); @@ -36,10 +24,13 @@ module.exports = function* download(next) { var url = null; if (typeof nfs.url === 'function') { + var query = this.query || {}; + // allow download from specific store bucket + var options = query.bucket ? { bucket: query.bucket } : null; if (is.generatorFunction(nfs.url)) { - url = yield nfs.url(common.getCDNKey(name, filename)); + url = yield nfs.url(common.getCDNKey(name, filename), options); } else { - url = nfs.url(common.getCDNKey(name, filename)); + url = nfs.url(common.getCDNKey(name, filename), options); } } diff --git a/lib/common.js b/lib/common.js index d45b047c4..2fb79ac22 100644 --- a/lib/common.js +++ b/lib/common.js @@ -27,6 +27,9 @@ exports.setDownloadURL = function (pkg, ctx, host) { pkg.dist.tarball = util.format('%s://%s/%s/download/%s-%s.tgz', ctx.protocol, host, pkg.name, pkg.name, pkg.version); + if (ctx.querystring) { + pkg.dist.tarball += '?' + ctx.querystring; + } } }; diff --git a/servers/registry.js b/servers/registry.js index d2758e5d9..c3f7410c5 100644 --- a/servers/registry.js +++ b/servers/registry.js @@ -61,10 +61,10 @@ app.on('error', function (err, ctx) { logger.error(err); }); -app = http.createServer(app.callback()); +const server = http.createServer(app.callback()); if (!module.parent) { - app.listen(config.registryPort); + server.listen(config.registryPort); } -module.exports = app; +module.exports = server; diff --git a/test/controllers/registry/package/download.test.js b/test/controllers/registry/package/download.test.js index c39716cc3..d18b4a577 100644 --- a/test/controllers/registry/package/download.test.js +++ b/test/controllers/registry/package/download.test.js @@ -1,17 +1,5 @@ -/**! - * Copyright(c) cnpm and other contributors. - * MIT Licensed - * - * Authors: - * fengmk2 (http://fengmk2.com) - */ - 'use strict'; -/** - * Module dependencies. - */ - var request = require('supertest'); var mm = require('mm'); var config = require('../../../../config'); @@ -73,6 +61,18 @@ describe('test/controllers/registry/package/download.test.js', function () { .expect('Location', 'http://foo.test.com/@cnpmtest/download-test-module/-/@cnpmtest/download-test-module-1.0.0.tgz') .expect(302, done); }); + + it('should download from foo-us1 bucket', function(done) { + mm(config.nfs, 'url', function(key, options) { + return 'http://' + options.bucket + '.oss.com' + key; + }); + mm(config, 'downloadRedirectToNFS', true); + + request(app) + .get('/@cnpmtest/download-test-module/-/@cnpmtest/download-test-module-1.0.0.tgz?bucket=foo-us1') + .expect('Location', 'http://foo-us1.oss.com/@cnpmtest/download-test-module/-/@cnpmtest/download-test-module-1.0.0.tgz') + .expect(302, done); + }); }); }); }); diff --git a/test/controllers/registry/package/list.test.js b/test/controllers/registry/package/list.test.js index 7ebade9d5..4624e499d 100644 --- a/test/controllers/registry/package/list.test.js +++ b/test/controllers/registry/package/list.test.js @@ -22,7 +22,7 @@ describe('test/controllers/registry/package/list.test.js', () => { bytetest: '~0.0.1', mocha: '~1.0.0' }; - request(app.listen()) + request(app) .put('/' + pkg.name) .set('authorization', utils.otherUserAuth) .send(pkg) @@ -33,7 +33,7 @@ describe('test/controllers/registry/package/list.test.js', () => { bytetest: '~0.0.1', mocha: '~1.0.0' }; - request(app.listen()) + request(app) .put('/' + pkg.name) .set('authorization', utils.otherUserAuth) .send(pkg) @@ -42,7 +42,7 @@ describe('test/controllers/registry/package/list.test.js', () => { }); it('should return all versions', done => { - request(app.listen()) + request(app) .get('/@cnpmtest/testmodule-list-1') .expect(200, function (err, res) { should.not.exist(err); @@ -63,7 +63,7 @@ describe('test/controllers/registry/package/list.test.js', () => { }); it('should return all versions in abbreviated meta format for private scope package', function(done) { - request(app.listen()) + request(app) .get('/@cnpmtest/testmodule-list-1') .set('Accept', 'application/vnd.npm.install-v1+json') .expect(200, function(err, res) { @@ -76,7 +76,7 @@ describe('test/controllers/registry/package/list.test.js', () => { assert(!data.time); // should 304 - request(app.listen()) + request(app) .get('/@cnpmtest/testmodule-list-1') .set('Accept', 'application/vnd.npm.install-v1+json') .set('If-None-Match', res.headers.etag) @@ -85,7 +85,7 @@ describe('test/controllers/registry/package/list.test.js', () => { }); it('should return abbreviated meta when Accept: application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*', () => { - return request(app.listen()) + return request(app) .get('/@cnpmtest/testmodule-list-1') .set('Accept', 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*') .expect(res => { @@ -103,7 +103,7 @@ describe('test/controllers/registry/package/list.test.js', () => { mm(packageService, 'listStarUserNames', function* () { return ['fengmk2', 'foouser']; }); - request(app.listen()) + request(app) .get('/@cnpmtest/testmodule-list-1') .expect(200, function (err, res) { should.not.exist(err); @@ -119,14 +119,14 @@ describe('test/controllers/registry/package/list.test.js', () => { }); it('should support jsonp', function (done) { - request(app.listen()) + request(app) .get('/@cnpmtest/testmodule-list-1?callback=jsonp') .expect(/jsonp\(\{/) .expect(200, done); }); it('should 404 when package not exists', function (done) { - request(app.listen()) + request(app) .get('/@cnpmtest/not-exists-package') .expect(404) .expect({ @@ -137,7 +137,7 @@ describe('test/controllers/registry/package/list.test.js', () => { it('should not sync not-exists package when config.syncByInstall = false', function (done) { mm(config, 'syncByInstall', false); - request(app.listen()) + request(app) .get('/@cnpmtest/not-exists-package') .expect(404) .expect({ @@ -148,14 +148,14 @@ describe('test/controllers/registry/package/list.test.js', () => { it('should sync not-exists package when config.syncByInstall = true', function (done) { mm(config, 'syncByInstall', true); - request(app.listen()) + request(app) .get('/should') .expect(302, done); }); it('should not sync not-exists scoped package', function (done) { mm(config, 'syncByInstall', true); - request(app.listen()) + request(app) .get('/@cnpmtest/pedding') .expect(404) .expect({ @@ -172,7 +172,7 @@ describe('test/controllers/registry/package/list.test.js', () => { it('should show unpublished info', done => { mm(config, 'syncModel', 'all'); - request(app.listen()) + request(app) .get('/moduletest1') .expect(404, function (err, res) { should.not.exist(err); @@ -190,7 +190,7 @@ describe('test/controllers/registry/package/list.test.js', () => { it('should show npm package after sync', function (done) { mm(config, 'syncModel', 'all'); - request(app.listen()) + request(app) .get('/tair') .expect(200, function (err, res) { should.not.exist(err); @@ -205,7 +205,7 @@ describe('test/controllers/registry/package/list.test.js', () => { describe('add tag', function () { var tagModified; before(function (done) { - request(app.listen()) + request(app) .put('/@cnpmtest/testmodule-list-1/test-tag') .set('content-type', 'application/json') .set('authorization', utils.adminAuth) @@ -219,7 +219,7 @@ describe('test/controllers/registry/package/list.test.js', () => { }); it('should use tag gmt_modified', function (done) { - request(app.listen()) + request(app) .get('/@cnpmtest/testmodule-list-1') .expect(200, function (err, res) { should.not.exist(err); @@ -233,22 +233,22 @@ describe('test/controllers/registry/package/list.test.js', () => { describe('list AbbreviatedMeta', () => { before(done => { - mm(config, 'sourceNpmRegistry', config.officialNpmRegistry); + // mm(config, 'sourceNpmRegistry', config.officialNpmRegistry); mm(config, 'syncModel', 'all'); mm(config, 'enableAbbreviatedMetadata', true); - utils.sync('detect-port', done); + utils.sync('pedding', done); }); it('should return abbreviated meta when Accept: application/vnd.npm.install-v1+json', () => { mm(config, 'syncModel', 'all'); mm(config, 'enableAbbreviatedMetadata', true); - return request(app.listen()) - .get('/detect-port') + return request(app) + .get('/pedding') .set('Accept', 'application/vnd.npm.install-v1+json') .expect(200) .expect(res => { const data = res.body; - assert(data.name === 'detect-port'); + assert(data.name === 'pedding'); assert(data.modified); assert(data['dist-tags'].latest); assert(Object.keys(data.versions).length > 0); @@ -264,7 +264,7 @@ describe('test/controllers/registry/package/list.test.js', () => { it('should 404 when package not exists', () => { mm(config, 'syncModel', 'all'); mm(config, 'enableAbbreviatedMetadata', true); - return request(app.listen()) + return request(app) .get('/@cnpmtest/not-exists-package') .set('Accept', 'application/vnd.npm.install-v1+json') .expect(404) @@ -277,13 +277,13 @@ describe('test/controllers/registry/package/list.test.js', () => { it('should return full meta when enableAbbreviatedMetadata is false and Accept is application/vnd.npm.install-v1+json', () => { mm(config, 'syncModel', 'all'); mm(config, 'enableAbbreviatedMetadata', false); - return request(app.listen()) - .get('/detect-port') + return request(app) + .get('/pedding') .set('Accept', 'application/vnd.npm.install-v1+json') .expect(200) .expect(res => { const data = res.body; - assert(data.name === 'detect-port'); + assert(data.name === 'pedding'); assert(data.description); assert(data.maintainers); // assert(data.readme); @@ -301,13 +301,13 @@ describe('test/controllers/registry/package/list.test.js', () => { it('should return full meta when Accept is not application/vnd.npm.install-v1+json', () => { mm(config, 'syncModel', 'all'); mm(config, 'enableAbbreviatedMetadata', true); - return request(app.listen()) - .get('/detect-port') + return request(app) + .get('/pedding?bucket=foo-us1&admin=1') .set('Accept', 'application/json') .expect(200) .expect(res => { const data = res.body; - assert(data.name === 'detect-port'); + assert(data.name === 'pedding'); assert(data.description); assert(data.readme); assert(data.maintainers); @@ -318,6 +318,7 @@ describe('test/controllers/registry/package/list.test.js', () => { assert('_hasShrinkwrap' in pkg); assert(pkg.publish_time && typeof pkg.publish_time === 'number'); assert(pkg._publish_on_cnpm === undefined); + assert(pkg.dist.tarball.endsWith('.tgz?bucket=foo-us1&admin=1')); } }); });