xref: /PHP-7.1/ext/openssl/tests/bug74159.phpt (revision 3c42f64e)
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