Skip to content

Commit

Permalink
fix(service-provider-core): allow specifying a host with _ characters M…
Browse files Browse the repository at this point in the history
  • Loading branch information
rose-m committed Jul 30, 2021
1 parent fb16917 commit ed0bad6
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 6 deletions.
15 changes: 15 additions & 0 deletions packages/cli-repl/test/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,21 @@ describe('e2e', function() {
});
});

describe('with --host', () => {
let shell: TestShell;
it('allows invalid hostnames with _', async() => {
shell = TestShell.start({
args: [ '--host', 'xx_invalid_host_xx' ],
env: { ...process.env, FORCE_COLOR: 'true', TERM: 'xterm-256color' },
forceTerminal: true
});
const result = await shell.waitForPromptOrExit();

expect(result.state).to.equal('exit');
shell.assertContainsOutput('MongoNetworkError');
});
});

describe('Ctrl+C aka SIGINT', () => {
before(function() {
if (process.platform === 'win32') {
Expand Down
7 changes: 5 additions & 2 deletions packages/service-provider-core/src/uri-generator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ describe('uri-generator.generate-uri', () => {
it('handles host with port included', () => {
expect(generateUri({ connectionSpecifier: undefined, host: 'localhost:27018' })).to.equal('mongodb://localhost:27018/?directConnection=true&serverSelectionTimeoutMS=2000');
});
it('handles host with an underscore', () => {
expect(generateUri({ connectionSpecifier: undefined, host: 'some_host' })).to.equal('mongodb://some_host:27017/?directConnection=true');
});
it('throws if host has port AND port set to other value', () => {
try {
generateUri({ connectionSpecifier: undefined, host: 'localhost:27018', port: '27019' });
Expand Down Expand Up @@ -422,10 +425,10 @@ describe('uri-generator.generate-uri', () => {
});
it('returns a URI for the hosts and ports specified in --host and database name', () => {
const options = {
host: 'host1:123,host2,host3:456,',
host: 'host1:123,host_2,host3:456,',
connectionSpecifier: 'admin'
};
expect(generateUri(options)).to.equal('mongodb://host1:123,host2,host3:456/admin');
expect(generateUri(options)).to.equal('mongodb://host1:123,host_2,host3:456/admin');
});
});
context('with a replica set', () => {
Expand Down
8 changes: 4 additions & 4 deletions packages/service-provider-core/src/uri-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function validateConflicts(options: CliOptions, connectionString?: ConnectionStr
* @param {string} host - The value of the --host option.
*/
function validateHost(host: string): void {
const invalidCharacter = host.match(/[^a-zA-Z0-9.:\[\]-]/);
const invalidCharacter = host.match(/[^a-zA-Z0-9.:\[\]_-]/);
if (invalidCharacter) {
throw new MongoshInvalidInputError(
i18n.__(INVALID_HOST) + ': ' + invalidCharacter[0],
Expand Down Expand Up @@ -149,7 +149,7 @@ function generateUriNormalized(options: CliOptions): ConnectionString {
// If the --host argument contains /, it has the format
// <replSetName>/<hostname1><:port>,<hostname2><:port>,<...>
const replSetHostMatch = (options.host ?? '').match(
/^(?<replSetName>[^/]+)\/(?<hosts>([A-Za-z0-9.-]+(:\d+)?,?)+)$/
/^(?<replSetName>[^/]+)\/(?<hosts>([A-Za-z0-9._-]+(:\d+)?,?)+)$/
);
if (replSetHostMatch) {
const { replSetName, hosts } = replSetHostMatch.groups as { replSetName: string, hosts: string };
Expand All @@ -162,7 +162,7 @@ function generateUriNormalized(options: CliOptions): ConnectionString {
// If the --host argument contains multiple hosts as a seed list
// we directly do not do additional host/port parsing
const seedList = (options.host ?? '').match(
/^(?<hosts>([A-Za-z0-9.-]+(:\d+)?,?)+)$/
/^(?<hosts>([A-Za-z0-9._-]+(:\d+)?,?)+)$/
);
if (seedList && options.host?.includes(',')) {
const { hosts } = seedList.groups as { hosts: string };
Expand Down Expand Up @@ -190,7 +190,7 @@ function generateUriNormalized(options: CliOptions): ConnectionString {

// Capture host, port and db from the string and generate a URI from
// the parts. If there is a db part, it *must* start with /.
const uriMatch = /^([A-Za-z0-9][A-Za-z0-9.-]+):?(\d+)?(?:\/(\S*))?$/gi;
const uriMatch = /^([A-Za-z0-9][A-Za-z0-9._-]+):?(\d+)?(?:\/(\S*))?$/gi;
let parts: string[] | null = uriMatch.exec(uri);

if (parts === null) {
Expand Down

0 comments on commit ed0bad6

Please sign in to comment.