summaryrefslogtreecommitdiff
path: root/src/Server.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/Server.php')
-rw-r--r--src/Server.php38
1 files changed, 35 insertions, 3 deletions
diff --git a/src/Server.php b/src/Server.php
index 46c7dca..102c4fd 100644
--- a/src/Server.php
+++ b/src/Server.php
@@ -12,19 +12,29 @@ class Server
'passphrase' => null,
];
+ protected array $options = [];
+
protected array $requestHandlers = [];
/**
* @param array $certificate
* @param string $hostname
+ * @param array $options
*/
public function __construct(
array $certificate,
- string $hostname = 'localhost'
+ string $hostname = 'localhost',
+ array $options = []
)
{
$this->certificate = $certificate;
$this->hostname = $hostname;
+
+ $this->options = array_replace_recursive([
+ 'context' => [],
+ 'client_certificate_support_workaround' => false, # "support" until https://bugs.php.net/bug.php?id=80770
+ 'client_certificate_support_workaround_timeout' => 3,
+ ], $options);
}
public function setCertificate(string $certificateFile, string $keyFile, string $passphrase = ''): static
@@ -47,7 +57,7 @@ class Server
public function listen(int $port = 1965): void
{
- $context = stream_context_create(options: [
+ $contextOptions = array_replace_recursive([
'ssl' => [
'local_cert' => $this->certificate['file'],
'local_pk' => $this->certificate['key'],
@@ -55,8 +65,11 @@ class Server
'allow_self_signed' => true,
'verify_peer' => false,
+ 'capture_peer_cert' => true,
],
- ]);
+ ], $this->options['context']);
+
+ $context = stream_context_create(options: $contextOptions);
$socket = stream_socket_server(
address: "tls://{$this->hostname}:{$port}",
@@ -66,6 +79,11 @@ class Server
$connections = [];
while (true) {
+ if ($this->options['client_certificate_support_workaround']) {
+ stream_context_set_option($socket, 'ssl', 'verify_peer', true);
+ }
+
+ echo "Listening for connections.\n";
$connection = stream_socket_accept(
socket: $socket,
timeout: empty($connections) ? -1 : 0,
@@ -74,6 +92,20 @@ class Server
if ($connection) {
$connections[$peer] = $connection;
+ } else if ($this->options['client_certificate_support_workaround']) {
+ echo "Enabling client certificate \"support\" workaround.\n";
+ echo "Listening without verifying peer.\n";
+
+ stream_context_set_option($socket, 'ssl', 'verify_peer', false);
+ $connection = stream_socket_accept(
+ socket: $socket,
+ timeout: $this->options['client_certificate_support_workaround_timeout'],
+ peer_name: $peer
+ );
+
+ if ($connection) {
+ $connections[$peer] = $connection;
+ }
}
if (count($connections) == 0) {