diff --git a/controllers/registry/module.js b/controllers/registry/module.js index 0629f711e..11e9b0802 100644 --- a/controllers/registry/module.js +++ b/controllers/registry/module.js @@ -351,7 +351,7 @@ exports.download = function *(next) { this.length = dist.size; } this.type = mime.lookup(dist.key); - this.attachment = filename; + this.attachment(filename); this.etag = dist.shasum; this.body = yield* downloadAsReadStream(dist.key); diff --git a/controllers/web/dist.js b/controllers/web/dist.js index f30983b3e..920890568 100644 --- a/controllers/web/dist.js +++ b/controllers/web/dist.js @@ -16,6 +16,7 @@ var debug = require('debug')('cnpmjs.org:controllers:web:dist'); var mime = require('mime'); +var urlparse = require('url').parse; var Dist = require('../../proxy/dist'); var config = require('../../config'); var downloadAsReadStream = require('../utils').downloadAsReadStream; @@ -61,7 +62,7 @@ exports.list = function* (next) { }); }; - function* download(next) { +function* download(next) { var fullname = this.params[0]; var info = yield* Dist.getfile(fullname); debug('download %s got %j', fullname, info); @@ -69,16 +70,31 @@ exports.list = function* (next) { return yield* next; } + if (/\.(html|js|css|json|txt)$/.test(fullname)) { + if (info.url.indexOf('http') === 0) { + info.url = urlparse(info.url).path; + } + return yield* pipe.call(this, info, false); + } + if (info.url.indexOf('http') === 0) { return this.redirect(info.url); } + yield* pipe.call(this, info, true); +} +function* pipe(info, attachment) { + debug('pipe %j, attachment: %s', info, attachment); // download it from nfs if (typeof info.size === 'number' && info.size > 0) { this.length = info.size; } this.type = mime.lookup(info.url); - this.attachment = info.name; - this.etag = info.sha1; + if (attachment) { + this.attachment(info.name); + } + if (info.sha1) { + this.etag = info.sha1; + } this.body = yield* downloadAsReadStream(info.url); } diff --git a/test/controllers/web/dist.test.js b/test/controllers/web/dist.test.js index 389066632..7bceddc79 100644 --- a/test/controllers/web/dist.test.js +++ b/test/controllers/web/dist.test.js @@ -91,36 +91,81 @@ describe('controllers/web/dist.test.js', function () { }); describe('GET /dist/ files', function () { - it('should redirect to nfs url', function (done) { + it('should pipe txt', function (done) { mm(Dist, 'getfile', function* () { return { name: 'foo.txt', size: 1024, date: '02-May-2014 00:54', url: 'http://mock.com/dist/v0.10.28/SHASUMS.txt' }; }); + fs.writeFileSync(nfs._getpath('/dist/v0.10.28/SHASUMS.txt'), '6eff580cc8460741155d42ef1ef537961194443f'); request(app) .get('/dist/v0.10.28/SHASUMS.txt') - .expect(302) - .expect('Location', 'http://mock.com/dist/v0.10.28/SHASUMS.txt', done); + .expect('Content-Type', 'text/plain; charset=utf-8') + .expect(200, function (err, res) { + should.not.exist(err); + should.not.exist(res.headers['Content-Disposition']); + done(); + }); }); - it('should GET /dist/npm-versions.txt redirect to nfs url', function (done) { + it('should pipe html', function (done) { + mm(Dist, 'getfile', function* () { + return { + name: 'foo.html', size: 1024, date: '02-May-2014 00:54', + url: 'http://mock.com/dist/v0.10.28/foo.html' + }; + }); + fs.writeFileSync(nfs._getpath('/dist/v0.10.28/foo.html'), '

hi

'); + + request(app) + .get('/dist/v0.10.28/foo.html') + .expect('Content-Type', 'text/html; charset=utf-8') + .expect('

hi

') + .expect(200, function (err, res) { + should.not.exist(err); + should.not.exist(res.headers['Content-Disposition']); + done(); + }); + }); + + it('should pipe json', function (done) { + mm(Dist, 'getfile', function* () { + return { + name: 'foo.json', date: '02-May-2014 00:54', + url: 'http://mock.com/dist/v0.10.28/foo.json' + }; + }); + fs.writeFileSync(nfs._getpath('/dist/v0.10.28/foo.json'), '{}'); + + request(app) + .get('/dist/v0.10.28/foo.json') + .expect('Content-Type', 'application/json; charset=utf-8') + .expect('{}') + .expect(200, function (err, res) { + should.not.exist(err); + should.not.exist(res.headers['Content-Disposition']); + done(); + }); + }); + + it('should GET /dist/npm-versions.tgz redirect to nfs url', function (done) { mm(Dist, 'getfile', function* (fullname) { - fullname.should.equal('/npm-versions.txt'); + fullname.should.equal('/npm-versions.tgz'); return { name: 'npm-versions.txt', size: 1024, date: '02-May-2014 00:54', - url: 'http://mock.com/dist/npm-versions.txt' + url: 'http://mock.com/dist/npm-versions.tgz' }; }); request(app) - .get('/dist/npm-versions.txt') + .get('/dist/npm-versions.tgz') .expect(302) - .expect('Location', 'http://mock.com/dist/npm-versions.txt', done); + .expect('Location', 'http://mock.com/dist/npm-versions.tgz', done); }); - it('should download nfs file and send it', function (done) { + it('should download nfs txt file and send it', function (done) { mm(Dist, 'getfile', function* () { return { name: 'foo.txt', @@ -135,5 +180,37 @@ describe('controllers/web/dist.test.js', function () { .expect(200) .expect(/6eff580cc8460741155d42ef1ef537961194443f/, done); }); + + it('should download nfs tgz file and send it', function (done) { + mm(Dist, 'getfile', function* () { + return { + name: 'foo.tgz', + size: 1264, + date: '02-May-2014 00:54', + url: '/dist/v0.10.28/foo.tgz' + }; + }); + fs.writeFileSync(nfs._getpath('/dist/v0.10.28/foo.tgz'), '6eff580cc8460741155d42ef1ef537961194443f'); + request(app) + .get('/dist/v0.10.28/foo.tgz') + .expect('Content-Disposition', 'attachment; filename="foo.tgz"') + .expect(200, done); + }); + + it.skip('should download nfs no-ascii attachment file name', function (done) { + mm(Dist, 'getfile', function* () { + return { + name: '中文名.tgz', + size: 1264, + date: '02-May-2014 00:54', + url: '/dist/v0.10.28/foo.tgz' + }; + }); + fs.writeFileSync(nfs._getpath('/dist/v0.10.28/foo.tgz'), '6eff580cc8460741155d42ef1ef537961194443f'); + request(app) + .get('/dist/v0.10.28/foo.tgz') + .expect('Content-Disposition', 'attachment; filename="%E4%B8%AD%E6%96%87%E5%90%8D.tgz"') + .expect(200, done); + }); }); });