Skip to content
This repository was archived by the owner on Feb 4, 2022. It is now read-only.

NODE-1295 Implement a connection string parser for the core module #269

Merged
merged 13 commits into from
Jan 23, 2018

Conversation

mbroadst
Copy link
Member

This is a partial rewrite of the connection string parser from native ported to core. The impetus for this was a need to parse connection strings during the SDAM refactor, but it is also a feature oft-requested from users (in particular Mongoose). The parser does not concern itself with the knowledge of any particular key (outside of the single deprecated key in the connection string spec), but instead serves to do the basic work of connection string parsing, leaving such specific concerns to the porcelain layer.

It should be noted this is another handcrafted parser, and it's my strong feel that we should instead develop a grammar for our particular flavor of URI that can be shared amongst mongo drivers. Having said that, I feel like the refactoring here improves and modernizes the original and should satisfy our needs in the field.

@mbroadst mbroadst requested review from jlord and daprahamian January 23, 2018 01:34
To satisfy the requirements of one of our connection string tests
I chose to use `punycode.toUnicode` on the result of parsing a
unicode string. This is error prone due to a number of deviations
in the punycode standard vs unicode outlined in the RFC. Instead we
should do the conversion in the tests, since the node URL parsers
output is actually correct.

NODE-1295
@daprahamian
Copy link
Contributor

@mbroadst Are there any changes from the node-mongodb-native version? Or is this just moving the files?

@mbroadst
Copy link
Member Author

@daprahamian yes, significant changes. The output is completely different, but now up to spec. It turns out we weren't even checking that the unit tests expected output matched the result of parsing previously!

Copy link
Contributor

@daprahamian daprahamian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard to review it all, but here is what stood out.


result.domainLength = result.hostname.split('.').length;
if (result.pathname && result.pathname.match(',')) {
return callback(new Error('Invalid URI, cannot contain multiple hostnames'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make a new type of MongoError here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, MongoParseError ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that sounds good.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

// Default to SSL true
if (!options.ssl && !result.search) {
connectionStringOptions.push('ssl=true');
} else if (!options.ssl && result.search && !result.search.match('ssl')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this just a regex lookup on a search string? If so, are we ok with matching an invalid field like myinvalidssl?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good point

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good call, we can easily have node's parser parse the query items and check that way

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

let connectionStringOptions = [];

// Default to SSL true
if (!options.ssl && !result.search) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we DeMorgan / Karnaugh this and have one if?

if (!options.ssl && (!result.search || !result.search.match('ssl'))) {
  ...
}

Or

if (!(options.ssl || result.search && result.search.match('ssl'))) {
  ...
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, this section was actually a direct port of Jess' work earlier this month - wonder we didn't catch it then shrug

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}

dns.resolveTxt(result.host, (err, record) => {
if (err && err.code !== 'ENODATA') return callback(err);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do:

if (err) {
  if (err.code !== 'ENODATA') {
    return callback(err);
  }
  record = null;
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

return Object.keys(result).length ? result : null;
}

const SUPPORTED_PROTOCOLS = ['mongodb', 'mongodb+srv'];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we reference 'mongodb+srv' twice, we should probably make these constants

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

"options": null
}
]
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing newline

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link

@jlord jlord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dan's comments are 👍 and otherwise looks good.

Avoid invalid strings matching a `ssl` direct match regex by using
the node parser to parse the query items, and determine if an `ssl`
key exists instead.

NODE-1295
@mbroadst
Copy link
Member Author

@jlord @daprahamian gooood to go

Copy link
Contributor

@daprahamian daprahamian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@mbroadst mbroadst merged commit af0427c into 3.0.0 Jan 23, 2018
@mbroadst mbroadst deleted the NODE-1295 branch January 23, 2018 20:55
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants