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