ID: 49486 Updated by: sjo...@php.net Reported By: kernins at gmail dot com -Status: Open +Status: Bogus Bug Type: Sockets related Operating System: Debian 4.0, WinXP SP3 PHP Version: 5.2.9, 5.3.0 New Comment:
Thank you for your report. Socket_read only returns false when the remote end has closed the connection. It will not return false when the remote side has not closed the connection but does not send data anymore. This is expected behavior. Socket_read can not detect the "end of data", other than the other side closing the connection. Previous Comments: ------------------------------------------------------------------------ [2009-09-06 13:34:50] kernins at gmail dot com Description: ------------ App description: Script should connect to socks4/5 or CONNECT proxy and establish a tunnel to some host, google.com:80, for example. Problem: socket_read() couldn't detect the end of data while reading response from socks4/5 server (response to initial hello msg or connect command) or from connect-proxy (response to connect command). Reproduce code: --------------- $host=gethostbyname("google.com"); $port=80; $proxy_ip="212.27.33.4"; $proxy_port=8118; if(!preg_match('/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/',$host,$ip)) die(); $s5_init="\x05\x01\x00"; $s5_connect="\x05\x01\x00\x01".chr($ip[1]).chr($ip[2]).chr($ip[3]).chr($ip[4]).pack('n',$port); $s4="\x04\x01".pack('n',$port).chr($ip[1]).chr($ip[2]).chr($ip[3]).chr($ip[4])."\x00"; $connect="CONNECT google.com:80 HTTP/1.1\r\nProxy-Connection: keep-alive\r\n\r\n"; $sock=socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_set_option($sock,SOL_SOCKET,SO_SNDTIMEO,array('sec'=>5,'usec'=>0)); socket_set_option($sock,SOL_SOCKET,SO_RCVTIMEO,array('sec'=>15,'usec'=>0)); socket_connect($sock,$proxy_ip,$proxy_port); echo "written: ".socket_write($sock,$connect).PHP_EOL; //$data=socket_read($sock,1024,PHP_BINARY_READ); while($data=socket_read($sock,1024,PHP_BINARY_READ)) var_dump($data); $err=socket_last_error($sock); $e=socket_get_option($sock,SOL_SOCKET,SO_ERROR); var_dump($data,$err,socket_strerror($err),$e,socket_strerror($e)); Expected result: ---------------- In blocking mode: while($data=socket_read($sock,1024,PHP_BINARY_READ)) will make two or more iterations, at last iteration socket_read will return emty string indicating end of data. In non-blocking mode: socket_select will return socket two or more times as ready for reading. Last time socket_read will return emty string indicating end of data. Actual result: -------------- In blocking mode: if I use a single socket_read($sock,1024,PHP_BINARY_READ) call, it returns data without any significant delay or error. In that case there are no problems. But while($data=socket_read($sock,1024,PHP_BINARY_READ)) will return all response in first iteration and then blocks until timeout was reached (if I set it via socket_set_option) and return false with EAGAIN error. If timeout is not set it will return epmty string and no errors as expected, but before this block for couple of minutes. In non-blocking: Whole response was also successfully recieved after first socket_select return, and then this socket has no more returned by socket_select as ready for reading. I've tested this on debian PHP 5.2.9-0.dotdeb.1 with Suhosin-Patch 0.9.7 and WinXP php 5.3.0 (binary from php.net) with some public socks and connect proxies and with SHHTunnel 4.3.0.0 for Win which has built in socks 4/5 proxy. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=49486&edit=1