-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
Proof of concept
Adding a second socket with ssl context options:
diff --git a/src/main/php/xp/web/srv/Standalone.class.php b/src/main/php/xp/web/srv/Standalone.class.php
index 0e5be20..3d4dccf 100755
--- a/src/main/php/xp/web/srv/Standalone.class.php
+++ b/src/main/php/xp/web/srv/Standalone.class.php
@@ -30,12 +30,27 @@ abstract class Standalone implements Server {
$environment= new Environment($profile, $webroot, $docroot, $config, $args, $logging);
$application= (new Source($source, $environment))->application($args);
$application->routing();
+ $protocol= new HttpProtocol($application, $environment->logging());
+
+ $http= new ServerSocket($this->host, $this->port);
+ $this->server->listen($http, $protocol);
+
+ // TODO: Remove hardcoded port and certificates, fetch from command line arguments
+ $https= new class($this->host, 8443) extends ServerSocket {
+ public function listen($backlog= SOMAXCONN) {
+ $this->setSocketOption('ssl', 'allow_self_signed', true);
+ $this->setSocketOption('ssl', 'disable_compression', true);
+ $this->setSocketOption('ssl', 'verify_peer', false);
+ $this->setSocketOption('ssl', 'local_cert', 'localhost.crt');
+ $this->setSocketOption('ssl', 'local_pk', 'localhost.key');
+ parent::listen($backlog);
+ }
+ };
+ $this->server->listen($https, new SSL($protocol));
- $socket= new ServerSocket($this->host, $this->port);
- $this->server->listen($socket, new HttpProtocol($application, $environment->logging()));
$this->server->init();
- Console::writeLine("\e[33m@", nameof($this), '(HTTP @ ', $socket->toString(), ")\e[0m");
+ Console::writeLine("\e[33m@", nameof($this), '(HTTP @ ', $http->toString(), ")\e[0m");
Console::writeLine("\e[1mServing ", $application, $config, "\e[0m > ", $environment->logging()->target());
Console::writeLine("\e[36m", str_repeat('═', 72), "\e[0m");
...and wrapping the protocol in this class:
<?php namespace xp\web\srv;
use peer\server\ServerProtocol;
use peer\server\protocol\SocketAcceptHandler;
/**
* HTTPS transport
*
* @see https://github.com/FiloSottile/mkcert
* @see https://letsencrypt.org/docs/certificates-for-localhost/
*/
class SSL implements ServerProtocol, SocketAcceptHandler {
private $underlying;
public function __construct(ServerProtocol $underlying) {
$this->underlying= $underlying;
}
/**
* Initialize Protocol
*
* @return bool
*/
public function initialize() {
return $this->underlying->initialize();
}
/**
* Handle client connect
*
* @param peer.Socket $socket
* @return bool
*/
public function handleAccept($socket) {
return stream_socket_enable_crypto(
$socket->getHandle(),
true,
STREAM_CRYPTO_METHOD_TLS_SERVER
);
}
/**
* Handle client connect
*
* @param peer.Socket $socket
* @return void
*/
public function handleConnect($socket) {
$this->underlying->handleConnect($socket);
}
/**
* Handle client disconnect
*
* @param peer.Socket $socket
* @return void
*/
public function handleDisconnect($socket) {
$this->underlying->handleDisconnect($socket);
}
/**
* Handle client data
*
* @param peer.Socket $socket
* @return ?iterable
*/
public function handleData($socket) {
return $this->underlying->handleData($socket);
}
/**
* Handle I/O error
*
* @param peer.Socket $socket
* @param lang.XPException $e
* @return void
*/
public function handleError($socket, $e) {
$this->underlying->handleError($socket, $e);
}
}Both include hints as to where our sockets API in xp-framework/networking is not sufficient yet.
Limitations
This only works for standalone webservers - default, async, fork, prefork - and the ext/sockets version might not be trivial. For the development webserver, we would need to implement a proxy.