Skip to content

Commit

Permalink
Foundational refactor to allow for HTTP/3
Browse files Browse the repository at this point in the history
  • Loading branch information
bwoebi committed Jan 6, 2024
1 parent f15d804 commit abfbe86
Show file tree
Hide file tree
Showing 16 changed files with 196 additions and 27 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"amphp/hpack": "^3",
"amphp/http": "^2",
"amphp/pipeline": "^1",
"amphp/quic": "dev-master",
"amphp/socket": "^2.1",
"amphp/sync": "^2",
"league/uri": "^6.8 | ^7.1",
Expand Down
5 changes: 5 additions & 0 deletions src/Driver/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,9 @@ public function getLocalAddress(): SocketAddress;
* If the client is encrypted a TlsInfo object is returned, otherwise null.
*/
public function getTlsInfo(): ?TlsInfo;

/**
* @return bool Whether the client uses QUIC.
*/
public function isQuicClient(): bool;
}
3 changes: 2 additions & 1 deletion src/Driver/ClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Amp\Http\Server\Driver;

use Amp\Http\Client\SocketException;
use Amp\Quic\QuicConnection;
use Amp\Socket\Socket;

interface ClientFactory
Expand All @@ -12,5 +13,5 @@ interface ClientFactory
*
* @throws SocketException
*/
public function createClient(Socket $socket): ?Client;
public function createClient(Socket|QuicConnection $socket): ?Client;
}
3 changes: 2 additions & 1 deletion src/Driver/ConnectionLimitingClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Amp\Http\Server\Driver;

use Amp\Quic\QuicConnection;
use Amp\Socket\InternetAddress;
use Amp\Socket\InternetAddressVersion;
use Amp\Socket\Socket;
Expand All @@ -19,7 +20,7 @@ public function __construct(
) {
}

