Cleanup middleware logic
* Http2Connection now sets up the streams and returns a responseStream
This commit is contained in:
@ -22,16 +22,20 @@ class Http2Middleware
|
||||
/** @var SplObjectStorage<Http2Connection> Active connections */
|
||||
private SplObjectStorage $connections;
|
||||
|
||||
public function __construct()
|
||||
private array $handlers;
|
||||
|
||||
public function __construct(callable ...$httpHandlers)
|
||||
{
|
||||
$this->handlers = $httpHandlers;
|
||||
$this->connections = new SplObjectStorage();
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequestInterface $request, ?callable $next=null)
|
||||
{
|
||||
// expect upgrade h2 for secure connections, h2c for plaintext
|
||||
|
||||
$requestSecure = $request->getHeaderLine("x-forwarded-proto") ?: "http";
|
||||
|
||||
// Parse out headers
|
||||
$requestUpgrade = $request->getHeaderLine("upgrade");
|
||||
$connectionFlags = array_map(
|
||||
fn($v) => strtolower(trim($v)),
|
||||
@ -45,28 +49,19 @@ class Http2Middleware
|
||||
return Response::plaintext("Unsupported protocol")->withStatus(Response::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
// handle HTTP/2 upgrade from HTTP/1.1
|
||||
$http2SettingsData = $request->getHeaderLine("http2-settings");
|
||||
if ($http2SettingsData) {
|
||||
$http2Settings = $this->parseSettingsFromBase64String($http2SettingsData);
|
||||
} else {
|
||||
// TODO handle HTTP/2 with prior knowledge
|
||||
return Response::plaintext("Expected HTTP2-Settings header")->withStatus(Response::STATUS_BAD_REQUEST);
|
||||
try {
|
||||
$connection = $this->setupConnection($request);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
return Response::plaintext("Error upgrading connection")->withStatus(Response::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$responseInputStream = new ThroughStream();
|
||||
$responseOutputStream = new ThroughStream();
|
||||
$responseStream = new CompositeStream($responseOutputStream, $responseInputStream);
|
||||
$serverStream = new CompositeStream($responseInputStream, $responseOutputStream);
|
||||
|
||||
$connection = new Http2Connection($serverStream, $request, $http2Settings??null);
|
||||
|
||||
$headers = [
|
||||
'Connection' => 'Upgrade',
|
||||
'Upgrade' => $requestUpgrade
|
||||
];
|
||||
|
||||
return (new Response(Response::STATUS_SWITCHING_PROTOCOLS, $headers, $responseStream));
|
||||
return (new Response(Response::STATUS_SWITCHING_PROTOCOLS, $headers, $connection->getResponseStream()));
|
||||
|
||||
}
|
||||
|
||||
@ -93,8 +88,19 @@ class Http2Middleware
|
||||
*/
|
||||
private function setupConnection(ServerRequestInterface $request): Http2Connection
|
||||
{
|
||||
$stream = new ThroughStream();
|
||||
$connection = new Http2Connection($stream);
|
||||
// handle HTTP/2 upgrade from HTTP/1.1
|
||||
$hasSettingsHeader = str_contains("http2-settings", strtolower($request->getHeaderLine("connection")));
|
||||
|
||||
$http2Settings = null;
|
||||
if ($hasSettingsHeader) {
|
||||
$http2SettingsData = $request->getHeaderLine("http2-settings");
|
||||
if (!$http2SettingsData) {
|
||||
throw new \RuntimeException("Expected HTTP2-Settings header");
|
||||
}
|
||||
$http2Settings = $this->parseSettingsFromBase64String($http2SettingsData);
|
||||
}
|
||||
|
||||
$connection = new Http2Connection($request, $http2Settings??null);
|
||||
|
||||
$this->connections->attach($connection);
|
||||
$connection->on('close', function () use ($connection) {
|
||||
|
Reference in New Issue
Block a user