8000 [Cache] Fix Couchbase password parsing · symfony/symfony@ed359c0 · GitHub
[go: up one dir, main page]

Skip to content

Commit ed359c0

Browse files
[Cache] Fix Couchbase password parsing
1 parent 5f942a9 commit ed359c0

File tree

5 files changed

+38
-20
lines changed

5 files changed

+38
-20
lines changed

.github/workflows/integration-tests.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,16 @@ jobs:
132132
133133
- name: Configure Couchbase
134134
run: |
135-
curl -s -u 'username=Administrator&password=111111' -X POST http://localhost:8091/node/controller/setupServices -d 'services=kv%2Cn1ql%2Cindex%2Cfts'
136-
curl -s -X POST http://localhost:8091/settings/web -d 'username=Administrator&password=111111&port=SAME'
137-
curl -s -u Administrator:111111 -X POST http://localhost:8091/pools/default/buckets -d 'ramQuotaMB=100&bucketType=ephemeral&name=cache'
138-
curl -s -u Administrator:111111 -X POST http://localhost:8091/pools/default -d 'memoryQuota=256'
135+
curl -s -u 'username=Administrator&password=111111@' -X POST http://localhost:8091/node/controller/setupServices -d 'services=kv%2Cn1ql%2Cindex%2Cfts'
136+
curl -s -X POST http://localhost:8091/settings/web -d 'username=Administrator&password=111111%40&port=SAME'
137+
curl -s -u Administrator:111111@ -X POST http://localhost:8091/pools/default/buckets -d 'ramQuotaMB=100&bucketType=ephemeral&name=cache'
138+
curl -s -u Administrator:111111@ -X POST http://localhost:8091/pools/default -d 'memoryQuota=256'
139139
140140
- name: Setup PHP
141141
uses: shivammathur/setup-php@v2
142142
with:
143143
coverage: "none"
144-
extensions: "json,couchbase-3.2.2,memcached,mongodb-1.10.0,redis-5.3.4,rdkafka,xsl,ldap"
144+
extensions: "json,couchbase-3.0.4,memcached,mongodb-1.10.0,redis-5.3.4,rdkafka,xsl,ldap"
145145
ini-values: date.timezone=UTC,memory_limit=-1,default_socket_timeout=10,session.gc_probability=0,apc.enable_cli=1,zend.assertions=1
146146
php-version: "${{ matrix.php }}"
147147
tools: pecl

phpunit.xml.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<env name="ZOOKEEPER_HOST" value="localhost" />
2626
<env name="COUCHBASE_HOST" value="localhost" />
2727
<env name="COUCHBASE_USER" value="Administrator" />
28-
<env name="COUCHBASE_PASS" value="111111" />
28+
<env name="COUCHBASE_PASS" value="111111%40" />
2929
</php>
3030

3131
<testsuites>

src/Symfony/Component/Cache/Adapter/CouchbaseCollectionAdapter.php

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
< 10000 button class="Button Button--iconOnly Button--invisible ExpandableHunkHeaderDiffLine-module__expand-button-line--wZKjF ExpandableHunkHeaderDiffLine-module__expand-button-unified--Eae6C" aria-label="Expand file up from line 67" data-direction="up" aria-hidden="true" tabindex="-1">
@@ -67,10 +67,7 @@ public static function createConnection($dsn, array $options = [])
6767

6868
set_error_handler(function ($type, $msg, $file, $line): bool { throw new \ErrorException($msg, 0, $type, $file, $line); });
6969

70-
$dsnPattern = '/^(?<protocol>couchbase(?:s)?)\:\/\/(?:(?<username>[^\:]+)\:(?<password>[^\@]{6,})@)?'
71-
.'(?<host>[^\:]+(?:\:\d+)?)(?:\/(?<bucketName>[^\/\?]+))(?:(?:\/(?<scopeName>[^\/]+))'
72-
.'(?:\/(?<collectionName>[^\/\?]+)))?(?:\/)?(?:\?(?<options>.*))?$/i';
73-
70+
$pathPattern = '/^(?:\/(?<bucketName>[^\/\?]+))(?:(?:\/(?<scopeName>[^\/]+))(?:\/(?<collectionName>[^\/\?]+)))?(?:\/)?$/';
7471
$newServers = [];
7572
$protocol = 'couchbase';
7673
try {
@@ -82,31 +79,32 @@ public static function createConnection($dsn, array $options = [])
8279
throw new InvalidArgumentException('Invalid Couchbase DSN: it does not start with "couchbase:".');
8380
}
8481

