Releases: amphp/http-server
3.4.2
3.4.1
What's Changed
- Fixed #376, removing calls to deprecated methods in
league/uri
, dropping support forleague/[email protected]
- Fixed #367 and #370 where a pending request could cause the server to hang during shutdown. Pending request reads are now cancelled when shutting down the HTTP/1.1 driver.
Full Changelog: v3.4.0...v3.4.1
3.4.0
What's Changed
- Fix method property in logger context by @luzrain in #373
- Add
ExceptionHandler
interface and middleware by @trowski in #375 - Add
_
to host validation by @maximal in #372 - Fixed issue #371, suspending the connection or stream timeout until the request handler returns a response.
New Contributors
Full Changelog: v3.3.1...v3.4.0
3.3.1
3.3.0
What's Changed
RequestBody
now implementsStringable
so the entire request body can be buffered by simply casting the object to a string (note the request body length limits still apply).- Fixed the HTTP/2 initial window size being potentially larger than the client would accept.
- Fixed incrementing the HTTP/2 window size if the body size limit is very large.
ClientException
now extendsAmp\ByteStream\StreamException
to avoid violating theReadableStream
interface by throwing a non-StreamException
from a stream method.
New Contributors
- @cwhite92 made their first contribution in #353
- @foremtehan made their first contribution in #356
Full Changelog: v3.2.0...v3.3.0
3.2.0
- Allowed
league/[email protected]
andpsr/message@v2
- Added previous param to
HttpErrorException
constructor
Full Changelog: v3.1.0...v3.2.0
3.1.0
3.0.0
Stable release compatible with AMPHP v3 and fibers! 🎉
As with other libraries compatible with AMPHP v3, most cases of parameters or returns of Promise<ResolutionType>
have been replaced with ResolutionType
.
The RequestHandler
and Middleware
interfaces along with the Request
and Response
objects are largely unchanged with the exception of replacing Promise
objects with the resolution type.
- The return type of
RequestHandler::handleRequest()
andMiddleware::handleRequest()
has changed fromPromise<Response>
toResponse
. - Request and response bodies must be an instance of
ReadableStream
or a string (note the interface name change inamphp/byte-stream
).null
will no longer be cast to an empty body.
Creating an HTTP Server
Initializing a server has changed significantly.
The Options
object has been removed, replaced by constructor parameters on various components. PHP 8.0's named parameters allows only defining the parameters you wish to override without the need to define those you do not wish to change.
HttpServer
is now an interface. ServerObserver
has been removed and replaced with onStart()
and onStop()
methods on the HttpServer
interface. SocketHttpServer
is the provided default implementation of HttpServer
. The methods getLogger()
, getRequestHandler()
, and getErrorHandler()
are no longer part of HttpServer
to avoid the interface being used as a service-locator.
In addition to the constructor, SocketHttpServer
provides two convenience static constructors for common use-cases.
createForDirectAccess()
— Creates an instance appropriate for direct access by the publiccreateForBehindProxy()
— Creates an instance appropriate for use when behind a proxy service such as nginx'
Listening interfaces are provided to SocketHttpServer
using the expose()
method. The RequestHandler
and ErrorHandler
instances are not provided to the constructor, instead being provided to the SocketHttpServer::start()
method. As these objects are provided after constructing the HttpServer
instance, RequestHandlers
may now require an instance of HttpServer
in their constructors to attach start and stop handlers.
SocketServer
instances are then created by SocketHttpServer
using an instance of SocketServerFactory
passed to the constructor. This allows server bind contexts to be initialized based on the provided (or default) HttpDriverFactory
.
Below is the "Hello, World!" example from examples/hello-world.php as an example of initializing a SocketHttpServer
instance.
<?php
require dirname(__DIR__) . "/vendor/autoload.php";
use Amp\ByteStream;
use Amp\Http\HttpStatus;
use Amp\Http\Server\DefaultErrorHandler;
use Amp\Http\Server\Driver\SocketClientFactory;
use Amp\Http\Server\Request;
use Amp\Http\Server\RequestHandler;
use Amp\Http\Server\Response;
use Amp\Http\Server\SocketHttpServer;
use Amp\Log\ConsoleFormatter;
use Amp\Log\StreamHandler;
use Amp\Socket;
use Monolog\Logger;
use Monolog\Processor\PsrLogMessageProcessor;
use function Amp\trapSignal;
// Run this script, then visit http://localhost:1337/ or https://localhost:1338/ in your browser.
$cert = new Socket\Certificate(__DIR__ . '/../test/server.pem');
$context = (new Socket\BindContext)
->withTlsContext((new Socket\ServerTlsContext)
->withDefaultCertificate($cert));
$logHandler = new StreamHandler(ByteStream\getStdout());
$logHandler->pushProcessor(new PsrLogMessageProcessor());
$logHandler->setFormatter(new ConsoleFormatter());
$logger = new Logger('server');
$logger->pushHandler($logHandler);
$logger->useLoggingLoopDetection(false);
$server = new SocketHttpServer(
$logger,
new Socket\ResourceServerSocketFactory(),
new SocketClientFactory($logger),
);
$server->expose("0.0.0.0:1337");
$server->expose("[::]:1337");
$server->expose("0.0.0.0:1338", $context);
$server->expose("[::]:1338", $context);
$server->start(new class implements RequestHandler {
public function handleRequest(Request $request): Response
{
return new Response(
status: HttpStatus::OK,
headers: ["content-type" => "text/plain; charset=utf-8"],
body: "Hello, World!",
);
}
}, new DefaultErrorHandler());
// Await a termination signal to be received.
$signal = trapSignal([SIGHUP, SIGINT, SIGQUIT, SIGTERM]);
$logger->info(sprintf("Received signal %d, stopping HTTP server", $signal));
$server->stop();
New Middlewares
- Added
ConcurrencyLimitingMiddleware
to limit the number of requests which may be concurrently handled by the server. - Added
ForwardedMiddleware
and associatedForwarded
class andForwardedHeaderType
enum. This middleware parses eitherForwarded
orX-Forwarded-For
headers to determine the original client address when used behind a proxy supporting these headers. - Added
AllowedMethodsMiddleware
which limits the allowed HTTP verbs used by requests. This middleware is used automatically bySocketHttpServer
. The allowed methods can be specified through a constructor parameter, using null to disable the middleware.
HTTP Drivers
Generally consumers of this library need not worry about these changes unless they implemented their own HTTP driver or interacted with the Client
interface beyond grabbing client metadata.
Client
is a significantly thinner interface, consisting of only metadata about the client connection.-
HttpDriver
instances now handle responding to requests instead of theClient
object.
HttpDriver::setup()
has been replaced withHttpDriver::handleClient
. Rather than returning a Generator parser which is fed data read from the client, this method is instead expected to read/write data from the provided streams itself.HttpDriver::write()
has been removed, as writing to the client should be handled internally within the driver.
3.0.0 Beta 8
- Added two static constructors for
SocketHttpServer
createForDirectAccess()
— Creates an instance appropriate for direct access by the publiccreateForBehindProxy()
— Creates an instance appropriate for use when behind a proxy service such as nginx'
- The constructor of
SocketHttpServer
has changed to require an instance ofServerSocketFactory
andClientFactory
, as well as accepting an array of middleware and a list of allowed HTTP methods. UseSocketHttpServer::createForDirectAccess()
to create a server with similar defaults as the previous constructor. - Added
ForwardedMiddleware
and associatedForwarded
class andForwardedHeaderType
enum. This middleware parses eitherForwarded
orX-Forwarded-For
headers to determine the original client address when used behind a proxy supporting these headers. - Added
AllowedMethodsMiddleware
which limits the allowed HTTP verbs used by requests. This middleware is used automatically bySocketHttpServer
. The allowed methods can be specified through a constructor parameter, using null to disable the middleware. - Removed the
$allowedMethods
argument from the constructors ofHttpDriverFactory
,Http1Driver
, andHttp2Driver
since this functionality is now handled by the middleware above. - Added query-related methods to
Request
to get individual query keys in a manner similar to headers.