diff --git a/lib/index-api.js b/lib/index-api.js index 1aa90cd6..f91b6245 100644 --- a/lib/index-api.js +++ b/lib/index-api.js @@ -33,6 +33,15 @@ module.exports = function(config, auth, storage) { app.use(expressJson5({ strict: false, limit: config.max_body_size || '10mb' })) app.use(Middleware.anti_loop(config)) + // encode / in a scoped package name to be matched as a single parameter in routes + app.use(function(req, res, next) { + if (req.url.indexOf('@') != -1) { + // e.g.: /@org/pkg/1.2.3 -> /@org%2Fpkg/1.2.3, /@org%2Fpkg/1.2.3 -> /@org%2Fpkg/1.2.3 + req.url = req.url.replace(/^(\/@[^\/%]+)\/(?!$)/, '$1%2F') + } + next() + }) + // for "npm whoami" app.get('/whoami', function(req, res, next) { if (req.headers.referer === 'whoami') { @@ -90,7 +99,7 @@ module.exports = function(config, auth, storage) { res.status(200) res.write('{"_updated":' + Date.now()); - var stream = storage.search(req.param.startkey || 0, { req: req }) + var stream = storage.search(req.query.startkey || 0, { req: req }) stream.on('data', function each(pkg) { processing_pkgs++ diff --git a/lib/index-web.js b/lib/index-web.js index caef8f99..d1a15a9c 100644 --- a/lib/index-web.js +++ b/lib/index-web.js @@ -55,6 +55,15 @@ module.exports = function(config, auth, storage) { }) }) }, function(packages) { + packages.sort(function(p1, p2) { + if (p1.name < p2.name) { + return -1; + } + else { + return 1; + } + }); + next(template({ name: config.web && config.web.title ? config.web.title : 'Sinopia', packages: packages, diff --git a/lib/up-storage.js b/lib/up-storage.js index f4c97551..83ae61ec 100644 --- a/lib/up-storage.js +++ b/lib/up-storage.js @@ -7,7 +7,9 @@ var parse_interval = require('./config').parse_interval var Logger = require('./logger') var MyStreams = require('./streams') var Utils = require('./utils') -var encode = encodeURIComponent +var encode = function(thing) { + return encodeURIComponent(thing).replace(/^%40/, '@'); +}; module.exports = Storage @@ -101,6 +103,7 @@ Storage.prototype.request = function(options, cb) { if (typeof(cb) === 'function') cb(Error('uplink is offline')) req.emit('error', Error('uplink is offline')) }) + req._read = function(){} // preventing 'Uncaught, unspecified "error" event' req.on('error', function(){}) return req diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index ef31355b..c2784c0c 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -3,13 +3,13 @@ "version": "1.4.0", "dependencies": { "JSONStream": { - "version": "1.0.3", + "version": "1.0.6", "dependencies": { "jsonparse": { - "version": "1.0.0" + "version": "1.1.0" }, "through": { - "version": "2.3.7" + "version": "2.3.8" } } }, @@ -17,10 +17,10 @@ "version": "0.9.2" }, "body-parser": { - "version": "1.12.4", + "version": "1.14.1", "dependencies": { "bytes": { - "version": "1.0.0" + "version": "2.1.0" }, "content-type": { "version": "1.0.1" @@ -34,41 +34,41 @@ } }, "depd": { - "version": "1.0.1" + "version": "1.1.0" }, "iconv-lite": { - "version": "0.4.8" + "version": "0.4.12" }, "on-finished": { - "version": "2.2.1", + "version": "2.3.0", "dependencies": { "ee-first": { - "version": "1.1.0" + "version": "1.1.1" } } }, "qs": { - "version": "2.4.2" + "version": "5.1.0" }, "raw-body": { - "version": "2.0.2", + "version": "2.1.4", "dependencies": { - "bytes": { - "version": "2.1.0" + "unpipe": { + "version": "1.0.0" } } }, "type-is": { - "version": "1.6.2", + "version": "1.6.9", "dependencies": { "media-typer": { "version": "0.3.0" }, "mime-types": { - "version": "2.0.12", + "version": "2.1.7", "dependencies": { "mime-db": { - "version": "1.10.0" + "version": "1.19.0" } } } @@ -77,24 +77,21 @@ } }, "bunyan": { - "version": "1.3.5", + "version": "1.5.1", "dependencies": { "dtrace-provider": { - "version": "0.4.0", + "version": "0.6.0", "dependencies": { "nan": { - "version": "1.5.3" + "version": "2.0.9" } } }, "mv": { - "version": "2.0.3", + "version": "2.1.1", "dependencies": { "ncp": { - "version": "0.6.0" - }, - "rimraf": { - "version": "2.2.8" + "version": "2.0.0" } } }, @@ -112,32 +109,32 @@ } }, "compression": { - "version": "1.4.4", + "version": "1.6.0", "dependencies": { "accepts": { - "version": "1.2.7", + "version": "1.3.0", "dependencies": { "mime-types": { - "version": "2.0.12", + "version": "2.1.7", "dependencies": { "mime-db": { - "version": "1.10.0" + "version": "1.19.0" } } }, "negotiator": { - "version": "0.5.3" + "version": "0.6.0" } } }, "bytes": { - "version": "1.0.0" + "version": "2.1.0" }, "compressible": { - "version": "2.0.2", + "version": "2.0.6", "dependencies": { "mime-db": { - "version": "1.10.0" + "version": "1.19.0" } } }, @@ -150,15 +147,15 @@ } }, "on-headers": { - "version": "1.0.0" + "version": "1.0.1" }, "vary": { - "version": "1.0.0" + "version": "1.1.0" } } }, "cookies": { - "version": "0.5.0", + "version": "0.5.1", "dependencies": { "keygrip": { "version": "1.0.1" @@ -169,7 +166,7 @@ "version": "0.1.8", "dependencies": { "nan": { - "version": "1.8.4" + "version": "1.9.0" } } }, @@ -177,35 +174,44 @@ "version": "0.21.1" }, "express": { - "version": "5.0.0-alpha.1", + "version": "5.0.0-alpha.2", "dependencies": { "accepts": { - "version": "1.1.4", + "version": "1.2.13", "dependencies": { "mime-types": { - "version": "2.0.12", + "version": "2.1.7", "dependencies": { "mime-db": { - "version": "1.10.0" + "version": "1.19.0" } } }, "negotiator": { - "version": "0.4.9" + "version": "0.5.3" } } }, + "array-flatten": { + "version": "1.1.0" + }, "content-disposition": { "version": "0.5.0" }, + "content-type": { + "version": "1.0.1" + }, + "cookie": { + "version": "0.1.3" + }, "cookie-signature": { - "version": "1.0.5" + "version": "1.0.6" }, "debug": { - "version": "2.1.3", + "version": "2.2.0", "dependencies": { "ms": { - "version": "0.7.0" + "version": "0.7.1" } } }, @@ -213,41 +219,44 @@ "version": "1.0.1" }, "escape-html": { - "version": "1.0.1" + "version": "1.0.2" }, "etag": { - "version": "1.5.1", + "version": "1.7.0" + }, + "finalhandler": { + "version": "0.4.0", "dependencies": { - "crc": { - "version": "3.2.1" + "unpipe": { + "version": "1.0.0" } } }, - "finalhandler": { - "version": "0.3.2" - }, "fresh": { - "version": "0.2.4" - }, - "media-typer": { "version": "0.3.0" }, + "merge-descriptors": { + "version": "1.0.0" + }, "methods": { - "version": "1.1.0" + "version": "1.1.1" }, "on-finished": { - "version": "2.1.1", + "version": "2.3.0", "dependencies": { "ee-first": { - "version": "1.1.0" + "version": "1.1.1" } } }, "parseurl": { "version": "1.3.0" }, + "path-is-absolute": { + "version": "1.0.0" + }, "path-to-regexp": { - "version": "0.1.3" + "version": "0.1.6" }, "proxy-addr": { "version": "1.0.8", @@ -261,49 +270,63 @@ } }, "qs": { - "version": "2.3.2" + "version": "4.0.0" }, "range-parser": { "version": "1.0.2" }, + "router": { + "version": "1.1.3", + "dependencies": { + "array-flatten": { + "version": "1.1.1" + }, + "path-to-regexp": { + "version": "0.1.7" + }, + "setprototypeof": { + "version": "1.0.0" + } + } + }, "send": { - "version": "0.10.1", + "version": "0.13.0", "dependencies": { "destroy": { "version": "1.0.3" }, "mime": { - "version": "1.2.11" + "version": "1.3.4" }, "ms": { - "version": "0.6.2" + "version": "0.7.1" + }, + "statuses": { + "version": "1.2.1" } } }, "serve-static": { - "version": "1.7.2" + "version": "1.10.0" }, "type-is": { - "version": "1.5.7", + "version": "1.6.9", "dependencies": { + "media-typer": { + "version": "0.3.0" + }, "mime-types": { - "version": "2.0.12", + "version": "2.1.7", "dependencies": { "mime-db": { - "version": "1.10.0" + "version": "1.19.0" } } } } }, "vary": { - "version": "1.0.0" - }, - "cookie": { - "version": "0.1.2" - }, - "merge-descriptors": { - "version": "0.0.2" + "version": "1.0.1" }, "utils-merge": { "version": "1.0.0" @@ -327,10 +350,10 @@ } }, "fs-ext": { - "version": "0.4.5", + "version": "0.4.6", "dependencies": { "nan": { - "version": "1.8.4" + "version": "1.9.0" } } }, @@ -355,7 +378,7 @@ "version": "0.1.43", "dependencies": { "amdefine": { - "version": "0.1.0" + "version": "1.0.0" } } } @@ -364,7 +387,7 @@ } }, "highlight.js": { - "version": "8.6.0" + "version": "8.8.0" }, "http-errors": { "version": "1.3.1", @@ -378,19 +401,19 @@ } }, "jju": { - "version": "1.2.0" + "version": "1.2.1" }, "js-yaml": { - "version": "3.3.1", + "version": "3.4.2", "dependencies": { "argparse": { "version": "1.0.2", "dependencies": { "lodash": { - "version": "3.9.3" + "version": "3.10.1" }, "sprintf-js": { - "version": "1.0.2" + "version": "1.0.3" } } }, @@ -400,13 +423,13 @@ } }, "lunr": { - "version": "0.5.9" + "version": "0.5.12" }, "minimatch": { "version": "1.0.0", "dependencies": { "lru-cache": { - "version": "2.6.4" + "version": "2.7.0" }, "sigmund": { "version": "1.0.1" @@ -439,19 +462,19 @@ } }, "render-readme": { - "version": "1.3.0", + "version": "1.3.1", "dependencies": { "markdown-it": { - "version": "4.2.1", + "version": "4.4.0", "dependencies": { "argparse": { "version": "1.0.2", "dependencies": { "lodash": { - "version": "3.9.3" + "version": "3.10.1" }, "sprintf-js": { - "version": "1.0.2" + "version": "1.0.3" } } }, @@ -459,10 +482,10 @@ "version": "1.1.1" }, "linkify-it": { - "version": "1.1.0" + "version": "1.2.0" }, "mdurl": { - "version": "1.0.0" + "version": "1.0.1" }, "uc.micro": { "version": "1.0.0" @@ -470,10 +493,10 @@ } }, "sanitize-html": { - "version": "1.6.1", + "version": "1.10.1", "dependencies": { "htmlparser2": { - "version": "3.8.2", + "version": "3.8.3", "dependencies": { "domhandler": { "version": "2.3.0" @@ -502,57 +525,61 @@ } } }, - "lodash": { - "version": "2.4.2" - }, "regexp-quote": { "version": "0.0.0" + }, + "xtend": { + "version": "4.0.0" } } } } }, "request": { - "version": "2.56.0", + "version": "2.64.0", "dependencies": { "bl": { - "version": "0.9.4", + "version": "1.0.0", "dependencies": { "readable-stream": { - "version": "1.0.33", + "version": "2.0.2", "dependencies": { "core-util-is": { "version": "1.0.1" }, + "inherits": { + "version": "2.0.1" + }, "isarray": { "version": "0.0.1" }, + "process-nextick-args": { + "version": "1.0.3" + }, "string_decoder": { "version": "0.10.31" }, - "inherits": { - "version": "2.0.1" + "util-deprecate": { + "version": "1.0.1" } } } } }, "caseless": { - "version": "0.10.0" + "version": "0.11.0" + }, + "extend": { + "version": "3.0.0" }, "forever-agent": { "version": "0.6.1" }, "form-data": { - "version": "0.2.0", + "version": "1.0.0-rc3", "dependencies": { - "combined-stream": { - "version": "0.0.7", - "dependencies": { - "delayed-stream": { - "version": "0.0.5" - } - } + "async": { + "version": "1.4.2" } } }, @@ -560,10 +587,10 @@ "version": "5.0.1" }, "mime-types": { - "version": "2.0.12", + "version": "2.1.7", "dependencies": { "mime-db": { - "version": "1.10.0" + "version": "1.19.0" } } }, @@ -571,13 +598,13 @@ "version": "1.4.3" }, "qs": { - "version": "3.1.0" + "version": "5.1.0" }, "tunnel-agent": { - "version": "0.4.0" + "version": "0.4.1" }, "tough-cookie": { - "version": "1.2.0" + "version": "2.1.0" }, "http-signature": { "version": "0.11.0", @@ -597,16 +624,16 @@ "version": "0.8.0" }, "hawk": { - "version": "2.3.1", + "version": "3.1.0", "dependencies": { "hoek": { - "version": "2.14.0" + "version": "2.16.3" }, "boom": { - "version": "2.7.2" + "version": "2.9.0" }, "cryptiles": { - "version": "2.0.4" + "version": "2.0.5" }, "sntp": { "version": "1.0.9" @@ -620,7 +647,7 @@ "version": "0.0.4" }, "combined-stream": { - "version": "1.0.3", + "version": "1.0.5", "dependencies": { "delayed-stream": { "version": "1.0.0" @@ -631,46 +658,40 @@ "version": "0.1.2" }, "har-validator": { - "version": "1.7.1", + "version": "1.8.0", "dependencies": { - "bluebird": { - "version": "2.9.27" - }, "chalk": { - "version": "1.0.0", + "version": "1.1.1", "dependencies": { "ansi-styles": { - "version": "2.0.1" + "version": "2.1.0" }, "escape-string-regexp": { "version": "1.0.3" }, "has-ansi": { - "version": "1.0.3", + "version": "2.0.0", "dependencies": { "ansi-regex": { - "version": "1.1.1" - }, - "get-stdin": { - "version": "4.0.1" + "version": "2.0.0" } } }, "strip-ansi": { - "version": "2.0.1", + "version": "3.0.0", "dependencies": { "ansi-regex": { - "version": "1.1.1" + "version": "2.0.0" } } }, "supports-color": { - "version": "1.3.1" + "version": "2.0.0" } } }, "is-my-json-valid": { - "version": "2.12.0", + "version": "2.12.2", "dependencies": { "generate-function": { "version": "2.0.0" @@ -684,7 +705,7 @@ } }, "jsonpointer": { - "version": "1.1.0" + "version": "2.0.0" }, "xtend": { "version": "4.0.0" @@ -696,7 +717,7 @@ } }, "semver": { - "version": "4.3.5" + "version": "4.3.6" }, "sinopia-htpasswd": { "version": "0.4.5" diff --git a/package.yaml b/package.yaml index 5dbadec1..0e4b939b 100644 --- a/package.yaml +++ b/package.yaml @@ -66,7 +66,7 @@ devDependencies: # # Linting tools # - eslint: '>= 0.18' + eslint: '1 >=1.1.0' # for debugging memory leaks, it'll be require()'d if # installed, but I don't want it to be installed everytime @@ -99,10 +99,10 @@ keywords: - server scripts: - test: eslint --reset . && mocha ./test/functional ./test/unit - test-travis: eslint --reset . && mocha -R spec ./test/functional ./test/unit + test: eslint . && mocha ./test/functional ./test/unit + test-travis: eslint . && mocha -R spec ./test/functional ./test/unit test-only: mocha ./test/functional ./test/unit - lint: eslint --reset . + lint: eslint . prepublish: js-yaml package.yaml > package.json clean-shrinkwrap: | node -e ' diff --git a/test/functional/scoped.js b/test/functional/scoped.js index 7244d89d..250853c7 100644 --- a/test/functional/scoped.js +++ b/test/functional/scoped.js @@ -65,5 +65,14 @@ module.exports = function() { assert.deepEqual(body['dist-tags'], {latest: '1.0.0'}) }) }) + + it('server2 - nginx workaround', function () { + return server2.request({ uri: '/@test/scoped/1.0.0' }) + .status(200) + .then(function (body) { + assert.equal(body.name, '@test/scoped') + assert.equal(body.dist.tarball, 'http://localhost:55552/@test%2fscoped/-/scoped-1.0.0.tgz') + }) + }) }) }