Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Lock] MongoDbStore skim non-standard options from uri #37218

Merged
merged 1 commit into from Aug 16, 2020

Conversation

kralos
Copy link

@kralos kralos commented Jun 11, 2020

Q A
Branch? 5.1
Bug fix? yes
New feature? no
Deprecations? no
Tickets Fix #37180
License MIT
Doc PR

Don't allow non-standard connection uri options reach MongoDB\Client

@kralos kralos changed the base branch from master to 5.1 June 11, 2020 13:19
parse_str($parsedUrl['query'], $query);
}

if (null === ($this->options['collection'] ?? null) && isset($query['collection'])) {
Copy link
Member

Choose a reason for hiding this comment

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

I know this was already the case before your PR, but the precedence looks wrong to me:
the DSN should have higher precedence over options (I just double-checked, that's how the Cache component does also).

/cc @jderusse maybe we should review all DSN parsing logic to ensure the precedence is consistent everywhere
/cc @Nyholm that's a good case for the DSN component - formalizing this behavior :)

Copy link
Member

Choose a reason for hiding this comment

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

👍 not only in cache and lock.

messenger Doctrine:

$configuration += $options + $query + static::DEFAULT_OPTIONS;

messenger Redis:

parse_str($parsedUrl['query'], $options);

messenger Sqs

 $configuration = ['buffer_size'] = $options['buffer_size'] ?? (int) ($query['buffer_size'] ?? self::DEFAULT_OPTIONS['buffer_size']),

messenger amqp

$amqpOptions = array_replace_recursive([], $options, $parsedQuery);

Copy link
Member

Choose a reason for hiding this comment

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

Bad news, we need to fix this. Up for a PR?

Copy link
Author

Choose a reason for hiding this comment

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

@nicolas-grekas In order to change the precedence, I think we should detect dsn / options where a precedence change would cause an effective option change and instead trigger_deprecation for now. Then swap the precedence in symfony 6.0. Do you want me to add this detection / trigger_deprecation in this PR for Lock\Store\MongoDbStore only or should we make a list of ALL dsn / options precedence affected classes and do them in a separate PR?

Copy link
Author

Choose a reason for hiding this comment

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

I've added the precedence change since you guys seem to be classing this as a bug rather than a deprecation in: #37268

Copy link
Member

Choose a reason for hiding this comment

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

There is no way to deprecate this behavior properly. Also this will very unlikely hit anyone. This precedence issue lessens the capabilities of the ops side of things. Basically, having the options take over the DSN means that the source needs to change (the options) instead of some env vars. That's a management issue at this point, and this change fixes a process issue: the env vars should always win to give control to the ops, which are the ones that know better since they're the ones in touch with the effective infra.

TL;DR, this is a bugfix.

@kralos kralos marked this pull request as ready for review June 15, 2020 06:05
@kralos kralos requested a review from xabbuh as a code owner June 15, 2020 06:24
@kralos kralos force-pushed the 37180-lock-mongodbstore-uri branch 2 times, most recently from e06956a to 599c128 Compare June 15, 2020 06:48
@nicolas-grekas nicolas-grekas added this to the 5.1 milestone Jun 18, 2020
nicolas-grekas added a commit that referenced this pull request Jun 18, 2020
…derusse)

This PR was squashed before being merged into the 5.1 branch.

Discussion
----------

[Lock][Messenger] Fix precedence of DSN options for 5.1

| Q             | A
| ------------- | ---
| Branch?       | 5.1
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | #37218 (comment)
| License       | MIT
| Doc PR        | N/A

This PR fix précédence of DSN options over constructor options in all component on branch 5.1

Commits
-------

9670e9f [Lock][Messenger] Fix precedence of DSN options for 5.1
nicolas-grekas added a commit that referenced this pull request Jun 18, 2020
This PR was merged into the 4.4 branch.

Discussion
----------

[Messenger] Fix precedence of DSN options for 4.4

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | #37218 (comment)
| License       | MIT
| Doc PR        | N/A

This PR fix précédence of DSN options over constructor options in all component on branch 4.4

Commits
-------

992205a Fix precendence in 4.4
symfony-splitter pushed a commit to symfony/messenger that referenced this pull request Jun 18, 2020
This PR was merged into the 4.4 branch.

Discussion
----------

[Messenger] Fix precedence of DSN options for 4.4

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | symfony/symfony#37218 (comment)
| License       | MIT
| Doc PR        | N/A

This PR fix précédence of DSN options over constructor options in all component on branch 4.4

Commits
-------

992205a759 Fix precendence in 4.4
@nicolas-grekas
Copy link
Member

Can you please rebase now that the priority is fixed?

@kralos kralos marked this pull request as draft June 18, 2020 23:08
@kralos kralos force-pushed the 37180-lock-mongodbstore-uri branch from 4df26a9 to 523bf2a Compare June 18, 2020 23:08
@kralos kralos marked this pull request as ready for review June 18, 2020 23:17
private function skimUri(string $uri): string
{
if (false === $parsedUrl = parse_url($uri)) {
throw new InvalidArgumentException(sprintf('The given MongoDB Connection URI "%s" is invalid.', $mongo));
Copy link
Member

Choose a reason for hiding this comment

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

$mongo is not defined

Copy link
Author

Choose a reason for hiding this comment

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

fixed

/**
* Extract default database and collection from given connection uri and remove collection querystring.
*/
private function skimUri(string $uri): string
Copy link
Member

Choose a reason for hiding this comment

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

I'm not comfortable with this method, a lot of complex logic to extract parameter from URI mixing parse_str and strpos.

Givent the format of the initial DSN is defined by symfony, wouldn't it be safer to build the mongo URI instead?

Copy link
Author

Choose a reason for hiding this comment

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

the reason i chose to use strpos to re-assemble was to simplify the re-assembly. there is no reverse of parse_str in php. see https://www.php.net/manual/en/function.parse-url.php#106731

I'm trying not to get too involved with touching the URI. What would you suggest that is simpler?

@jderusse
Copy link
Member

jderusse commented Jul 1, 2020

@nicolas-grekas LGTM from a lock point of view. I just have concerns about complexity of url generator #37218 (comment) . If you think it's ok you can merge it.

@fabpot fabpot force-pushed the 37180-lock-mongodbstore-uri branch from 79fee70 to 67912fa Compare August 16, 2020 14:54
@fabpot
Copy link
Member

fabpot commented Aug 16, 2020

Thank you @kralos.

@fabpot fabpot merged commit 5f074cd into symfony:5.1 Aug 16, 2020
$prefix = rtrim($prefix, '?');
}
$suffix = substr($uri, $queryStringPos + \strlen($parsedUrl['query']));
$uri = $prefix.$newQuery.$suffix;
Copy link
Contributor

Choose a reason for hiding this comment

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

@kralos: I only just came across this PR based on a notification in #37180. I understand what this function is attempting to do, but using parse_str may silently corrupting a connection string with repeated readPreferenceTags keys (a valid use case, as explained in the URI options spec). This comment on PHP.net goes into more detail about that.

I think it would be preferable to capture the URI option with a regular expression and then, if anything was found, strip it from the returned string. While collection names have their own restrictions, for purposes of URI parsing I think it'd be best to use something like /collection=([^&]*)/i.

Copy link
Author

Choose a reason for hiding this comment

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

see #37864 / #37868

@kralos kralos deleted the 37180-lock-mongodbstore-uri branch August 17, 2020 23:40
@fabpot fabpot mentioned this pull request Aug 31, 2020
symfony-splitter pushed a commit to symfony/messenger that referenced this pull request Sep 28, 2021
This PR was merged into the 4.4 branch.

Discussion
----------

[Messenger] Fix precedence of DSN options for 4.4

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | symfony/symfony#37218 (comment)
| License       | MIT
| Doc PR        | N/A

This PR fix précédence of DSN options over constructor options in all component on branch 4.4

Commits
-------

992205a759 Fix precendence in 4.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Lock] remove non-standard MongoDbStore URI parameters before passing to driver
6 participants