Added tests for Http2Middleware

* Added unit tests for middleware
* Message handling code
This commit is contained in:
2024-07-27 13:23:18 +02:00
parent d41cfb1be2
commit dc3225538f
4 changed files with 152 additions and 6 deletions

View File

@ -3,8 +3,15 @@
namespace NoccyLabs\React\Http2;
use NoccyLabs\React\Http2\Connection\Http2Connection;
use NoccyLabs\React\Http2\Frame\DataFrame;
use NoccyLabs\React\Http2\Frame\Frame;
use NoccyLabs\React\Http2\Frame\HeadersFrame;
use NoccyLabs\React\Http2\Frame\SettingsFrame;
use NoccyLabs\React\Http2\Header\HeaderPacker;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use React\Http\Message\Response;
use React\Stream\CompositeStream;
use React\Stream\DuplexResourceStream;
use React\Stream\DuplexStreamInterface;
use React\Stream\ThroughStream;
@ -24,11 +31,46 @@ class Http2Middleware
{
// expect upgrade h2 for secure connections, h2c for plaintext
// TODO handle HTTP/2 upgrade from HTTP/1.1
// TODO handle HTTP/2 with prior knowledge
$requestSecure = $request->getHeaderLine("x-forwarded-proto") ?: "http";
$requestUpgrade = $request->getHeaderLine("upgrade");
$connectionFlags = array_map(
fn($v) => strtolower(trim($v)),
explode(",", $request->getHeaderLine("connection"))
);
// Pass everything we aren't interested in on to the next handler
if (!in_array('upgrade', $connectionFlags) || !in_array($requestUpgrade, ['h2', 'h2c'])) {
if (is_callable($next))
return $next($request);
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);
}
$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));
}
/**
* Parse the settings frame present in the HTTP/1.1 upgrade request.
*
@ -61,4 +103,4 @@ class Http2Middleware
return $connection;
}
}
}