[Lock] MongoDbStore handle duplicate querystring keys in mongodb uri when stripping

This commit is contained in:
Joe Bennett 2020-08-18 10:56:03 +10:00 committed by Fabien Potencier
parent eb36fd6a8a
commit c1ea9ae476
2 changed files with 17 additions and 19 deletions

View File

@ -141,30 +141,21 @@ class MongoDbStore implements BlockingStoreInterface
if (false === $parsedUrl = parse_url($uri)) {
throw new InvalidArgumentException(sprintf('The given MongoDB Connection URI "%s" is invalid.', $uri));
}
$query = [];
if (isset($parsedUrl['query'])) {
parse_str($parsedUrl['query'], $query);
}
if (isset($query['collection'])) {
$this->options['collection'] = $query['collection'];
$queryStringPos = strrpos($uri, $parsedUrl['query']);
unset($query['collection']);
$prefix = substr($uri, 0, $queryStringPos);
$newQuery = http_build_query($query, '', '&', PHP_QUERY_RFC3986);
if (empty($newQuery)) {
$prefix = rtrim($prefix, '?');
}
$suffix = substr($uri, $queryStringPos + \strlen($parsedUrl['query']));
$uri = $prefix.$newQuery.$suffix;
}
$pathDb = ltrim($parsedUrl['path'] ?? '', '/') ?: null;
if (null !== $pathDb) {
$this->options['database'] = $pathDb;
}
$matches = [];
if (preg_match('/^(.*[\?&])collection=([^&#]*)&?(([^#]*).*)$/', $uri, $matches)) {
$prefix = $matches[1];
$this->options['collection'] = $matches[2];
if (empty($matches[4])) {
$prefix = substr($prefix, 0, -1);
}
$uri = $prefix.$matches[3];
}
return $uri;
}

View File

@ -187,5 +187,12 @@ class MongoDbStoreTest extends AbstractStoreTest
yield ['mongodb://localhost/?replicaSet=repl', ['database' => 'test', 'collection' => 'lock'], 'mongodb://localhost/?replicaSet=repl'];
yield ['mongodb://localhost/test?collection=lock&replicaSet=repl', [], 'mongodb://localhost/test?replicaSet=repl'];
yield ['mongodb://localhost/test?replicaSet=repl', ['collection' => 'lock'], 'mongodb://localhost/test?replicaSet=repl'];
yield ['mongodb://localhost/test?readPreferenceTags=dc:foo&collection=lock&readPreferenceTags=dc:bar', [], 'mongodb://localhost/test?readPreferenceTags=dc:foo&readPreferenceTags=dc:bar'];
yield ['mongodb://localhost?foo_collection=x&collection=lock&bar_collection=x#collection=x', ['database' => 'test'], 'mongodb://localhost?foo_collection=x&bar_collection=x#collection=x'];
yield ['mongodb://localhost?collection=lock&foo_collection=x&bar_collection=x#collection=x', ['database' => 'test'], 'mongodb://localhost?foo_collection=x&bar_collection=x#collection=x'];
yield ['mongodb://localhost?foo_collection=x&bar_collection=x&collection=lock#collection=x', ['database' => 'test'], 'mongodb://localhost?foo_collection=x&bar_collection=x#collection=x'];
yield ['mongodb://user:?collection=a@localhost?collection=lock', ['database' => 'test'], 'mongodb://user:?collection=a@localhost'];
yield ['mongodb://user:&collection=a@localhost/?collection=lock', ['database' => 'test'], 'mongodb://user:&collection=a@localhost/'];
}
}