diff --git a/lib/connect.js b/lib/connect.js index c55e0e87..603f1981 100644 --- a/lib/connect.js +++ b/lib/connect.js @@ -6,7 +6,7 @@ 'use strict'; -var URL = require('url'); +var URL = require('url-parse'); var QS = require('querystring'); var Connection = require('./connection').Connection; var fmt = require('util').format; @@ -76,22 +76,12 @@ function openFrames(vhost, query, credentials, extraClientProperties) { }; } -// Decide on credentials based on what we're supplied. Note that in a -// parsed URL, the auth part is already URL-decoded, so e.g., '%3a' in -// the URL is already decoded to ':'. This is a bit unhelpful, as it -// means we can't tell whether a colon is a separator, or part of the -// username. Assume no colons in usernames. +// Decide on credentials based on what we're supplied. function credentialsFromUrl(parts) { var user = 'guest', passwd = 'guest'; - if (parts.auth) { - var colon = parts.auth.indexOf(':') - if (colon == -1) { - user = parts.auth; - passwd = ''; - } else { - user = parts.auth.substring(0, colon); - passwd = parts.auth.substring(colon+1); - } + if (parts.username != '' || parts.password != '') { + user = (parts.username) ? unescape(parts.username) : ''; + passwd = (parts.password) ? unescape(parts.password) : ''; } return credentials.plain(user, passwd); } @@ -137,7 +127,7 @@ function connect(url, socketOptions, openCallback) { fields = openFrames(url.vhost, config, sockopts.credentials || credentials.plain(user, pass), extraClientProperties); } else { - var parts = URL.parse(url, true); // yes, parse the query string + var parts = URL(url, true); // yes, parse the query string protocol = parts.protocol; sockopts.host = parts.hostname; sockopts.port = parseInt(parts.port) || ((protocol === 'amqp:') ? 5672 : 5671); diff --git a/package.json b/package.json index e774f161..ce37690e 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "bluebird": "^3.4.6", "buffer-more-ints": "0.0.2", "readable-stream": "1.x >=1.1.9", - "safe-buffer": "^5.0.1" + "safe-buffer": "^5.0.1", + "url-parse": "^1.2.0" }, "devDependencies": { "mocha": "~1", diff --git a/test/connect.js b/test/connect.js index 277c3644..e44c38b6 100644 --- a/test/connect.js +++ b/test/connect.js @@ -13,6 +13,8 @@ var format = require('util').format; var URL = process.env.URL || 'amqp://localhost'; +var urlparse = require('url-parse'); + suite("Credentials", function() { function checkCreds(creds, user, pass, done) { @@ -27,29 +29,29 @@ suite("Credentials", function() { } test("no creds", function(done) { - var parts = {auth: ''}; + var parts = urlparse('amqp://localhost'); var creds = credentialsFromUrl(parts); checkCreds(creds, 'guest', 'guest', done); }); test("usual user:pass", function(done) { - var parts = {auth: 'user:pass'}; + var parts = urlparse('amqp://user:pass@localhost') var creds = credentialsFromUrl(parts); checkCreds(creds, 'user', 'pass', done); }); test("missing user", function(done) { - var parts = {auth: ':password'}; + var parts = urlparse('amqps://:password@localhost'); var creds = credentialsFromUrl(parts); checkCreds(creds, '', 'password', done); }); test("missing password", function(done) { - var parts = {auth: 'username'}; + var parts = urlparse('amqps://username:@localhost'); var creds = credentialsFromUrl(parts); checkCreds(creds, 'username', '', done); }); - test("colon in password", function(done) { - var parts = {auth: 'username:pass:word'}; + test("escaped colons", function(done) { + var parts = urlparse('amqp://user%3Aname:pass%3Aword@localhost') var creds = credentialsFromUrl(parts); - checkCreds(creds, 'username', 'pass:word', done); + checkCreds(creds, 'user:name', 'pass:word', done); }); });