Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Http Server Laravel Package

amphp/http-server

Asynchronous, non-blocking HTTP server for PHP built on Amp. Create high-performance web apps and APIs with event-driven I/O, middleware, routing, and streaming request/response bodies. Includes HTTP/1.1 and HTTP/2 support and TLS integration.

View on GitHub
Deep Wiki
Context7
v2.1.10

What's Changed

Fixed "MadeYouReset" HTTP/2 DoS attack vector described by CVE-2025-8671 and https://kb.cert.org/vuls/id/767506.

Stream reset protection has been refactored to account for the number of reset streams within a sliding time window. Note that your application must expose HTTP/2 connections directly to be affected by this vulnerability. Servers behind a proxy using HTTP/1.x such as nginx are not affected.

Full Changelog: https://github.com/amphp/http-server/compare/v2.1.9...v2.1.10

v3.4.4

What's Changed

Fixed "MadeYouReset" HTTP/2 DoS attack vector described by CVE-2025-8671 and https://kb.cert.org/vuls/id/767506.

Stream reset protection has been refactored to account for the number of reset streams within a sliding time window. Note that your application must expose HTTP/2 connections directly to be affected by this vulnerability. Servers behind a proxy using HTTP/1.x such as nginx are not affected.

Full Changelog: https://github.com/amphp/http-server/compare/v3.4.3...v3.4.4

v2.1.9

What's Changed

  • Allowed league/uri@^7.1 in addition to ^6

Full Changelog: https://github.com/amphp/http-server/compare/v2.1.8...v2.1.9

v3.4.3

What's Changed

New Contributors

Full Changelog: https://github.com/amphp/http-server/compare/v3.4.2...v3.4.3

v3.4.2

What's Changed

New Contributors

Full Changelog: https://github.com/amphp/http-server/compare/v3.4.1...v3.4.2

v3.4.1

What's Changed

  • Fixed #376, removing calls to deprecated methods in league/uri, dropping support for league/uri@6.x
  • 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: https://github.com/amphp/http-server/compare/v3.4.0...v3.4.1

v3.4.0

What's Changed

New Contributors

Full Changelog: https://github.com/amphp/http-server/compare/v3.3.1...v3.4.0

v3.3.1

What's Changed

New Contributors

Full Changelog: https://github.com/amphp/http-server/compare/v3.3.0...v3.3.1

v3.3.0

What's Changed

  • RequestBody now implements Stringable 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 extends Amp\ByteStream\StreamException to avoid violating the ReadableStream interface by throwing a non-StreamException from a stream method.

New Contributors

Full Changelog: https://github.com/amphp/http-server/compare/v3.2.0...v3.3.0

v3.2.0
  • Allowed league/uri@v7.1 and psr/message@v2
  • Added previous param to HttpErrorException constructor

Full Changelog: https://github.com/amphp/http-server/compare/v3.1.0...v3.2.0

v3.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() 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. 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 public
  • createForBehindProxy() — 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 associated Forwarded class and ForwardedHeaderType enum. This middleware parses either Forwarded or X-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 by SocketHttpServer. 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 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.
v3.0.0-beta.8
  • Added two static constructors for SocketHttpServer
    • createForDirectAccess() — Creates an instance appropriate for direct access by the public
    • createForBehindProxy() — Creates an instance appropriate for use when behind a proxy service such as nginx'
  • The constructor of SocketHttpServer has changed to require an instance of ServerSocketFactory and ClientFactory, as well as accepting an array of middleware and a list of allowed HTTP methods. Use SocketHttpServer::createForDirectAccess() to create a server with similar defaults as the previous constructor.
  • Added ForwardedMiddleware and associated Forwarded class and ForwardedHeaderType enum. This middleware parses either Forwarded or X-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 by SocketHttpServer. The allowed methods can be specified through a constructor parameter, using null to disable the middleware.
  • Removed the $allowedMethods argument from the constructors of HttpDriverFactory, Http1Driver, and Http2Driver 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.
v3.0.0-beta.7
  • 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.
