php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #49295 stream_socket_client() fails on SSL+async
Submitted: 2009-08-19 13:52 UTC Modified: 2010-12-09 04:47 UTC
Votes:12
Avg. Score:4.4 ± 1.2
Reproduced:10 of 12 (83.3%)
Same Version:3 (30.0%)
Same OS:4 (40.0%)
From: frase at cs dot wisc dot edu Assigned:
Status: Open Package: OpenSSL related
PHP Version: 5.2.11, 5.3.1 OS: win32 only - Win 2000 Pro SP4
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: frase at cs dot wisc dot edu
New email:
PHP Version: OS:

 

 [2009-08-19 13:52 UTC] frase at cs dot wisc dot edu
Description:
------------
stream_socket_client() can only open one socket using SSL and the STREAM_CLIENT_ASYNC_CONNECT flag, and then fails every time until the Apache process is restarted.  SSL sockets without ASYNC open fine, as do plain TCP sockets with or without ASYNC.

Originally reported as an update to bug #48182, which also only affected the combination of SSL+ASYNC, but now reported separately here per srinatar@php.net's request.

Additionally, the timeout (argument #4 to stream_socket_client()) is not ignored when using ASYNC, contrary to the manual: if set to 0 here, the first warning is "SSL: connection timeout" instead of "SSL: The operation completed successfully."

Windows 2000 Professional SP4
Apache 2.2.11
PHP 5.2.11RC1-Win32-VC6-x86 (threadsafe binary from http://windows.php.net/qa/)
configured as an Apache module
with php_openssl.dll and libeay32.dll+ssleay.dll v0.9.8k


Reproduce code:
---------------
<?php
header('Content-Type: text/plain');
$errno = null;
$errstr = null;
$socket = stream_socket_client(
		'ssl://'.gethostbyname('launchpad.net').':443', $errno, $errstr,
		10, // timeout should be ignored when ASYNC
		STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT
);
if (!$socket) {
	echo "errno = ".$errno."\nerrstr = ".$errstr."\n";
	exit;
}
stream_set_blocking($socket, 0);
$data = "GET / HTTP/1.0\r\nHost: launchpad.net\r\nConnection: close\r\n\r\n";
$selR = null;
$selW = array();
$selE = null;
while ($data) {
	$selW[0] = $socket;
	if (stream_select($selR, $selW, $selE, 10)) {
		$wrote = fwrite($socket, $data, strlen($data));
		$data = substr($data, $wrote);
	}
}
$html = "";
$selR = array($socket);
$selW = null;
while (!feof($socket)) {
	$selR[0] = $socket;
	if (stream_select($selR, $selW, $selE, 10))
		$html .= fread($socket, 8192);
}
fclose($socket);
echo "OK!\n----------\n".$html;


Expected result:
----------------
OK!
----------
(HTTP headers and content from launchpad.net)

Actual result:
--------------
Warning: stream_socket_client() [function.stream-socket-client]: SSL: The operation completed successfully. in test-async-ssl.php on line 8

Warning: stream_socket_client() [function.stream-socket-client]: Failed to enable crypto in test-async-ssl.php on line 8

Warning: stream_socket_client() [function.stream-socket-client]: unable to connect to ssl://91.189.90.211:443 (Unknown error) in test-async-ssl.php on line 8
errno = 10035 errstr = 


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-08-21 01:15 UTC] srinatar@php.net
this issue seems to be happening when this script is executed more than once and also seems to be happening only on windows. 
 [2009-08-21 15:05 UTC] frase at cs dot wisc dot edu
I had a chance to compile and test PHP5.2.11RC1 under Linux this morning (Ubuntu Jaunty, Apache 2.2.11 from repositories), and these warnings do not appear, however I noticed another problem.

Although the SSL+async connection is successful and data is returned under Linux, the socket is not actually opened asynchonously.  The script blocks until the socket has finished opening, exactly as it does without the ASYNC flag.  This is also true under Windows, for the first run -- after that, of course, it returns the errors posted above.
 [2009-09-02 08:09 UTC] srinatar@php.net
ok, i was looking into this issue today. the issue is that , 
especially on windows -where sockets are not file descriptors unlike 
in unix, async sockets and openssl works together only if we use BIO 
wrappers provided by openssl module instead of directly accessing 
underlying sockets as file descriptors. 

the possible right way to do this would be to use  to socket wrappers 
provided by  SSL module (known as BIO wrappers which makes it work 
properly on windows).

this will require some amount of fiddling our openssl module. i don't 
think, 5.2 is a good place to do this change.  

for now, commenting this below code should help you to run your script 
properly on windows. 
stream_set_blocking($socket, 0);

i will spend more time on this and investigate on the best way to use 
BIO wrappers within existing openssl module say within php 5.3
 [2009-09-02 08:38 UTC] srinatar@php.net
just a follow up note, this issue (async not working consistently with 
openssl on windows) has always been the case and this issue has nothing 
to do with the fix that went in for bug:48182.
 [2009-09-02 14:17 UTC] frase at cs dot wisc dot edu
Commenting the stream_set_blocking() doesn't change anything for me on Windows.  SSL+ASYNC still works exactly once (but doesn't actually connect asynchronously) and then gives the warnings; SSL+SYNC still works fine, as does TCP+ASYNC.

Thanks for your work on this.  I get complaints about it every week because if the remote server doesn't respond then our software gets stuck in the connection phase, and since the connection phase cannot be made asynchronous, the user is unable to abort it and just has to wait.
 [2009-09-04 13:21 UTC] frase at cs dot wisc dot edu
I'm sure this is expected, but the bug remains in 5.2.11RC2.

I also noticed another clue: I mentioned previously that SSL+ASYNC works once (but not asynchronously) after starting Apache, and then fails and throws warnings.  It turns out any SSL socket connection will cause future SSL+ASYNC attempts to do this, even if the first one was SYNC.  So to get SSL+ASYNC to connect, it must be the very first SSL socket opened since Apache started.
 [2009-09-16 18:22 UTC] srinatar@php.net
as i mentioned to you last time, our openssl implementation is incorrectly using file based sockets instead of openssl provided 'BIO'  for underlying communication. this will require re-implementation of some of php's openssl implementation. 

this should be an issue only on windows. 
 [2009-12-11 01:09 UTC] pajoye@php.net
Having read the backlog, will you work on that or completely give up on this bug (saw that you unassigned this bug)?
 [2009-12-19 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2010-01-25 20:31 UTC] frase at cs dot wisc dot edu
This bug was "suspended automatically" by the bug system because "no feedback was provided for this bug for over a week," although it seems to me the feedback required is from a PHP developer, not from me.

Nonetheless, here's some feedback to reopen it: I'd still love to see this fixed.  :)
 [2010-05-09 22:59 UTC] felipe@php.net
-Status: Open +Status: Assigned
 [2010-12-09 04:47 UTC] srinatar@php.net
-Assigned To: srinatar +Assigned To:
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 09 22:01:27 2024 UTC