PHPackages                             anonymhk/http - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. anonymhk/http

ActiveLibrary[HTTP &amp; Networking](/categories/http)

anonymhk/http
=============

Event-driven, streaming HTTP client and server implementation for ReactPHP

v1.9.3(2y ago)0191MITPHPPHP &gt;=5.3.0

Since Jul 11Pushed 2y ago1 watchersCompare

[ Source](https://github.com/AnonymHK/http)[ Packagist](https://packagist.org/packages/anonymhk/http)[ RSS](/packages/anonymhk-http/feed)WikiDiscussions 1.x Synced 1mo ago

READMEChangelog (1)Dependencies (15)Versions (40)Used By (1)

HTTP
====

[](#http)

[![CI status](https://github.com/reactphp/http/actions/workflows/ci.yml/badge.svg)](https://github.com/reactphp/http/actions)[![installs on Packagist](https://camo.githubusercontent.com/c392ef20c32841314052d5d90e4480def5d3d0ca43ab69be56357732e4961c85/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f72656163742f687474703f636f6c6f723d626c7565266c6162656c3d696e7374616c6c732532306f6e2532305061636b6167697374)](https://packagist.org/packages/react/http)

Event-driven, streaming HTTP client and server implementation for [ReactPHP](https://reactphp.org/).

This HTTP library provides re-usable implementations for an HTTP client and server based on ReactPHP's [`Socket`](https://github.com/reactphp/socket) and [`EventLoop`](https://github.com/reactphp/event-loop) components. Its client component allows you to send any number of async HTTP/HTTPS requests concurrently. Its server component allows you to build plaintext HTTP and secure HTTPS servers that accept incoming HTTP requests from HTTP clients (such as web browsers). This library provides async, streaming means for all of this, so you can handle multiple concurrent HTTP requests without blocking.

**Table of contents**

- [Quickstart example](#quickstart-example)
- [Client Usage](#client-usage)
    - [Request methods](#request-methods)
    - [Promises](#promises)
    - [Cancellation](#cancellation)
    - [Timeouts](#timeouts)
    - [Authentication](#authentication)
    - [Redirects](#redirects)
    - [Blocking](#blocking)
    - [Concurrency](#concurrency)
    - [Streaming response](#streaming-response)
    - [Streaming request](#streaming-request)
    - [HTTP proxy](#http-proxy)
    - [SOCKS proxy](#socks-proxy)
    - [SSH proxy](#ssh-proxy)
    - [Unix domain sockets](#unix-domain-sockets)
- [Server Usage](#server-usage)
    - [HttpServer](#httpserver)
    - [listen()](#listen)
    - [Server Request](#server-request)
        - [Request parameters](#request-parameters)
        - [Query parameters](#query-parameters)
        - [Request body](#request-body)
        - [Streaming incoming request](#streaming-incoming-request)
        - [Request method](#request-method)
        - [Cookie parameters](#cookie-parameters)
        - [Invalid request](#invalid-request)
    - [Server Response](#server-response)
        - [Deferred response](#deferred-response)
        - [Streaming outgoing response](#streaming-outgoing-response)
        - [Response length](#response-length)
        - [Invalid response](#invalid-response)
        - [Default response headers](#default-response-headers)
    - [Middleware](#middleware)
        - [Custom middleware](#custom-middleware)
        - [Third-Party Middleware](#third-party-middleware)
- [API](#api)
    - [Browser](#browser)
        - [get()](#get)
        - [post()](#post)
        - [head()](#head)
        - [patch()](#patch)
        - [put()](#put)
        - [delete()](#delete)
        - [request()](#request)
        - [requestStreaming()](#requeststreaming)
        - [withTimeout()](#withtimeout)
        - [withFollowRedirects()](#withfollowredirects)
        - [withRejectErrorResponse()](#withrejecterrorresponse)
        - [withBase()](#withbase)
        - [withProtocolVersion()](#withprotocolversion)
        - [withResponseBuffer()](#withresponsebuffer)
        - [withHeader()](#withheader)
        - [withoutHeader()](#withoutheader)
    - [React\\Http\\Message](#reacthttpmessage)
        - [Response](#response)
            - [html()](#html)
            - [json()](#json)
            - [plaintext()](#plaintext)
            - [xml()](#xml)
        - [Request](#request-1)
        - [ServerRequest](#serverrequest)
        - [ResponseException](#responseexception)
    - [React\\Http\\Middleware](#reacthttpmiddleware)
        - [StreamingRequestMiddleware](#streamingrequestmiddleware)
        - [LimitConcurrentRequestsMiddleware](#limitconcurrentrequestsmiddleware)
        - [RequestBodyBufferMiddleware](#requestbodybuffermiddleware)
        - [RequestBodyParserMiddleware](#requestbodyparsermiddleware)
- [Install](#install)
- [Tests](#tests)
- [License](#license)

Quickstart example
------------------

[](#quickstart-example)

Once [installed](#install), you can use the following code to access an HTTP web server and send some simple HTTP GET requests:

```

    Hello wörld!

XML;

$response = React\Http\Message\Response::xml($xml);
```

This is a convenient shortcut method that returns the equivalent of this:

```
$response = new React\Http\Message\Response(
    React\Http\Message\Response::STATUS_OK,
    [
        'Content-Type' => 'application/xml'
    ],
    $xml
);

```

This method always returns a response with a `200 OK` status code and the appropriate `Content-Type` response header for the given XML source string. It's generally recommended to use UTF-8 (Unicode) and specify this as part of the leading XML declaration and to end the given XML source string with a trailing newline.

If you want to use a different status code or custom HTTP response headers, you can manipulate the returned response object using the provided PSR-7 methods or directly instantiate a custom HTTP response object using the `Response` constructor:

```
$response = React\Http\Message\Response::xml(
    "Invalid user name given.\n"
)->withStatus(React\Http\Message\Response::STATUS_BAD_REQUEST);
```

#### Request

[](#request-1)

The `React\Http\Message\Request` class can be used to respresent an outgoing HTTP request message.

This class implements the [PSR-7 `RequestInterface`](https://www.php-fig.org/psr/psr-7/#32-psrhttpmessagerequestinterface)which extends the [PSR-7 `MessageInterface`](https://www.php-fig.org/psr/psr-7/#31-psrhttpmessagemessageinterface).

This is mostly used internally to represent each outgoing HTTP request message for the HTTP client implementation. Likewise, you can also use this class with other HTTP client implementations and for tests.

> Internally, this implementation builds on top of an existing outgoing request message and only adds support for streaming. This base class is considered an implementation detail that may change in the future.

#### ServerRequest

[](#serverrequest)

The `React\Http\Message\ServerRequest` class can be used to respresent an incoming server request message.

This class implements the [PSR-7 `ServerRequestInterface`](https://www.php-fig.org/psr/psr-7/#321-psrhttpmessageserverrequestinterface)which extends the [PSR-7 `RequestInterface`](https://www.php-fig.org/psr/psr-7/#32-psrhttpmessagerequestinterface)which in turn extends the [PSR-7 `MessageInterface`](https://www.php-fig.org/psr/psr-7/#31-psrhttpmessagemessageinterface).

This is mostly used internally to represent each incoming request message. Likewise, you can also use this class in test cases to test how your web application reacts to certain HTTP requests.

> Internally, this implementation builds on top of an existing outgoing request message and only adds required server methods. This base class is considered an implementation detail that may change in the future.

#### ResponseException

[](#responseexception)

The `React\Http\Message\ResponseException` is an `Exception` sub-class that will be used to reject a request promise if the remote server returns a non-success status code (anything but 2xx or 3xx). You can control this behavior via the [`withRejectErrorResponse()` method](#withrejecterrorresponse).

The `getCode(): int` method can be used to return the HTTP response status code.

The `getResponse(): ResponseInterface` method can be used to access its underlying response object.

### React\\Http\\Middleware

[](#reacthttpmiddleware)

#### StreamingRequestMiddleware

[](#streamingrequestmiddleware)

The `React\Http\Middleware\StreamingRequestMiddleware` can be used to process incoming requests with a streaming request body (without buffering).

This allows you to process requests of any size without buffering the request body in memory. Instead, it will represent the request body as a [`ReadableStreamInterface`](https://github.com/reactphp/stream#readablestreaminterface)that emit chunks of incoming data as it is received:

```
$http = new React\Http\HttpServer(
    new React\Http\Middleware\StreamingRequestMiddleware(),
    function (Psr\Http\Message\ServerRequestInterface $request) {
        $body = $request->getBody();
        assert($body instanceof Psr\Http\Message\StreamInterface);
        assert($body instanceof React\Stream\ReadableStreamInterface);

        return new React\Promise\Promise(function ($resolve) use ($body) {
            $bytes = 0;
            $body->on('data', function ($chunk) use (&$bytes) {
                $bytes += \count($chunk);
            });
            $body->on('close', function () use (&$bytes, $resolve) {
                $resolve(new React\Http\Message\Response(
                    React\Http\Message\Response::STATUS_OK,
                    [],
                    "Received $bytes bytes\n"
                ));
            });
        });
    }
);
```

See also [streaming incoming request](#streaming-incoming-request)for more details.

Additionally, this middleware can be used in combination with the [`LimitConcurrentRequestsMiddleware`](#limitconcurrentrequestsmiddleware) and [`RequestBodyBufferMiddleware`](#requestbodybuffermiddleware) (see below) to explicitly configure the total number of requests that can be handled at once:

```
$http = new React\Http\HttpServer(
    new React\Http\Middleware\StreamingRequestMiddleware(),
    new React\Http\Middleware\LimitConcurrentRequestsMiddleware(100), // 100 concurrent buffering handlers
    new React\Http\Middleware\RequestBodyBufferMiddleware(2 * 1024 * 1024), // 2 MiB per request
    new React\Http\Middleware\RequestBodyParserMiddleware(),
    $handler
);
```

> Internally, this class is used as a "marker" to not trigger the default request buffering behavior in the `HttpServer`. It does not implement any logic on its own.

#### LimitConcurrentRequestsMiddleware

[](#limitconcurrentrequestsmiddleware)

The `React\Http\Middleware\LimitConcurrentRequestsMiddleware` can be used to limit how many next handlers can be executed concurrently.

If this middleware is invoked, it will check if the number of pending handlers is below the allowed limit and then simply invoke the next handler and it will return whatever the next handler returns (or throws).

If the number of pending handlers exceeds the allowed limit, the request will be queued (and its streaming body will be paused) and it will return a pending promise. Once a pending handler returns (or throws), it will pick the oldest request from this queue and invokes the next handler (and its streaming body will be resumed).

The following example shows how this middleware can be used to ensure no more than 10 handlers will be invoked at once:

```
$http = new React\Http\HttpServer(
    new React\Http\Middleware\LimitConcurrentRequestsMiddleware(10),
    $handler
);
```

Similarly, this middleware is often used in combination with the [`RequestBodyBufferMiddleware`](#requestbodybuffermiddleware) (see below) to limit the total number of requests that can be buffered at once:

```
$http = new React\Http\HttpServer(
    new React\Http\Middleware\StreamingRequestMiddleware(),
    new React\Http\Middleware\LimitConcurrentRequestsMiddleware(100), // 100 concurrent buffering handlers
    new React\Http\Middleware\RequestBodyBufferMiddleware(2 * 1024 * 1024), // 2 MiB per request
    new React\Http\Middleware\RequestBodyParserMiddleware(),
    $handler
);
```

More sophisticated examples include limiting the total number of requests that can be buffered at once and then ensure the actual request handler only processes one request after another without any concurrency:

```
$http = new React\Http\HttpServer(
    new React\Http\Middleware\StreamingRequestMiddleware(),
    new React\Http\Middleware\LimitConcurrentRequestsMiddleware(100), // 100 concurrent buffering handlers
    new React\Http\Middleware\RequestBodyBufferMiddleware(2 * 1024 * 1024), // 2 MiB per request
    new React\Http\Middleware\RequestBodyParserMiddleware(),
    new React\Http\Middleware\LimitConcurrentRequestsMiddleware(1), // only execute 1 handler (no concurrency)
    $handler
);
```

#### RequestBodyBufferMiddleware

[](#requestbodybuffermiddleware)

One of the built-in middleware is the `React\Http\Middleware\RequestBodyBufferMiddleware` which can be used to buffer the whole incoming request body in memory. This can be useful if full PSR-7 compatibility is needed for the request handler and the default streaming request body handling is not needed. The constructor accepts one optional argument, the maximum request body size. When one isn't provided it will use `post_max_size` (default 8 MiB) from PHP's configuration. (Note that the value from your matching SAPI will be used, which is the CLI configuration in most cases.)

Any incoming request that has a request body that exceeds this limit will be accepted, but its request body will be discarded (empty request body). This is done in order to avoid having to keep an incoming request with an excessive size (for example, think of a 2 GB file upload) in memory. This allows the next middleware handler to still handle this request, but it will see an empty request body. This is similar to PHP's default behavior, where the body will not be parsed if this limit is exceeded. However, unlike PHP's default behavior, the raw request body is not available via `php://input`.

The `RequestBodyBufferMiddleware` will buffer requests with bodies of known size (i.e. with `Content-Length` header specified) as well as requests with bodies of unknown size (i.e. with `Transfer-Encoding: chunked` header).

All requests will be buffered in memory until the request body end has been reached and then call the next middleware handler with the complete, buffered request. Similarly, this will immediately invoke the next middleware handler for requests that have an empty request body (such as a simple `GET` request) and requests that are already buffered (such as due to another middleware).

Note that the given buffer size limit is applied to each request individually. This means that if you allow a 2 MiB limit and then receive 1000 concurrent requests, up to 2000 MiB may be allocated for these buffers alone. As such, it's highly recommended to use this along with the [`LimitConcurrentRequestsMiddleware`](#limitconcurrentrequestsmiddleware) (see above) to limit the total number of concurrent requests.

Usage:

```
$http = new React\Http\HttpServer(
    new React\Http\Middleware\StreamingRequestMiddleware(),
    new React\Http\Middleware\LimitConcurrentRequestsMiddleware(100), // 100 concurrent buffering handlers
    new React\Http\Middleware\RequestBodyBufferMiddleware(16 * 1024 * 1024), // 16 MiB
    function (Psr\Http\Message\ServerRequestInterface $request) {
        // The body from $request->getBody() is now fully available without the need to stream it
        return new React\Http\Message\Response(React\Http\Message\Response::STATUS_OK);
    },
);
```

#### RequestBodyParserMiddleware

[](#requestbodyparsermiddleware)

The `React\Http\Middleware\RequestBodyParserMiddleware` takes a fully buffered request body (generally from [`RequestBodyBufferMiddleware`](#requestbodybuffermiddleware)), and parses the form values and file uploads from the incoming HTTP request body.

This middleware handler takes care of applying values from HTTP requests that use `Content-Type: application/x-www-form-urlencoded` or `Content-Type: multipart/form-data` to resemble PHP's default superglobals `$_POST` and `$_FILES`. Instead of relying on these superglobals, you can use the `$request->getParsedBody()` and `$request->getUploadedFiles()` methods as defined by PSR-7.

Accordingly, each file upload will be represented as instance implementing the [PSR-7 `UploadedFileInterface`](https://www.php-fig.org/psr/psr-7/#36-psrhttpmessageuploadedfileinterface). Due to its blocking nature, the `moveTo()` method is not available and throws a `RuntimeException` instead. You can use `$contents = (string)$file->getStream();` to access the file contents and persist this to your favorite data store.

```
$handler = function (Psr\Http\Message\ServerRequestInterface $request) {
    // If any, parsed form fields are now available from $request->getParsedBody()
    $body = $request->getParsedBody();
    $name = isset($body['name']) ? $body['name'] : 'unnamed';

    $files = $request->getUploadedFiles();
    $avatar = isset($files['avatar']) ? $files['avatar'] : null;
    if ($avatar instanceof Psr\Http\Message\UploadedFileInterface) {
        if ($avatar->getError() === UPLOAD_ERR_OK) {
            $uploaded = $avatar->getSize() . ' bytes';
        } elseif ($avatar->getError() === UPLOAD_ERR_INI_SIZE) {
            $uploaded = 'file too large';
        } else {
            $uploaded = 'with error';
        }
    } else {
        $uploaded = 'nothing';
    }

    return new React\Http\Message\Response(
        React\Http\Message\Response::STATUS_OK,
        array(
            'Content-Type' => 'text/plain'
        ),
        $name . ' uploaded ' . $uploaded
    );
};

$http = new React\Http\HttpServer(
    new React\Http\Middleware\StreamingRequestMiddleware(),
    new React\Http\Middleware\LimitConcurrentRequestsMiddleware(100), // 100 concurrent buffering handlers
    new React\Http\Middleware\RequestBodyBufferMiddleware(16 * 1024 * 1024), // 16 MiB
    new React\Http\Middleware\RequestBodyParserMiddleware(),
    $handler
);
```

See also [form upload server example](examples/62-server-form-upload.php) for more details.

By default, this middleware respects the [`upload_max_filesize`](https://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize)(default `2M`) ini setting. Files that exceed this limit will be rejected with an `UPLOAD_ERR_INI_SIZE` error. You can control the maximum filesize for each individual file upload by explicitly passing the maximum filesize in bytes as the first parameter to the constructor like this:

```
new React\Http\Middleware\RequestBodyParserMiddleware(8 * 1024 * 1024); // 8 MiB limit per file
```

By default, this middleware respects the [`file_uploads`](https://www.php.net/manual/en/ini.core.php#ini.file-uploads)(default `1`) and [`max_file_uploads`](https://www.php.net/manual/en/ini.core.php#ini.max-file-uploads)(default `20`) ini settings. These settings control if any and how many files can be uploaded in a single request. If you upload more files in a single request, additional files will be ignored and the `getUploadedFiles()` method returns a truncated array. Note that upload fields left blank on submission do not count towards this limit. You can control the maximum number of file uploads per request by explicitly passing the second parameter to the constructor like this:

```
new React\Http\Middleware\RequestBodyParserMiddleware(10 * 1024, 100); // 100 files with 10 KiB each
```

> Note that this middleware handler simply parses everything that is already buffered in the request body. It is imperative that the request body is buffered by a prior middleware handler as given in the example above. This previous middleware handler is also responsible for rejecting incoming requests that exceed allowed message sizes (such as big file uploads). The [`RequestBodyBufferMiddleware`](#requestbodybuffermiddleware) used above simply discards excessive request bodies, resulting in an empty body. If you use this middleware without buffering first, it will try to parse an empty (streaming) body and may thus assume an empty data structure. See also [`RequestBodyBufferMiddleware`](#requestbodybuffermiddleware) for more details.

> PHP's `MAX_FILE_SIZE` hidden field is respected by this middleware. Files that exceed this limit will be rejected with an `UPLOAD_ERR_FORM_SIZE` error.

> This middleware respects the [`max_input_vars`](https://www.php.net/manual/en/info.configuration.php#ini.max-input-vars)(default `1000`) and [`max_input_nesting_level`](https://www.php.net/manual/en/info.configuration.php#ini.max-input-nesting-level)(default `64`) ini settings.

> Note that this middleware ignores the [`enable_post_data_reading`](https://www.php.net/manual/en/ini.core.php#ini.enable-post-data-reading)(default `1`) ini setting because it makes little sense to respect here and is left up to higher-level implementations. If you want to respect this setting, you have to check its value and effectively avoid using this middleware entirely.

Install
-------

[](#install)

The recommended way to install this library is [through Composer](https://getcomposer.org/). [New to Composer?](https://getcomposer.org/doc/00-intro.md)

This project follows [SemVer](https://semver.org/). This will install the latest supported version:

```
composer require react/http:^1.9
```

See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.

This project aims to run on any platform and thus does not require any PHP extensions and supports running on legacy PHP 5.3 through current PHP 8+ and HHVM. It's *highly recommended to use the latest supported PHP version* for this project.

Tests
-----

[](#tests)

To run the test suite, you first need to clone this repo and then install all dependencies [through Composer](https://getcomposer.org/):

```
composer install
```

To run the test suite, go to the project root and run:

```
vendor/bin/phpunit
```

The test suite also contains a number of functional integration tests that rely on a stable internet connection. If you do not want to run these, they can simply be skipped like this:

```
vendor/bin/phpunit --exclude-group internet
```

License
-------

[](#license)

MIT, see [LICENSE file](LICENSE).

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community22

Small or concentrated contributor base

Maturity70

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~105 days

Total

40

Last Release

959d ago

Major Versions

v0.8.7 → v1.0.02020-07-11

PHP version history (4 changes)v0.1.0PHP &gt;=5.3.2

v0.2.0PHP &gt;=5.3.3

v0.4.0PHP &gt;=5.4.0

v0.4.3PHP &gt;=5.3.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/9d1325d6264b247c1cc9aa38aac2de4dc4f5cecb2bddfc7bdabafa46abc0e209?d=identicon)[AnonymHK](/maintainers/AnonymHK)

---

Top Contributors

[![clue](https://avatars.githubusercontent.com/u/776829?v=4)](https://github.com/clue "clue (307 commits)")[![WyriHaximus](https://avatars.githubusercontent.com/u/147145?v=4)](https://github.com/WyriHaximus "WyriHaximus (205 commits)")[![jsor](https://avatars.githubusercontent.com/u/55574?v=4)](https://github.com/jsor "jsor (57 commits)")[![legionth](https://avatars.githubusercontent.com/u/1578709?v=4)](https://github.com/legionth "legionth (43 commits)")[![igorw](https://avatars.githubusercontent.com/u/88061?v=4)](https://github.com/igorw "igorw (40 commits)")[![cboden](https://avatars.githubusercontent.com/u/617694?v=4)](https://github.com/cboden "cboden (30 commits)")[![arnaud-lb](https://avatars.githubusercontent.com/u/365207?v=4)](https://github.com/arnaud-lb "arnaud-lb (23 commits)")[![SimonFrings](https://avatars.githubusercontent.com/u/44357440?v=4)](https://github.com/SimonFrings "SimonFrings (16 commits)")[![andig](https://avatars.githubusercontent.com/u/184815?v=4)](https://github.com/andig "andig (8 commits)")[![onigoetz](https://avatars.githubusercontent.com/u/309594?v=4)](https://github.com/onigoetz "onigoetz (6 commits)")[![seregazhuk](https://avatars.githubusercontent.com/u/9959761?v=4)](https://github.com/seregazhuk "seregazhuk (5 commits)")[![carusogabriel](https://avatars.githubusercontent.com/u/16328050?v=4)](https://github.com/carusogabriel "carusogabriel (4 commits)")[![kalessil](https://avatars.githubusercontent.com/u/1577185?v=4)](https://github.com/kalessil "kalessil (4 commits)")[![AnonymHK](https://avatars.githubusercontent.com/u/110597435?v=4)](https://github.com/AnonymHK "AnonymHK (4 commits)")[![slava-vishnyakov](https://avatars.githubusercontent.com/u/817931?v=4)](https://github.com/slava-vishnyakov "slava-vishnyakov (3 commits)")[![nopolabs](https://avatars.githubusercontent.com/u/815864?v=4)](https://github.com/nopolabs "nopolabs (3 commits)")[![aaronbonneau](https://avatars.githubusercontent.com/u/8574061?v=4)](https://github.com/aaronbonneau "aaronbonneau (2 commits)")[![ebimmel-ysp](https://avatars.githubusercontent.com/u/55812632?v=4)](https://github.com/ebimmel-ysp "ebimmel-ysp (2 commits)")[![iannsp](https://avatars.githubusercontent.com/u/40551?v=4)](https://github.com/iannsp "iannsp (2 commits)")[![pavog](https://avatars.githubusercontent.com/u/4786628?v=4)](https://github.com/pavog "pavog (2 commits)")

---

Tags

httppsr-7httpsasyncclienthttp clientreactphpserverstreamingevent-drivenhttp server

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/anonymhk-http/health.svg)

```
[![Health](https://phpackages.com/badges/anonymhk-http/health.svg)](https://phpackages.com/packages/anonymhk-http)
```

###  Alternatives

[react/http

Event-driven, streaming HTTP client and server implementation for ReactPHP

78126.4M414](/packages/react-http)[league/uri-interfaces

Common tools for parsing and resolving RFC3987/RFC3986 URI

538204.9M23](/packages/league-uri-interfaces)[swow/swow

Coroutine-based multi-platform support engine with a focus on concurrent I/O

1.3k2.1M84](/packages/swow-swow)[clue/docker-react

Async, event-driven access to the Docker Engine API, built on top of ReactPHP.

113154.9k1](/packages/clue-docker-react)[amphp/http-client-psr7

PSR-7 adapter for Amp's HTTP client.

1454.7k4](/packages/amphp-http-client-psr7)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28137.8k](/packages/phpro-http-tools)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