public function createClient(Socket $socket): ?Client
public function createClient(Socket|QuicConnection $socket): ?Client
{
$address = $socket->getRemoteAddress();

Expand Down
12 changes: 12 additions & 0 deletions src/Driver/DefaultHttpDriverFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ public function createHttpDriver(
ErrorHandler $errorHandler,
Client $client,
): HttpDriver {
if ($client->isQuicClient()) {
return new Http3Driver(
requestHandler: $requestHandler,
errorHandler: $errorHandler,
logger: $this->logger,
streamTimeout: $this->streamTimeout,
headerSizeLimit: $this->headerSizeLimit,
bodySizeLimit: $this->bodySizeLimit,
pushEnabled: $this->pushEnabled,
);
}

if ($client->getTlsInfo()?->getApplicationLayerProtocol() === "h2") {
return new Http2Driver(
requestHandler: $requestHandler,
Expand Down
4 changes: 2 additions & 2 deletions src/Driver/Http1Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
use Amp\Http\HttpStatus;
use Amp\Http\InvalidHeaderException;
use Amp\Http\Server\ClientException;
use Amp\Http\Server\Driver\Internal\AbstractHttpDriver;
use Amp\Http\Server\Driver\Internal\StreamHttpDriver;
use Amp\Http\Server\ErrorHandler;
use Amp\Http\Server\Request;
use Amp\Http\Server\RequestBody;
Expand All @@ -32,7 +32,7 @@
use function Amp\Http\formatDateHeader;
use function Amp\Http\mapHeaderPairs;

final class Http1Driver extends AbstractHttpDriver
final class Http1Driver extends StreamHttpDriver
{
private static function makeHeaderReduceClosure(string $search): \Closure
{
Expand Down
4 changes: 2 additions & 2 deletions src/Driver/Http2Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
use Amp\Http\HttpStatus;
use Amp\Http\InvalidHeaderException;
use Amp\Http\Server\ClientException;
use Amp\Http\Server\Driver\Internal\AbstractHttpDriver;
use Amp\Http\Server\Driver\Internal\Http2Stream;
use Amp\Http\Server\Driver\Internal\StreamHttpDriver;
use Amp\Http\Server\ErrorHandler;
use Amp\Http\Server\Push;
use Amp\Http\Server\Request;
Expand All @@ -35,7 +35,7 @@
use function Amp\async;
use function Amp\Http\formatDateHeader;

final class Http2Driver extends AbstractHttpDriver implements Http2Processor
final class Http2Driver extends StreamHttpDriver implements Http2Processor
{
public const DEFAULT_CONCURRENT_STREAM_LIMIT = 100;

Expand Down
60 changes: 60 additions & 0 deletions src/Driver/Http3Driver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php declare(strict_types=1);

namespace Amp\Http\Server\Driver;

use Amp\Http\Server\Driver\Internal\ConnectionHttpDriver;
use Amp\Http\Server\Driver\Internal\QPack;
use Amp\Http\Server\ErrorHandler;
use Amp\Http\Server\Request;
use Amp\Http\Server\RequestHandler;
use Amp\Http\Server\Response;
use Amp\Quic\QuicConnection;
use Amp\Socket\Socket;
use Psr\Log\LoggerInterface as PsrLogger;

class Http3Driver extends ConnectionHttpDriver
{
private bool $allowsPush;

public function __construct(
RequestHandler $requestHandler,
ErrorHandler $errorHandler,
PsrLogger $logger,
private readonly int $streamTimeout = Http2Driver::DEFAULT_STREAM_TIMEOUT,
private readonly int $headerSizeLimit = Http2Driver::DEFAULT_HEADER_SIZE_LIMIT,
private readonly int $bodySizeLimit = Http2Driver::DEFAULT_BODY_SIZE_LIMIT,
private readonly bool $pushEnabled = true,
private readonly ?string $settings = null,
) {
parent::__construct($requestHandler, $errorHandler, $logger);

$this->allowsPush = $pushEnabled;

$this->qpack = new QPack;
}

protected function write(Request $request, Response $response): void
{

}

public function getApplicationLayerProtocols(): array
{
return ["h3"]; // that's a property of the server itself...? "h3" is the default mandated by RFC 9114, but section 3.1 allows for custom mechanisms too, technically.
}

public function handleConnection(Client $client, QuicConnection|Socket $connection): void
{

}

public function getPendingRequestCount(): int
{
return 0;
}

public function stop(): void
{

}
}
12 changes: 11 additions & 1 deletion src/Driver/HttpDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use Amp\ByteStream\ReadableStream;
use Amp\ByteStream\WritableStream;
use Amp\Quic\QuicConnection;
use Amp\Socket\Socket;

interface HttpDriver
{
Expand All @@ -18,14 +20,22 @@ interface HttpDriver
public function getApplicationLayerProtocols(): array;

/**
* Set up the driver.
* Set up the driver in a socket independent way.
*/
public function handleClient(
Client $client,
ReadableStream $readableStream,
WritableStream $writableStream,
): void;

/**
* Set up the driver directly through a connection.
*/
public function handleConnection(
Client $client,
Socket|QuicConnection $connection
): void;

/**
* @return int Number of requests that are being read by the parser.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

namespace Amp\Http\Server\Driver\Internal;

use Amp\ByteStream\ReadableStream;
use Amp\ByteStream\WritableStream;
use Amp\Http\HttpStatus;
use Amp\Http\Server\ClientException;
use Amp\Http\Server\DefaultErrorHandler;
use Amp\Http\Server\Driver\Client;
use Amp\Http\Server\Driver\HttpDriver;
use Amp\Http\Server\ErrorHandler;
use Amp\Http\Server\HttpErrorException;
Expand All @@ -14,7 +17,7 @@
use Psr\Log\LoggerInterface;

/** @internal */
abstract class AbstractHttpDriver implements HttpDriver
abstract class ConnectionHttpDriver implements HttpDriver
{
private static ?TimeoutQueue $timeoutQueue = null;
private static ?ErrorHandler $defaultErrorHandler = null;
Expand Down Expand Up @@ -143,4 +146,12 @@ private function handleError(int $status, ?string $reason, Request $request): Re
return self::getDefaultErrorHandler()->handleError($status, null, $request);
}
}

public function handleClient(
Client $client,
ReadableStream $readableStream,
WritableStream $writableStream,
): void {
throw new \Error(get_class($this) . " cannot handle Clients in a stream independent way. Use handleConnection() instead.");
}
}
8 changes: 8 additions & 0 deletions src/Driver/Internal/QPack.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Amp\Http\Server\Driver\Internal;

class QPack
{

}
15 changes: 15 additions & 0 deletions src/Driver/Internal/StreamHttpDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Amp\Http\Server\Driver\Internal;

use Amp\Http\Server\Driver\Client;
use Amp\Quic\QuicConnection;
use Amp\Socket\Socket;

abstract class StreamHttpDriver extends ConnectionHttpDriver
{
public function handleConnection(Client $client, QuicConnection|Socket $connection): void
{
$this->handleClient($client, $connection, $connection);
}
}
3 changes: 2 additions & 1 deletion src/Driver/LoggingSocketClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Amp\Http\Server\Driver;

use Amp\Quic\QuicConnection;
use Amp\Socket\Socket;
use Psr\Log\LoggerInterface as PsrLogger;

Expand All @@ -13,7 +14,7 @@ public function __construct(
) {
}

public function createClient(Socket $socket): ?Client
public function createClient(Socket|QuicConnection $socket): ?Client
{
$local = $socket->getLocalAddress()->toString();
$remote = $socket->getRemoteAddress()->toString();
Expand Down
8 changes: 7 additions & 1 deletion src/Driver/SocketClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Amp\Http\Server\Driver;

use Amp\Quic\QuicConnection;
use Amp\Socket\Socket;
use Amp\Socket\SocketAddress;
use Amp\Socket\TlsInfo;
Expand All @@ -11,7 +12,7 @@ final class SocketClient implements Client
private readonly int $id;

public function __construct(
private readonly Socket $socket,
private readonly Socket|QuicConnection $socket,
) {
$this->id = createClientId();
}
Expand Down Expand Up @@ -50,4 +51,9 @@ public function isClosed(): bool
{
return $this->socket->isClosed();
}

public function isQuicClient(): bool
{
return $this->socket instanceof QuicConnection;
}
}
3 changes: 2 additions & 1 deletion src/Driver/SocketClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Amp\Http\Server\Driver;

use Amp\CancelledException;
use Amp\Quic\QuicConnection;
use Amp\Socket\Socket;
use Amp\Socket\SocketException;
use Amp\TimeoutCancellation;
Expand All @@ -16,7 +17,7 @@ public function __construct(
) {
}

public function createClient(Socket $socket): ?Client
public function createClient(Socket|QuicConnection $socket): ?Client
{
$local = $socket->getLocalAddress()->toString();
$remote = $socket->getRemoteAddress()->toString();
Expand Down
Loading

0 comments on commit abfbe86

Please sign in to comment.