xref: /php-src/ext/openssl/tests/gh10495.phpt (revision 100258ff)
1--TEST--
2GH-10495: feof hangs indefinitely
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 . 'gh10495.pem.tmp';
12$cacertFile = __DIR__ . DIRECTORY_SEPARATOR . 'gh10495-ca.pem.tmp';
13
14$peerName = 'gh10495';
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("tlsv1.2://127.0.0.1:10012", $errornum, $errorstr, 1, STREAM_CLIENT_CONNECT, $context);
23
24    phpt_wait('proxy');
25
26    $time = microtime(true);
27    var_dump(feof($fp));
28    var_dump(microtime(true) - $time < 0.5);
29
30    var_dump(stream_get_contents($fp, 6));
31
32    phpt_notify('server');
33    phpt_notify('proxy');
34CODE;
35$clientCode = sprintf($clientCode, $peerName);
36
37$serverCode = <<<'CODE'
38    $context = stream_context_create(['ssl' => ['local_cert' => '%s']]);
39
40    $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
41    $fp = stream_socket_server("tlsv1.2://127.0.0.1:10011", $errornum, $errorstr, $flags, $context);
42    phpt_notify();
43
44    $conn = stream_socket_accept($fp);
45    fwrite($conn, 'warmup');
46
47    phpt_wait();
48    fclose($conn);
49CODE;
50$serverCode = sprintf($serverCode, $certFile);
51
52$proxyCode = <<<'CODE'
53    phpt_wait();
54
55    $upstream = stream_socket_client("tcp://127.0.0.1:10011", $errornum, $errorstr, 3000, STREAM_CLIENT_CONNECT);
56    stream_set_blocking($upstream, false);
57
58    $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
59    $server = stream_socket_server("tcp://127.0.0.1:10012", $errornum, $errorstr, $flags);
60    phpt_notify();
61    $conn = stream_socket_accept($server);
62    stream_set_blocking($conn, false);
63
64    $read = [$upstream, $conn];
65    $applicationData = false;
66    while (stream_select($read, $write, $except, 1)) {
67        foreach ($read as $fp) {
68            $data = stream_get_contents($fp);
69            if ($fp === $conn) {
70                fwrite($upstream, $data);
71            } else {
72                foreach (phpt_extract_tls_records($data) as $record) {
73                    if ($record !== '' && $record[0] === chr(23)) {
74                        if (!$applicationData) {
75                            $applicationData = true;
76                            fwrite($conn, $record[0]);
77                            phpt_notify();
78                            sleep(1);
79                            fwrite($conn, substr($record, 1));
80                        } else {
81                            fwrite($conn, $record);
82                        }
83                    } else {
84                        fwrite($conn, $record);
85                    }
86                }
87            }
88        }
89        if (feof($upstream)) {
90            break;
91        }
92        $read = [$upstream, $conn];
93    }
94
95    phpt_wait();
96CODE;
97
98include 'CertificateGenerator.inc';
99$certificateGenerator = new CertificateGenerator();
100$certificateGenerator->saveCaCert($cacertFile);
101$certificateGenerator->saveNewCertAsFileWithKey($peerName, $certFile);
102
103include 'ServerClientTestCase.inc';
104ServerClientTestCase::getInstance()->run($clientCode, [
105    'server' => $serverCode,
106    'proxy' => $proxyCode,
107]);
108?>
109--CLEAN--
110<?php
111@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'gh10495.pem.tmp');
112@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'gh10495-ca.pem.tmp');
113?>
114--EXPECT--
115bool(false)
116bool(true)
117string(6) "warmup"
118