Skip to content

Commit 5612795

Browse files
committed
Fixed #853 // Configuration validation issue with Memcached socket (path)
1 parent 80a139c commit 5612795

File tree

8 files changed

+462
-100
lines changed

8 files changed

+462
-100
lines changed

lib/Phpfastcache/Drivers/Memcache/Config.php

Lines changed: 26 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
namespace Phpfastcache\Drivers\Memcache;
1818

1919
use Phpfastcache\Config\ConfigurationOption;
20+
use Phpfastcache\Exceptions\PhpfastcacheDriverException;
2021
use Phpfastcache\Exceptions\PhpfastcacheInvalidConfigurationException;
2122

2223

@@ -28,10 +29,10 @@ class Config extends ConfigurationOption
2829
* Multiple server can be added this way:
2930
* $cfg->setServers([
3031
* [
32+
* // If you use an UNIX socket set the host and port to null
3133
* 'host' => '127.0.0.1',
34+
* //'path' => 'path/to/unix/socket',
3235
* 'port' => 11211,
33-
* 'saslUser' => false,
34-
* 'saslPassword' => false,
3536
* ]
3637
* ]);
3738
*/
@@ -47,52 +48,6 @@ class Config extends ConfigurationOption
4748
*/
4849
protected $port = 11211;
4950

