--- /dev/null
+--TEST--
+client http2
+--SKIPIF--
+<?php
+include "skipif.inc";
+skip_client_test();
+skip_http2_test();
+?>
+--FILE--
+<?php
+
+include "helper/server.inc";
+
+echo "Test\n";
+
+nghttpd(function($port) {
+ $client = new http\Client;
+ $client->setOptions([
+ "protocol" => http\Client\Curl\HTTP_VERSION_2_0,
+ "ssl" => [
+ "cainfo" => __DIR__."/helper/http2.crt",
+ ]
+ ]);
+ $client->enqueue(new http\Client\Request("GET", "https://localhost:$port"));
+ echo $client->send()->getResponse();
+});
+
+?>
+===DONE===
+--EXPECTF--
+Test
+HTTP/2.0 200
+%a
+
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>HTTP2</title>
+ </head>
+ <body>
+ Nothing to see here.
+ </body>
+</html>
+===DONE===
--- /dev/null
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>HTTP2</title>
+ </head>
+ <body>
+ Nothing to see here.
+ </body>
+</html>
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIDNzCCAh+gAwIBAgIJAKOw1awbt7aIMA0GCSqGSIb3DQEBCwUAMDIxCzAJBgNV
+BAYTAkFUMQ8wDQYDVQQKDAZQSFAgUUExEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0x
+NTAyMTIxMjQ2NTRaFw0xNzExMDcxMjQ2NTRaMDIxCzAJBgNVBAYTAkFUMQ8wDQYD
+VQQKDAZQSFAgUUExEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAMxa+A6xEKQOYme55nQyu0qpvvGB4c4wGBNa6X6YAEzE
+Hc19Nbix02UZWQgHM1dmBhbVDW3stO42CQmcViIKfAy5R1A9UZjUcn9nQpaxL/sp
+9LrrCANyljISXS40QcBvhCzmcUvDWBRhVTGjV+QTaYmmaM+8hJJJM6W7ByIP22Zv
+jHoAnzTx9sjs+OMyWmjYT9pWv6aE+u5iSC8bn3B0GgtfPwoPqDF8ePxIMBpmtbk7
+JqXFzHxTVywkypnsF34XK94QjpvRcFGSg/Dc1TopJG2Wfq8hxwtoKerSlL5tyKy0
+ZrltxCiLkfVZixwNZEqkg7jPSUvLS299mBrwy+ikmr8CAwEAAaNQME4wHQYDVR0O
+BBYEFDiHynoXXjMChfYhc1k7TNtU8ey0MB8GA1UdIwQYMBaAFDiHynoXXjMChfYh
+c1k7TNtU8ey0MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAGD9GERC
+uJv+oHfMwkNkDV5ZB4F+SQPzXVxDx+rJm1aGJs9PcwPNiV5GweXbvgcnvRAL4h8h
+uv3MLQPgVOq0iqp1QPFCoUXxbYYjYzi9FVbR/154sg0uWEHElU2e3fSjcinNRfXD
+12232k6HNwSeeZUFQqn2fuk+cae5BsYT8GfsyMq5EfPtG2d8IG+Ji4eEOJeKu4gl
+Y33yQnHhw6QKbx8vWaDpZK8qtpapCtLrTtw/nRhX5YV6kMGK+htQUK1etV2O0VQQ
+OtDrhOWWaDxQULsHIvCMgTTnZqNQD+Xz4MBm3PGEGi/QUsrEaSQYppb8xxQKZU4X
+MyTh7rO5TdNSXmo=
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAzFr4DrEQpA5iZ7nmdDK7Sqm+8YHhzjAYE1rpfpgATMQdzX01
+uLHTZRlZCAczV2YGFtUNbey07jYJCZxWIgp8DLlHUD1RmNRyf2dClrEv+yn0uusI
+A3KWMhJdLjRBwG+ELOZxS8NYFGFVMaNX5BNpiaZoz7yEkkkzpbsHIg/bZm+MegCf
+NPH2yOz44zJaaNhP2la/poT67mJILxufcHQaC18/Cg+oMXx4/EgwGma1uTsmpcXM
+fFNXLCTKmewXfhcr3hCOm9FwUZKD8NzVOikkbZZ+ryHHC2gp6tKUvm3IrLRmuW3E
+KIuR9VmLHA1kSqSDuM9JS8tLb32YGvDL6KSavwIDAQABAoIBAQCzUdAB9FYJ36Vy
+J6qVpD69EZ7ABZzDdWhq84eY0oDQ2/ba7lhJraE2QbviU481zgzh1CponyFVNo1P
+paPfUxvvflWZj3Ueiq2+JjpESU81MmfR7ZOmktJBNeQWOzzHRBPT4pLgTJXprE85
+s3/YX0BozWGDiIU8aIetkiR8OzXm97+BrJWiPFl733dGnHvfpHAZu/PwKZc2+8ft
+CnQw4GHRhTBWCVNj29HLwm+CA66zQqiAXItgijWMKzs+9ciPn+aCsCnZDNF+o1zs
+4pWt60CtIJQtD3r3rSRy7nBaCKcTrr/JU3FvwqKdunuUBUsuYeSaMBokW67kpVzS
+dO9L9p6BAoGBAP+pvcAd8qfC1WIrn9vka3aK25ulbYSCae3YaWmABc93INJPBMvO
+GrcUuaLKiQC1oou+E64vGyJ9MeEFwxh2zbvU75a9ezeKAajgaq92ciMX2QqREh0N
+IntNOc4w7eB6BK8NpaDXNvTtxNWMvlYyhVN0M7FVQRmYJfCJdnTZAkzvAoGBAMyf
+6rvWuc/wmIcAtBVe+jIeQ69EJJ/Idcjk0JUm6lFECAAraPpsCglha+wTHWWRQZ9u
+pPqBnb7QPjevU+3bZHnMvGoEzd5F4Rw74J+p5EZeMUJpuKmon7Ekzemcb0DV+qX9
+NorB781D2Z0MG9SCptKyKpN5TPHTjGz4BB3mLC8xAoGAdq99/ynn9ClmleRameI4
+YRelS2RIqzM/qcLFbMyZ5e4PtpIoT9SmYkekxgXwA/xOMUFUMZB8sE4eUbAzGbBN
+Yd1APGJKSUYv7w3/eOUrp07y2wzts77dOxBmvWnJhGQguINFWJ2QTbPzpI9p7OoX
+Kt7PAIvrZM5VDo1CCIyVnNECgYEAgLmpZXlzcwicK3GZ2EfjhVvcoIlxsMLetf6b
+6PiON4lgrxqf88m7lqMezWhI+fgjHDTyvFSF89/1A/rcBaoazzSo4tka2VWEg8p3
+SHoMDOh8fJcdgD2AGGRa1TeAFX2HLJzajvfp72tbnpxbdZircah7eEK60PaQRIzR
+qi1+ZkECgYEAi7GkO7Ey98DppLnt7567veQoEj0u8ixTlCyJ4V278nHR5+6eAZP5
+PfdZVC3MtKGLnxrrPTVUy5wU0hR6Gk9EVDmrAF8TgJdnZFlBK7X23eWZ0q4qO/eO
+3xIi+UrNwLag8BjYOr32nP/i+F+TLikgRIFR4oiZjk867+ofkTXmNFA=
+-----END RSA PRIVATE KEY-----
function serve(callable $cb) {
foreach (range(8000, 9000) as $port) {
- if (($server = stream_socket_server("tcp://localhost:$port"))) {
+ if (($server = @stream_socket_server("tcp://localhost:$port"))) {
fprintf(STDERR, "%s\n", $port);
do {
$R = [$server]; $W = []; $E = [];
}
function server($handler, callable $cb) {
- $spec = array(array("pipe","r"), array("pipe","w"), array("pipe","w"));
- $comm = sprintf("%s %s/%s", PHP_BINARY, __DIR__, $handler);
- if (($proc = proc_open($comm, $spec, $pipes, __DIR__))) {
- $port = trim(fgets($pipes[2]));
+ proc(PHP_BINARY, [__DIR__."/$handler"], $cb);
+}
+
+function nghttpd(callable $cb) {
+ $spec = [["pipe","r"], ["pipe","w"], ["pipe","w"]];
+ foreach (range(8000, 9000) as $port) {
+ $comm = "exec nghttpd -d html $port http2.key http2.crt";
+ if (($proc = proc_open($comm, $spec, $pipes, __DIR__))) {
+ $stdin = $pipes[0];
+ $stdout = $pipes[1];
+ $stderr = $pipes[2];
+
+ usleep(50000);
+ $status = proc_get_status($proc);
+
+ if (!$status["running"]) {
+ continue;
+ }
+
+ try {
+ $cb($port, $stdin, $stdout, $stderr);
+ } catch (Exception $e) {
+ echo $e,"\n";
+ }
- try {
- $cb($port, $stdin = $pipes[0], $stdout = $pipes[1], $stderr = $pipes[2]);
- } catch (Exception $e) {
- echo $e,"\n";
+ proc_terminate($proc);
+
+ fpassthru($stderr);
+ fpassthru($stdout);
+ return;
}
+ }
+
+}
+
+function proc($bin, $args, callable $cb) {
+ $spec = [["pipe","r"], ["pipe","w"], ["pipe","w"]];
+ $comm = escapeshellcmd($bin) . " ". implode(" ", array_map("escapeshellarg", $args));
+ if (($proc = proc_open($comm, $spec, $pipes, __DIR__))) {
+ $stdin = $pipes[0];
+ $stdout = $pipes[1];
+ $stderr = $pipes[2];
+ do {
+ $port = trim(fgets($stderr));
+ $R = [$stderr]; $W = []; $E = [];
+ } while (is_numeric($port) && stream_select($R, $W, $E, 0, 10000));
+
+ if (is_numeric($port)) {
+ try {
+ $cb($port, $stdin, $stdout, $stderr);
+ } catch (Exception $e) {
+ echo $e,"\n";
+ }
+ }
+
proc_terminate($proc);
-
+
fpassthru($stderr);
fpassthru($stdout);
}
-}
+}
\ No newline at end of file
die($message);
}
}
+
+function skip_http2_test($message = "skip need http2 support (nghttpd in PATH)\n") {
+ foreach (explode(":", $_ENV["PATH"]) as $path) {
+ if (is_executable($path . "/nghttpd")) {
+ return;
+ }
+ }
+ die($message);
+}
\ No newline at end of file