v2.1.8
  • Fixed the first chunk read from the response body being duplicated when the content-length header was not set on the response (#342)
v3.0.0-beta.6
  • 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.

v3.0.0-beta.4
  • Fixed issues with HTTP/1.0 keep-alive connections
  • Added missing dependencies in composer.json
v2.1.7
  • Fixed buffer timeout in CompressionMiddleware added in the last release not actually being set (#339)
v2.1.6
  • Fixed compression with streamed responses (https://github.com/amphp/http-server/issues/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.
v3.0.0-beta.3
  • 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.
v3.0.0-beta.2
  • 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.
v3.0.0-beta.1

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.
v2.1.5
  • 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.
v2.1.4
  • 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.
v2.1.3
  • Fixed abrupt client disconnections when the server is shutdown by invoking server observers before closing connected clients. This provides an opportunity for observers to send or receive data from clients before the connection is closed.
v2.1.2
  • Fixed loading src/Server.php with --classmap-authoritative
v2.1.1
  • Fixed typo in performance recommender.
v2.1.0
  • Added CallableMiddleware (#313)
  • Improved exception logging (#306)
  • Added setting to Options to pass the Request object to the logger context. The option defaults to off. (#310)
  • Fixed HTTP/2 streams closing if the response was sent before the request body was fully received. (#304)
  • Fixed HTTP/2 window size for too large request bodies, so they can be rejected instead of hanging
v2.0.1
  • Fixed HTTP/2 window size validation on 32 bit platforms
v2.0.0

This release provides compatibility with amphp/socket v1.0. Please see the amphp/socket release notes for more information on changes in that library. While most code using this library should not require major changes, some compatibility breaks with v1.x were made.

Summary of compatibility breaks from v1.x to v2.0

  • Updated to league/uri@^6. Consequentially, PHP 7.2+ is now required.
  • Renamed Server to HttpServer. An alias of Server to HttpServer was kept for backward compatibility with v1.x, but may be removed in a future version.
  • Added Push object for pushed resources. Response::getPush() now returns an array of Push objects.
  • Upgrade callbacks (those set with Response::upgrade()) now receive an instance of Amp\Socket\EncryptableSocket, an interface extending Amp\Socket\Socket, as the parameter to the callback function. Upgrade callback are now run as a coroutine if a generater is returned. Coroutine (or promise returned from the callback) failures are logged to the server log.
  • Driver\Client returns an instance of Amp\Socket\SocketAddress from getLocalAddress() and getRemoteAddress(). The methods getLocalPort() and getRemotePort() have been removed. The IP address and port are available on the instance of SocketAddress returned.
  • Driver\Client::getCryptoContext() has been replaced with getTlsInfo(), which now returns an instance of Amp\Socket\TlsInfo for encrypted clients or null for plaintext clients.
  • HTTP/2 protocol is now declared as "2" instead of "2.0" in requests and responses (see https://http2.github.io/faq/#is-it-http20-or-http2).
  • Refactored HTTP/2 flood prevention to be based on a ratio between payload and non-payload bytes received, inspired by NGINX's flood prevention. Some options were removed:
    • Removed Options::getMinimumAverageFrameSize() and withMinimumAverageFrameSize().
    • Removed Options::getFramesPerSecondLimit() and withFramesPerSecondLimit().
  • Removed Options::getConnectionTimeout() and withConnectionTimeout(). HTTP/1.x and HTTP/2 connection timeouts are now separate and can be set using the http1Timeout (default 15 seconds) and http2Timeout (default 60 seconds) options.

Trailers

The Trailers object has been refactored to contain a list of header declared trailer fields (which may be empty) and a promise for an Amp\Http\Message object containing the future trailer values. Trailers in requests have been moved from the request body to the Request object. Request::getTrailers() returns a Trailers object having two methods:

  • Trailers::getFields(): Returns an array of declared trailer fields (this list may be empty, but still receive trailers).
  • Trailers::await(): Returns a promise that is resolved with a Amp\Http\Message instance once all trailers have been received.

Trailers are now supported in responses. A new Response constructor parameter or Response::setTrailers(Trailers $trailers) may be used to set a Trailers object for the response. The promise provided to the Trailers constructor should be resolved with an array of header values indexed by the header field name, similar to header field array provided to the Response constructor or Response::setHeaders().

Other backward compatibility breaks unlikely to affect application code

  • Driver\Http1Driver and Driver\Http2Driver constructors now require an instance of Psr\Log\LoggerInterface as the final parameter.
  • Promise parameter for Trailers object removed from RequestBody constructor.
  • void returns added to start(), onClose(), and close() methods in Driver\Client interface.
  • void return added to TimeReference::onTimeUpdate().
  • HTTP/2 pseudo headers (header fields starting with a colon (:) such as :method or :status) cannot be used in Request and Response. Accordingly, these header fields are no longer included in requests generated by the server. The values of these headers are used to populate request properties and should be accessed by getters in Request.
  • Removed TimeReference and SystemTimeReference. Use Amp\Http\formatDateHeader() in the amphp/http@1.5 package to generate the value for an HTTP header value containing a date.
  • Refactored TimeoutCache and renamed some methods. Client timeouts are no longer updated within Client, rather HttpDriver implementations must update the client timeout. Users should be unaffected by this change unless they implemented their own Client or HttpDriver.
  • HttpDriverFactory::selectDriver() now requires instances of ErrorHandler, Psr\Log\LoggerInterface, and Options in addition to the Client instance.

New Features

  • The original casing of HTTP/1.x request headers is now available through Request::getRawHeaders().
  • Added Request::getAttributes() to retrieve an array of all request attributes and Request::removeAttribute() to remove an attribute.
  • Added Request::removeAttribute().
  • Added ClientException::getClient() that returns the Client that caused the error.
  • Back-pressure from consumption of request bodies is now used to control window sizes in HTTP/2. Window sizes are only increased in small increments instead of the entire allowable body size. This will improve memory consumption when handling large request bodies.
  • Added tlsSetupTimeout in Options. Default is 5 seconds.

Upgrading from v1.x

We believe only minor changes will be necessary for applications to upgrade from v1.x to v2.0. As trailers and upgrade responses are uncommon for applications, the most likely concern for upgraders is the shift to SocketAddress in Client::getLocalAddress() and Client::getRemoteAddress(), changes to methods in Options, as well as the changes made in amphp/socket v1.0.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport