php / php-src

The PHP Interpreter
https://www.php.net
Other
38.05k stars 7.73k forks source link

MYSQLI_OPT_CONNECT_TIMEOUT and mysql.connect_timeout not working when connecting to a non-responsive server #15193

Open oogFranz opened 2 months ago

oogFranz commented 2 months ago

Description

I encountered an issue where the MYSQLI_OPT_CONNECT_TIMEOUT option and the mysql.connect_timeout setting do not work as expected when attempting to connect to a non-responsive server. The connection attempt hangs instead of timing out. In contrast, when attempting to connect to a non-existent server, the connection attempt fails immediately.

Steps to Reproduce:

  1. Set up a non-responsive server. I made it by python like this(tcp_server.py):
    
    import socket

HOST = '0.0.0.0' PORT = 12345

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() print(f"Listening on {HOST}:{PORT}") while True: conn, addr = s.accept() print(f"Connected by {addr}")


2. Use the mysqli extension to connect to this server with the `MYSQLI_OPT_CONNECT_TIMEOUT` option set.
```php
<?php
$connect = @mysqli_init();
mysqli_options($connect, MYSQLI_OPT_CONNECT_TIMEOUT, 5);
@mysqli_real_connect($connect, 'host.docker.internal', 'user', 'password', null, 12345, "", 0);
  1. Observe that the connection attempt does not timeout as expected.

Expected Behavior: The connection attempt should timeout after 5 seconds as specified MYSQLI_OPT_CONNECT_TIMEOUT duration and rise an exception.

Actual Behavior: The connection attempt hangs without timing out.

I used the following PHP.

php -v
PHP 8.2.21 (cli) (built: Jul 23 2024 06:55:37) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.21, Copyright (c) Zend Technologies

The mysqlnd.net_read_timeout and MYSQL_OPT_READ_TIMEOUT options work, but they affect not only the connection handshake but also every query execution, which is not desirable for our use case.

PHP Version

PHP 8.2.21

Operating System

No response

youkidearitai commented 2 months ago

Seems not reproduced on my environment (macOS and Linux(aarch64)) in default of php.ini-development.

@SakiTakamachi Could you help that?

youkidearitai commented 2 months ago

I asked @oogFranz in real, This issue an actual behavior is "the connection is continue forever, never anything raise an exception". In that case, I reproduce it.

SakiTakamachi commented 2 months ago

@oogFranz

This uses Docker, right?

Is the port for the dummy server set to tcp?

edit: Also, please tell me the OS you are running php on.

oogFranz commented 2 months ago

@SakiTakamachi

This uses Docker, right? Is the port for the dummy server set to tcp?

Yes, that's right. Actually, I made the following Dockerfile to run the python server.

FROM python:3.9-slim
WORKDIR /app
COPY tcp_server.py .
CMD ["python", "tcp_server.py"]

Then build and run it like: docker run -it --rm -p 12345:12345 tcp-server

Also, please tell me the OS you are running php on.

I run the docker php:8.2-cli image on Apple M1 Pro Sonoma 14.1.2

Thanks!

mconkin commented 1 month ago

This seems related to the bug I commented on earlier yesterday. mysqli_num_affected_rows based.

I'll still need to provide more code lines, but closer to the solution is @mysqli_real_connect( ... ).

Due to the nature of these bugs, it's likely that there are more symptom Issues on this project.

Please watch for those threads accordingly.

I'll try to notice more as they arise. I'll retroactively check any older threads for further investigation.