com php-src: Fix bug #72333 (fwrite() on non-blocking SSL sockets does not work): ext/openssl/tests/bug72333.phpt ext/openssl/xp_ssl.c

[email protected] (Jakub Zelenka)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    17e9fc9bfeaf575b25782a42937a56e809155858
Author:    Jakub Zelenka <[email protected]>         Sun, 22 Jan 2017 20:44:29 +0000
Parents:   8e455830060fe4bd826ad089ecb22c1f567f65aa
Branches:  PHP-7.0

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=17e9fc9bfeaf575b25782a42937a56e809155858

Log:
Fix bug #72333 (fwrite() on non-blocking SSL sockets does not work)

Bugs:
https://bugs.php.net/72333

Changed paths:
  A  ext/openssl/tests/bug72333.phpt
  M  ext/openssl/xp_ssl.c


Diff:
diff --git a/ext/openssl/tests/bug72333.phpt b/ext/openssl/tests/bug72333.phpt
new file mode 100644
index 0000000..ab2b607
--- /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 9dd402a..ee8137a 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;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.