1--TEST-- 2Bug #74159: Writing a large buffer to non-blocking encrypted streams fails 3--SKIPIF-- 4<?php 5if (!extension_loaded("openssl")) die("skip openssl not loaded"); 6if (!function_exists("proc_open")) die("skip no proc_open"); 7?> 8--FILE-- 9<?php 10// the server code is doing many readings in a short interval which is 11// not really reliable on more powerful machine but cover different 12// scenarios which might be useful. More reliable test is bug72333.phpt 13$serverCode = <<<'CODE' 14 $serverUri = "ssl://127.0.0.1:10012"; 15 $serverFlags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN; 16 $serverCtx = stream_context_create(['ssl' => [ 17 'local_cert' => __DIR__ . '/bug54992.pem', 18 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, 19 ]]); 20 21 $server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx); 22 phpt_notify(); 23 24 $client = stream_socket_accept($server, 1); 25 26 if (!$client) { 27 exit(); 28 } 29 30 $data = ''; 31 while (strlen($data) < 0xfffff) { 32 $buffer = fread($client, 8192); 33 if (empty($buffer)) { 34 exit(); 35 } 36 $data .= $buffer; 37 usleep(100); 38 } 39 40 fclose($client); 41CODE; 42 43$clientCode = <<<'CODE' 44 function streamRead($stream) : int { 45 return strlen(fread($stream, 8192)); 46 } 47 48 function streamWrite($stream, $data) : int { 49 return fwrite($stream, $data); 50 } 51 52 function waitForWrite(...$streams) : bool { 53 $read = null; 54 $except = null; 55 while($streams && !($n = stream_select($read, $streams, $except, 1))); 56 return $n > 0; 57 } 58 59 function waitForRead(...$streams) : bool { 60 $write = null; 61 $except = null; 62 while ($streams && !($n = stream_select($streams, $write, $except, 1))); 63 return $n > 0; 64 } 65 66 set_error_handler(function ($errno, $errstr) { 67 exit("$errstr\n"); 68 }); 69 70 $serverUri = "tcp://127.0.0.1:10012"; 71 $clientFlags = STREAM_CLIENT_CONNECT; 72 $clientCtx = stream_context_create(['ssl' => [ 73 'verify_peer' => true, 74 'cafile' => __DIR__ . '/bug54992-ca.pem', 75 'peer_name' => 'bug54992.local', 76 ]]); 77 78 phpt_wait(); 79 80 $fp = stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx); 81 82 stream_set_blocking($fp, false); 83 while (0 === ($n = stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT))); 84 85 $data = str_repeat("a", 0xfffff); 86 $written = 0; 87 $total = $written; 88 while(!empty($data)) { 89 $written = streamWrite($fp, $data); 90 $total += $written; 91 $data = substr($data, $written); 92 waitForWrite($fp); 93 } 94 printf("Written %d bytes\n", $total); 95 96 while(waitForRead($fp)) { 97 streamRead($fp); 98 if (feof($fp)) { 99 break; 100 } 101 } 102 103 exit("DONE\n"); 104CODE; 105 106include 'ServerClientTestCase.inc'; 107ServerClientTestCase::getInstance()->run($clientCode, $serverCode); 108?> 109--EXPECTF-- 110Written 1048575 bytes 111DONE 112