diff --git a/index.js b/index.js index 3cabb37..7e914ba 100644 --- a/index.js +++ b/index.js @@ -35,13 +35,22 @@ function parse(str) { config.client_encoding = result.query.encoding; return config; } - config.host = result.hostname; + if (!config.host) { + // Only set the host if there is no equivalent query param. + config.host = result.hostname; + } + // If the host is missing it might be a URL-encoded path to a socket. + var pathname = result.pathname; + if (!config.host && pathname && /^%2f/i.test(pathname)) { + var pathnameSplit = pathname.split('/'); + config.host = decodeURIComponent(pathnameSplit[0]); + pathname = pathnameSplit.splice(1).join('/'); + } // result.pathname is not always guaranteed to have a '/' prefix (e.g. relative urls) // only strip the slash if it is present. - var pathname = result.pathname; if (pathname && pathname.charAt(0) === '/') { - pathname = result.pathname.slice(1) || null; + pathname = pathname.slice(1) || null; } config.database = pathname && decodeURI(pathname); diff --git a/test/parse.js b/test/parse.js index 4de2871..07f886e 100644 --- a/test/parse.js +++ b/test/parse.js @@ -120,6 +120,43 @@ describe('parse', function(){ (subject.database === null).should.equal(true); }); + it('configuration parameter host', function() { + var subject = parse('pg://user:pass@/dbname?host=/unix/socket'); + subject.user.should.equal('user'); + subject.password.should.equal('pass'); + subject.host.should.equal('/unix/socket'); + subject.database.should.equal('dbname'); + }); + + it('configuration parameter host overrides url host', function() { + var subject = parse('pg://user:pass@localhost/dbname?host=/unix/socket'); + subject.host.should.equal('/unix/socket'); + }); + + it('url with encoded socket', function() { + var subject = parse('pg://user:pass@%2Funix%2Fsocket/dbname'); + subject.user.should.equal('user'); + subject.password.should.equal('pass'); + subject.host.should.equal('/unix/socket'); + subject.database.should.equal('dbname'); + }); + + it('url with real host and an encoded db name', function() { + var subject = parse('pg://user:pass@localhost/%2Fdbname'); + subject.user.should.equal('user'); + subject.password.should.equal('pass'); + subject.host.should.equal('localhost'); + subject.database.should.equal('%2Fdbname'); + }); + + it('configuration parameter host treats encoded socket as part of the db name', function() { + var subject = parse('pg://user:pass@%2Funix%2Fsocket/dbname?host=localhost'); + subject.user.should.equal('user'); + subject.password.should.equal('pass'); + subject.host.should.equal('localhost'); + subject.database.should.equal('%2Funix%2Fsocket/dbname'); + }); + it('configuration parameter application_name', function(){ var connectionString = 'pg:///?application_name=TheApp'; var subject = parse(connectionString);