1--TEST-- 2Bug #76705: feof might hang on TLS streams in case of fragmented TLS records 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$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'bug77390.pem.tmp'; 11$cacertFile = __DIR__ . DIRECTORY_SEPARATOR . 'bug77390-ca.pem.tmp'; 12 13$peerName = 'bug77390'; 14$clientCode = <<<'CODE' 15 $context = stream_context_create(['ssl' => ['verify_peer' => false, 'peer_name' => '%s']]); 16 17 phpt_wait('server'); 18 phpt_notify('proxy'); 19 20 phpt_wait('proxy'); 21 $fp = stream_socket_client("ssl://127.0.0.1:10012", $errornum, $errorstr, 3000, STREAM_CLIENT_CONNECT, $context); 22 stream_set_blocking($fp, false); 23 24 $read = [$fp]; 25 $buf = ''; 26 $emptyChunkPrinted = false; 27 $warmedUp = false; 28 while (stream_select($read, $write, $except, 1000)) { 29 $chunk = stream_get_contents($fp, 4096); 30 $buf .= $chunk; 31 phpt_notify('proxy'); 32 if (!$warmedUp) { 33 if ($buf !== 'warmup') { 34 continue; 35 } 36 $warmedUp = true; 37 $buf = ''; 38 phpt_notify('server'); 39 continue; 40 } 41 if ($chunk !== '' || !$emptyChunkPrinted) { 42 $emptyChunkPrinted = true; 43 var_dump($chunk); 44 } 45 if ($buf === 'hello, world') { 46 break; 47 } 48 } 49 50 phpt_notify('server'); 51 phpt_notify('proxy'); 52CODE; 53$clientCode = sprintf($clientCode, $peerName); 54 55$serverCode = <<<'CODE' 56 $context = stream_context_create(['ssl' => ['local_cert' => '%s']]); 57 58 $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; 59 $fp = stream_socket_server("ssl://127.0.0.1:10011", $errornum, $errorstr, $flags, $context); 60 phpt_notify(); 61 62 $conn = stream_socket_accept($fp); 63 fwrite($conn, 'warmup'); 64 phpt_wait(); 65 fwrite($conn, 'hello, world'); 66 67 phpt_wait(); 68 fclose($conn); 69CODE; 70$serverCode = sprintf($serverCode, $certFile); 71 72$proxyCode = <<<'CODE' 73 phpt_wait(); 74 75 $upstream = stream_socket_client("tcp://127.0.0.1:10011", $errornum, $errorstr, 3000, STREAM_CLIENT_CONNECT); 76 stream_set_blocking($upstream, false); 77 78 $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; 79 $server = stream_socket_server("tcp://127.0.0.1:10012", $errornum, $errorstr, $flags); 80 phpt_notify(); 81 82 $conn = stream_socket_accept($server); 83 stream_set_blocking($conn, false); 84 85 $read = [$upstream, $conn]; 86 while (stream_select($read, $write, $except, 1)) { 87 foreach ($read as $fp) { 88 $data = stream_get_contents($fp); 89 if ($fp === $conn) { 90 fwrite($upstream, $data); 91 } else { 92 if ($data !== '' && $data[0] === chr(23)) { 93 $parts = str_split($data, (int) ceil(strlen($data) / 3)); 94 foreach ($parts as $part) { 95 fwrite($conn, $part); 96 phpt_wait(null, 1); 97 } 98 } else { 99 fwrite($conn, $data); 100 } 101 } 102 } 103 if (feof($upstream)) { 104 break; 105 } 106 $read = [$upstream, $conn]; 107 } 108 109 phpt_wait(); 110CODE; 111 112include 'CertificateGenerator.inc'; 113$certificateGenerator = new CertificateGenerator(); 114$certificateGenerator->saveCaCert($cacertFile); 115$certificateGenerator->saveNewCertAsFileWithKey($peerName, $certFile); 116 117include 'ServerClientTestCase.inc'; 118ServerClientTestCase::getInstance()->run($clientCode, [ 119 'server' => $serverCode, 120 'proxy' => $proxyCode, 121]); 122?> 123--CLEAN-- 124<?php 125@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug77390.pem.tmp'); 126@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug77390-ca.pem.tmp'); 127?> 128--EXPECT-- 129string(0) "" 130string(12) "hello, world" 131