summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Zelenka <bukka@php.net>2017-01-22 20:44:29 +0000
committerJakub Zelenka <bukka@php.net>2017-03-14 18:13:57 +0000
commit17e9fc9bfeaf575b25782a42937a56e809155858 (patch)
tree33bf21e8ac206a9573cfa5622137f5ca0fc5dffd
parent8e455830060fe4bd826ad089ecb22c1f567f65aa (diff)
downloadphp-git-17e9fc9bfeaf575b25782a42937a56e809155858.tar.gz
Fix bug #72333 (fwrite() on non-blocking SSL sockets does not work)
-rw-r--r--ext/openssl/tests/bug72333.phpt54
-rw-r--r--ext/openssl/xp_ssl.c8
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;