diff options
author | Jakub Zelenka <bukka@php.net> | 2017-01-22 20:44:29 +0000 |
---|---|---|
committer | Jakub Zelenka <bukka@php.net> | 2017-03-14 18:13:57 +0000 |
commit | 17e9fc9bfeaf575b25782a42937a56e809155858 (patch) | |
tree | 33bf21e8ac206a9573cfa5622137f5ca0fc5dffd | |
parent | 8e455830060fe4bd826ad089ecb22c1f567f65aa (diff) | |
download | php-git-17e9fc9bfeaf575b25782a42937a56e809155858.tar.gz |
Fix bug #72333 (fwrite() on non-blocking SSL sockets does not work)
-rw-r--r-- | ext/openssl/tests/bug72333.phpt | 54 | ||||
-rw-r--r-- | ext/openssl/xp_ssl.c | 8 |
2 files changed, 62 insertions, 0 deletions
diff --git a/ext/openssl/tests/bug72333.phpt b/ext/openssl/tests/bug72333.phpt new file mode 100644 index 0000000000..ab2b60791c --- /dev/null +++ b/ext/openssl/tests/bug72333.phpt @@ -0,0 +1,54 @@ +--TEST-- +Bug #72333: fwrite() on non-blocking SSL sockets doesn't work +--SKIPIF-- +<?php +if (!extension_loaded("openssl")) die("skip openssl not loaded"); +if (!function_exists("proc_open")) die("skip no proc_open"); +?> +--FILE-- +<?php +$serverCode = <<<'CODE' + $context = stream_context_create(['ssl' => ['local_cert' => __DIR__ . '/bug54992.pem']]); + + $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; + $fp = stream_socket_server("ssl://127.0.0.1:10011", $errornum, $errorstr, $flags, $context); + phpt_notify(); + $conn = stream_socket_accept($fp); + + for ($i = 0; $i < 5; $i++) { + fread($conn, 100000); + usleep(200000); + } +CODE; + +$clientCode = <<<'CODE' + $context = stream_context_create(['ssl' => ['verify_peer' => false, 'peer_name' => 'bug54992.local']]); + + phpt_wait(); + $fp = stream_socket_client("ssl://127.0.0.1:10011", $errornum, $errorstr, 3000, STREAM_CLIENT_CONNECT, $context); + stream_set_blocking($fp, 0); + + function blocking_fwrite($fp, $buf) { + $write = [$fp]; + $total = 0; + while (stream_select($read, $write, $except, 180)) { + $result = fwrite($fp, $buf); + $total += $result; + if ($total >= strlen($buf)) { + return $total; + } + $buf = substr($buf, $total); + } + } + + $str1 = str_repeat("a", 5000000); + blocking_fwrite($fp, $str1); + echo "done"; +CODE; + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +done + diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 9dd402a8bd..ee8137a1b5 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -1814,6 +1814,14 @@ static int php_openssl_enable_crypto(php_stream *stream, if (SUCCESS == php_set_sock_blocking(sslsock->s.socket, 0)) { sslsock->s.is_blocked = 0; + SSL_set_mode( + sslsock->ssl_handle, + ( + SSL_get_mode(sslsock->ssl_handle) | + SSL_MODE_ENABLE_PARTIAL_WRITE | + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER + ) + ); } timeout = sslsock->is_client ? &sslsock->connect_timeout : &sslsock->s.timeout; |