85-
preg_match($dsnPattern, $server, $matches);
82+
$parsed = parse_url($server);
8683

87-
$username = $matches['username'] ?: $username;
88-
$password = $matches['password'] ?: $password;
89-
$protocol = $matches['protocol'] ?: $protocol;
84+
$username = $parsed['user'] ?? $username;
85+
$password = rawurldecode($parsed['pass'] ?? $password);
86+
$protocol = $parsed['scheme'] ?? $protocol;
9087

91-
if (isset($matches['options'])) {
92-
$optionsInDsn = self::getOptions($matches['options']);
88+
if (isset($parsed['query'])) {
89+
$optionsInDsn = self::getOptions($parsed['query']);
9390

9491
foreach ($optionsInDsn as $parameter => $value) {
9592
$options[$parameter] = $value;
9693
}
9794
}
9895

99-
$newServers[] = $matches['host'];
96+
$newServers[] = $parsed['host'];
10097
}
10198

102-
$option = isset($matches['options']) ? '?'.$matches['options'] : '';
99+
$option = isset($parsed['query']) ? '?'.$parsed['query'] : '';
103100
$connectionString = $protocol.'://'.implode(',', $newServers).$option;
104101

105102
$clusterOptions = new ClusterOptions();
106103
$clusterOptions->credentials($username, $password);
107104

108105
$client = new Cluster($connectionString, $clusterOptions);
109106

107+
preg_match($pathPattern, $parsed['path'] ?? '', $matches);
110108
$bucket = $client->bucket($matches['bucketName']);
111109
$collection = $bucket->defaultCollection();
112110
if (!empty($matches['scopeName'])) {
@@ -122,7 +120,7 @@ public static function createConnection($dsn, array $options = [])
122120

123121
public static function isSupported(): bool
124122
{
125-
return \extension_loaded('couchbase') && version_compare(phpversion('couchbase'), '3.0.5', '>=') && version_compare(phpversion('couchbase'), '4.0', '<');
123+
return \extension_loaded('couchbase') && version_compare(phpversion('couchbase'), '3.0.4', '>=') && version_compare(phpversion('couchbase'), '4.0', '<');
126124
}
127125

128126
private static function getOptions(string $options): array

src/Symfony/Component/Cache/Tests/Adapter/CouchbaseCollectionAdapterTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,24 @@ public function createCachePool($defaultLifetime = 0): CacheItemPoolInterface
6363

6464
return new CouchbaseCollectionAdapter($client, str_replace('\\', '.', __CLASS__), $defaultLifetime);
6565
}
66+
67+
/**
68+
* Couchbase consider expiration time greater than 30 days as an absolute timestamp.
69+
* This test case overrides parent to avoid this behavior for the "k2" item.
70+
*/
71+
public function testExpiration()
72+
{
73+
$cache = $this->createCachePool();
74+
$cache->save($cache->getItem('k1')->set('v1')->expiresAfter(2));
75+
$cache->save($cache->getItem('k2')->set('v2')->expiresAfter(86400));
76+
77+
sleep(3);
78+
$item = $cache->getItem('k1');
79+
$this->assertFalse($item->isHit());
80+
$this->assertNull($item->get(), "Item's value must be null when isHit() is false.");
81+
82+
$item = $cache->getItem('k2');
83+
$this->assertTrue($item->isHit());
84+
$this->assertSame('v2', $item->get());
85+
}
6686
}

src/Symfony/Component/Cache/phpunit.xml.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<env name="MEMCACHED_HOST" value="localhost" />
1616
<env name="COUCHBASE_HOST" value="localhost" />
1717
<env name="COUCHBASE_USER" value="Administrator" />
18-
<env name="COUCHBASE_PASS" value="111111" />
18+
<env name="COUCHBASE_PASS" value="111111%40" />
1919
</php>
2020

2121
<testsuites>

0 commit comments

Comments
 (0)
0