50-
/**
51-
* @var string
52-
*/
53-
protected $saslUser = '';
54-
55-
/**
56-
* @var string
57-
*/
58-
protected $saslPassword = '';
59-
60-
/**
61-
* @return bool
62-
*/
63-
public function getSaslUser(): string
64-
{
65-
return $this->saslUser;
66-
}
67-
68-
/**
69-
* @param string $saslUser
70-
* @return self
71-
*/
72-
public function setSaslUser(string $saslUser): self
73-
{
74-
$this->saslUser = $saslUser;
75-
return $this;
76-
}
77-
78-
/**
79-
* @return string
80-
*/
81-
public function getSaslPassword(): string
82-
{
83-
return $this->saslPassword;
84-
}
85-
86-
/**
87-
* @param string $saslPassword
88-
* @return self
89-
*/
90-
public function setSaslPassword(string $saslPassword): self
91-
{
92-
$this->saslPassword = $saslPassword;
93-
return $this;
94-
}
95-
9651
/**
9752
* @return array
9853
*/
@@ -109,18 +64,33 @@ public function getServers(): array
10964
public function setServers(array $servers): self
11065
{
11166
foreach ($servers as $server) {
112-
if ($diff = array_diff(['host', 'port', 'saslUser', 'saslPassword'], array_keys($server))) {
113-
throw new PhpfastcacheInvalidConfigurationException('Missing keys for memcached server: ' . implode(', ', $diff));
67+
if (\array_key_exists('saslUser', $server) || array_key_exists('saslPassword', $server)) {
68+
throw new PhpfastcacheInvalidConfigurationException('Unlike Memcached, Memcache does not support SASL authentication');
11469
}
115-
if ($diff = array_diff(array_keys($server), ['host', 'port', 'saslUser', 'saslPassword'])) {
70+
71+
if ($diff = array_diff(array_keys($server), ['host', 'port', 'path'])) {
11672
throw new PhpfastcacheInvalidConfigurationException('Unknown keys for memcached server: ' . implode(', ', $diff));
11773
}
118-
if (!is_string($server['host'])) {
119-
throw new PhpfastcacheInvalidConfigurationException('Host must be a valid string in "$server" configuration array');
74+
75+
if (!empty($server['host']) && !empty($server['path'])) {
76+
throw new PhpfastcacheInvalidConfigurationException('Host and path cannot be simultaneous defined.');
77+
}
78+
79+
if ((isset($server['host']) && !is_string($server['host'])) || (empty($server['path']) && empty($server['host']))) {
80+
throw new PhpfastcacheInvalidConfigurationException('Host must be a valid string in "$server" configuration array if path is not defined');
81+
}
82+
83+
if ((isset($server['path']) && !is_string($server['path'])) || (empty($server['host']) && empty($server['path']))) {
84+
throw new PhpfastcacheInvalidConfigurationException('Path must be a valid string in "$server" configuration array if host is not defined');
12085
}
121-
if (!is_int($server['port'])) {
86+
87+
if (!empty($server['host']) && (empty($server['port']) || !is_int($server['port'])|| $server['port'] < 1)) {
12288
throw new PhpfastcacheInvalidConfigurationException('Port must be a valid integer in "$server" configuration array');
12389
}
90+
91+
if (!empty($server['port']) && !empty($server['path'])) {
92+
throw new PhpfastcacheInvalidConfigurationException('Port should not be defined along with path');
93+
}
12494
}
12595
$this->servers = $servers;
12696
return $this;
@@ -141,6 +111,7 @@ public function getHost(): string
141111
public function setHost(string $host): self
142112
{
143113
$this->host = $host;
114+
144115
return $this;
145116
}
146117

@@ -161,4 +132,4 @@ public function setPort(int $port): self
161132
$this->port = $port;
162133
return $this;
163134
}
164-
}
135+
}

lib/Phpfastcache/Drivers/Memcache/Driver.php

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -92,35 +92,28 @@ public function getStats(): DriverStatistic
9292
protected function driverConnect(): bool
9393
{
9494
$this->instance = new MemcacheSoftware();
95-
$servers = $this->getConfig()->getServers();
96-
97-
if (count($servers) < 1) {
98-
$servers = [
99-
[
100-
'host' => $this->getConfig()->getHost(),
101-
'path' => $this->getConfig()->getPath(),
102-
'port' => $this->getConfig()->getPort(),
103-
'saslUser' => $this->getConfig()->getSaslUser() ?: false,
104-
'saslPassword' => $this->getConfig()->getSaslPassword() ?: false,
105-
],
106-
];
95+
96+
if (count($this->getConfig()->getServers()) < 1) {
97+
$this->getConfig()->setServers(
98+
[
99+
[
100+
'host' => $this->getConfig()->getHost(),
101+
'path' => $this->getConfig()->getPath(),
102+
'port' => $this->getConfig()->getPort(),
103+
]
104+
]
105+
);
107106
}
108107

109-
foreach ($servers as $server) {
108+
foreach ($this->getConfig()->getServers() as $server) {
110109
try {
111110
/**
112111
* If path is provided we consider it as an UNIX Socket
113112
*/
114113
if (!empty($server['path']) && !$this->instance->addServer($server['path'], 0)) {
115114
$this->fallback = true;
116-
} else {
117-
if (!empty($server['host']) && !$this->instance->addServer($server['host'], $server['port'])) {
118-
$this->fallback = true;
119-
}
120-
}
121-
122-
if (!empty($server['saslUser']) && !empty($server['saslPassword'])) {
123-
throw new PhpfastcacheDriverException('Unlike Memcached, Memcache does not support SASL authentication');
115+
} elseif (!empty($server['host']) && !$this->instance->addServer($server['host'], $server['port'])) {
116+
$this->fallback = true;
124117
}
125118
} catch (Exception $e) {
126119
$this->fallback = true;

lib/Phpfastcache/Drivers/Memcached/Config.php

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ class Config extends ConfigurationOption
2828
* Multiple server can be added this way:
2929
* $cfg->setServers([
3030
* [
31+
* // If you use an UNIX socket set the host and port to null
3132
* 'host' => '127.0.0.1',
33+
* //'path' => 'path/to/unix/socket',
3234
* 'port' => 11211,
33-
* 'saslUser' => false,
34-
* 'saslPassword' => false,
35+
* 'saslUser' => null,
36+
* 'saslPassword' => null,
3537
* ]
3638
* ]);
3739
*/
@@ -114,18 +116,33 @@ public function getServers(): array
114116
public function setServers(array $servers): self
115117
{
116118
foreach ($servers as $server) {
117-
if ($diff = array_diff(['host', 'port', 'saslUser', 'saslPassword'], array_keys($server))) {
118-
throw new PhpfastcacheInvalidConfigurationException('Missing keys for memcached server: ' . implode(', ', $diff));
119-
}
120-
if ($diff = array_diff(array_keys($server), ['host', 'port', 'saslUser', 'saslPassword'])) {
119+
if ($diff = array_diff(array_keys($server), ['host', 'port', 'saslUser', 'saslPassword', 'path'])) {
121120
throw new PhpfastcacheInvalidConfigurationException('Unknown keys for memcached server: ' . implode(', ', $diff));
122121
}
123-
if (!is_string($server['host'])) {
124-
throw new PhpfastcacheInvalidConfigurationException('Host must be a valid string in "$server" configuration array');
122+
123+
if (!empty($server['host']) && !empty($server['path'])) {
124+
throw new PhpfastcacheInvalidConfigurationException('Host and path cannot be simultaneous defined.');
125+
}
126+
127+
if ((isset($server['host']) && !is_string($server['host'])) || (empty($server['path']) && empty($server['host']))) {
128+
throw new PhpfastcacheInvalidConfigurationException('Host must be a valid string in "$server" configuration array if path is not defined');
129+
}
130+
131+
if ((isset($server['path']) && !is_string($server['path'])) || (empty($server['host']) && empty($server['path']))) {
132+
throw new PhpfastcacheInvalidConfigurationException('Path must be a valid string in "$server" configuration array if host is not defined');
125133
}
126-
if (!is_int($server['port'])) {
134+
135+
if (!empty($server['host']) && (empty($server['port']) || !is_int($server['port'])|| $server['port'] < 1)) {
127136
throw new PhpfastcacheInvalidConfigurationException('Port must be a valid integer in "$server" configuration array');
128137
}
138+
139+
if (!empty($server['port']) && !empty($server['path'])) {
140+
throw new PhpfastcacheInvalidConfigurationException('Port should not be defined along with path');
141+
}
142+
143+
if (!empty($server['saslUser']) && !empty($server['saslPassword']) && (!is_string($server['saslUser']) || !is_string($server['saslPassword']))) {
144+
throw new PhpfastcacheInvalidConfigurationException('If provided, saslUser and saslPassword must be a string');
145+
}
129146
}
130147
$this->servers = $servers;
131148
return $this;
@@ -186,4 +203,4 @@ public function setOptPrefix(string $optPrefix): Config
186203
$this->optPrefix = trim($optPrefix);
187204
return $this;
188205
}
189-
}
206+
}

lib/Phpfastcache/Drivers/Memcached/Driver.php

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,21 @@ protected function driverConnect(): bool
9696

9797
$servers = $this->getConfig()->getServers();
9898

99-
if (count($servers) < 1) {
100-
$servers = [
99+
if (count($this->getConfig()->getServers()) < 1) {
100+
$this->getConfig()->setServers(
101101
[
102-
'host' => $this->getConfig()->getHost(),
103-
'path' => $this->getConfig()->getPath(),
104-
'port' => $this->getConfig()->getPort(),
105-
'saslUser' => $this->getConfig()->getSaslUser() ?: false,
106-
'saslPassword' => $this->getConfig()->getSaslPassword() ?: false,
107-
],
108-
];
102+
[
103+
'host' => $this->getConfig()->getHost(),
104+
'path' => $this->getConfig()->getPath(),
105+
'port' => $this->getConfig()->getPort(),
106+
'saslUser' => $this->getConfig()->getSaslUser() ?: null,
107+
'saslPassword' => $this->getConfig()->getSaslPassword() ?: null,
108+
],
109+
]
110+
);
109111
}
110112

111-
foreach ($servers as $server) {
113+
foreach ($this->getConfig()->getServers() as $server) {
112114
try {
113115
/**
114116
* If path is provided we consider it as an UNIX Socket

tests/Memcache.test.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,23 @@
66
*/
77

88
use Phpfastcache\CacheManager;
9-
use Phpfastcache\Drivers\Memcache\Config as MemcachedConfig;
9+
use Phpfastcache\Drivers\Memcache\Config as MemcacheConfig;
1010
use Phpfastcache\Tests\Helper\TestHelper;
1111

1212
chdir(__DIR__);
1313
require_once __DIR__ . '/../vendor/autoload.php';
1414
$testHelper = new TestHelper('Memcache driver');
1515

1616

17-
$config = new MemcachedConfig();
17+
$config = new MemcacheConfig([
18+
'servers' => [
19+
[
20+
'path' => '',
21+
'host' => '127.0.0.1',
22+
'port' => 11211,
23+
]
24+
]
25+
]);
1826
$config->setItemDetailedDate(true);
1927
$cacheInstance = CacheManager::getInstance('Memcache', $config);
2028
$testHelper->runCRUDTests($cacheInstance);

tests/MemcachedAlternativeConfigurationSyntax.test.php renamed to tests/Memcached.test.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
chdir(__DIR__);
1313
require_once __DIR__ . '/../vendor/autoload.php';
14-
$testHelper = new TestHelper('Memcached alternative configuration syntax');
14+
$testHelper = new TestHelper('Memcached');
1515

1616
$cacheInstanceDefSyntax = CacheManager::getInstance('Memcached');
1717

0 commit comments

Comments
 (0)