codeigniter4 / CodeIgniter4

Open Source PHP Framework (originally from EllisLab)
https://codeigniter.com/
MIT License
5.39k stars 1.9k forks source link

Bug: Redis session with socket #6929

Closed matrox445 closed 1 year ago

matrox445 commented 1 year ago

PHP Version

7.4

CodeIgniter4 Version

4.2.10

CodeIgniter4 Installation Method

Manual (zip or tar.gz)

Which operating systems have you tested for this bug?

Linux

Which server did you use?

apache

Database

MariaDB 10.5.15

What happened?

Codeigniter session throw this error when using Redis with socket: RedisException: php_network_getaddresses: getaddrinfo failed: Name or service not known.

Steps to Reproduce

Configure Codeigniter to use Redis session and use a socket host (ex: /tmp/redis.sock).

Expected Output

A working Redis session.

Anything else?

In the RedisHandler session file, default port is set to 6379. When using a socket, we want a port set to 0. Here is my working patch on the system/Session/Handlers/RedisHandler.php file, line 121 :

change this : if (! $redis->connect($this->savePath['host'], $this->savePath['port'], $this->savePath['timeout'])) {

to this : if (! $redis->connect($this->savePath['host'], ($this->savePath['host'][0] === '/' ? 0 : $this->savePath['port']), $this->savePath['timeout'])) {

No more RedisException.

kenjis commented 1 year ago

Thank you for reporting.

Can you send a PR? https://github.com/codeigniter4/CodeIgniter4/blob/develop/contributing/pull_request.md

ddevsr commented 1 year ago

@matrox445 Why you set port 0? You can read this

What you changed is not correct. 0 will give return true in empty($matches[2])

https://github.com/codeigniter4/CodeIgniter4/blob/develop/system/Session/Handlers/RedisHandler.php#L96

matrox445 commented 1 year ago

@ddevsr Actually, i just copy/paste the line 74 of the system/Cache/handlers/RedisHandler.php to make it work for the session handler. I'm not sure what is the best way to do it.

My proposal is not impacting the line 96, since i'm using a socket host ("/tmp/redis.sock"). I don't set any port.

kenjis commented 1 year ago

@ddevsr 0 seems okay.

$redis->connect('/tmp/redis.sock'); // unix domain socket.
$redis->connect('/tmp/redis.sock', 0, 1.5, NULL, 0, 1.5); // Unix socket with 1.5s timeouts (connect and read)

See https://github.com/phpredis/phpredis#connect-open