Skip to content

Releases: amphp/http-server

3.0.0 Beta 7

25 Feb 15:29
v3.0.0-beta.7
a2f94d0
Compare
Choose a tag to compare
3.0.0 Beta 7 Pre-release
Pre-release
  • Updated for compatibility with 2.0 of amphp/socket.
  • A string is now allowed on SocketHttpServer::expose() in addition to a SocketAddress instance.
  • Fixed Response::onDispose() being invoked as soon as the client connection or stream is closed. Prior it was not invoked until another chunk was read from the response body.

3.0.0 Beta 6

08 Jan 18:27
v3.0.0-beta.6
bff9b18
Compare
Choose a tag to compare
3.0.0 Beta 6 Pre-release
Pre-release
  • Fixed compatibility with v2.0 of amphp/byte-stream by updating ReadableStream implementations to also implement Traversable.

Note: 3.0.0 Beta 5 was skipped due to the tag missing a commit to update UpgradedSocket to be iterable.

3.0.0 Beta 4

12 Nov 17:32
v3.0.0-beta.4
fe25dc0
Compare
Choose a tag to compare
3.0.0 Beta 4 Pre-release
Pre-release
  • Fixed issues with HTTP/1.0 keep-alive connections
  • Added missing dependencies in composer.json

2.1.7

16 Aug 21:10
v2.1.7
850f1b2
Compare
Choose a tag to compare
  • Fixed buffer timeout in CompressionMiddleware added in the last release not actually being set (#339)

3.0.0 Beta 3

10 Aug 21:39
v3.0.0-beta.3
6906c78
Compare
Choose a tag to compare
3.0.0 Beta 3 Pre-release
Pre-release
  • Remove the streamThreshold parameter from DefaultHttpDriverFactory, Http1Driver, and Http2Driver constructors. Data read from body streams is now immediately pushed to the client. Use a custom stream implementation for the body if buffering is desired.
  • Fixed HTTP/2 upgrade requests. (#333)
  • Fixed compression with streamed responses (#324) - Compression is now unconditionally enabled if the first body chunk does not arrive within 100ms (configurable via a constructor parameter).
  • Added option to disable HTTP/2 in DefaultHttpDriverFactory constructor.

2.1.6

10 Aug 21:52
v2.1.6
fef588a
Compare
Choose a tag to compare
  • Fixed compression with streamed responses (#324) - Compression is now unconditionally enabled if the first body chunk does not arrive within 100ms (configurable via a constructor parameter)
  • Fixed a null ref if a Http2Driver::shutdown() was called while there were pending streams
  • Fixed Link headers being overwritten by HTTP/1.x driver.

3.0.0 Beta 2

08 Apr 21:42
v3.0.0-beta.2
60f1653
Compare
Choose a tag to compare
3.0.0 Beta 2 Pre-release
Pre-release
  • Removed getLogger(), getRequestHandler(), and getErrorHandler() from HttpServer to avoid the interface being used as a service-locator.
  • The instance of ErrorHandler is now required for SocketHttpServer::start() instead of being optional.

3.0.0 Beta 1

04 Apr 18:11
v3.0.0-beta.1
59c39d2
Compare
Choose a tag to compare
3.0.0 Beta 1 Pre-release
Pre-release

Initial release compatible with AMPHP v3.

As with other libraries compatible with AMPHP v3, most cases of parameters or returns of Promise<ResolutionType> have been replaced with ResolutionType.

Request Handler Stack

Happily, 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() and Middleware::handleRequest() has changed from Promise<Response> to Response.
  • Request and response bodies must be an instance of ReadableStream or a string (note the interface name change in amphp/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.

Listening interfaces are provided to SocketHttpServer using the expose(). 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\Server\Request;
use Amp\Http\Server\RequestHandler\ClosureRequestHandler;
use Amp\Http\Server\Response;
use Amp\Http\Server\SocketHttpServer;
use Amp\Http\Status;
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);

$server = new SocketHttpServer($logger);

$server->expose(new Socket\InternetAddress("0.0.0.0", 1337));
$server->expose(new Socket\InternetAddress("[::]", 1337));
$server->expose(new Socket\InternetAddress("0.0.0.0", 1338), $context);
$server->expose(new Socket\InternetAddress("[::]", 1338), $context);

$server->start(new ClosureRequestHandler(static function (Request $request): Response {
    return new Response(Status::OK, [
            "content-type" => "text/plain; charset=utf-8",
    ], "Hello, World!");
}));

// Await SIGINT or SIGTERM to be received.
$signal = trapSignal([\SIGINT, \SIGTERM]);

$logger->info(sprintf("Received signal %d, stopping HTTP server", $signal));

$server->stop();

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 the Client object.
  • HttpDriver::setup() has been replaced with HttpDriver::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.

2.1.5

14 Dec 23:30
7045694
Compare
Choose a tag to compare
  • Fixed an issue when using an event-loop extension (e.g., ext-ev or ext-uv) where large request bodies would fail to be read if the data was buffered internally by PHP, in which case the client readable callback would not be invoked again by the event-loop extension.

2.1.4

23 Aug 14:22
681b358
Compare
Choose a tag to compare
  • Raised the error level of log messages related to denying clients to warning instead of debug and removed the need for assertions to be enabled for these messages to be logged. This will prevent these messages from being hidden in a production environment.