PHPackages                             aternos/curl-psr - 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. aternos/curl-psr

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

aternos/curl-psr
================

A simple PSR-18 HTTP client based on cURL that supports actual streaming

v2.0.0(3mo ago)23.8k↓37.5%1MITPHPPHP &gt;=8.5CI passing

Since Nov 19Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/aternosorg/php-curl-psr)[ Packagist](https://packagist.org/packages/aternos/curl-psr)[ RSS](/packages/aternos-curl-psr/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (4)Versions (17)Used By (0)

aternos/curl-psr
================

[](#aternoscurl-psr)

A simple PSR-18 client implementation based on cURL that actually supports streaming both requests and responses.

Installation
------------

[](#installation)

```
composer require aternos/curl-psr
```

In addition to [PSR-18 (HTTP Client)](https://www.php-fig.org/psr/psr-18/), this library also provides implementations for [PSR-17 (HTTP Factories)](https://www.php-fig.org/psr/psr-17/) and [PSR-7 (HTTP Messages)](https://www.php-fig.org/psr/psr-7/), so no other implementations need to be installed.

Usage
-----

[](#usage)

### Creating a client

[](#creating-a-client)

```
$client = new \Aternos\CurlPsr\Psr18\Client();
```

When creating a client, you can optionally provide PSR-17 `ResponseFactoryInterface` and `UriFactoryInterface` instances. By default, the client will use the `Aternos\CurlPsr\Psr17\Psr17Factory` class included in this library.

Additionally, you can pass an optional `UriResolverInterface` instance, which is used to resolve redirect targets.

### Configuring the client

[](#configuring-the-client)

Since PSR-7 does not offer many request options, you can set client-wide options that are used for all requests. Requests will use the client options as they are at the moment they are sent. Changing client options will therefore not affect already running requests.

```
$client->setTimeout(10) // Set the timeout to 10 seconds
       ->setMaxRedirects(5) // Set the maximum number of redirects to follow to 5
       ->setCookieFile("/path/to/cookie/file") // Set the path to the cURL cookie file
       ->setCurlOption(CURLOPT_DNS_SHUFFLE_ADDRESSES, true) // Set a custom cURL option
       ->setDefaultHeaders(["User-Agent" => ["MyClient/1.0"]]) // Set default headers for all requests
       ->addDefaultHeader("Accept", "application/json"); // Add a default header

$client->setProgressCallback(function (
    \Psr\Http\Message\RequestInterface $request,
    int $downloadTotal,
    int $downloaded,
    int $uploadTotal,
    int $uploaded
) {
    // Progress callback
});
```

#### Custom cURL options

[](#custom-curl-options)

You can set custom cURL options using the `setCurlOption` method. Note that some options cannot be set, since they are used internally by the client.

#### Redirects

[](#redirects)

The client will follow redirects by default. You can set the maximum number of redirects to follow using the `setMaxRedirects` method. It is also possible to disable redirects using `setFollowRedirects`. The difference between setting the maximum number of redirects to 0 and disabling redirects is that the former will throw an exception if a redirect is received, while the latter will simply return the redirect response.

Only when status `303 See Other` is received, the client will automatically change the request method to `GET` and remove the request body. Historically, this behavior was also sometimes present for `301` and `302`, so it is possible to enable it for other status codes using the `setRedirectToGetStatusCodes` method.

Status `300 Multiple Choices` will only be treated as a redirect if the `Location` header is present. Otherwise, the response will be returned as is.

To manage how redirect targets are resolved, or limit what locations the client can be redirected to, you can pass an instance of `UriResolverInterface` to the client constructor.

When a redirect response is received that does not prompt the client to change the request method to `GET`and the body stream cannot be rewound, an exception is thrown. This is because the client cannot resend the request with the same body stream.

#### Progress callback

[](#progress-callback)

The progress callback function works the same way as the `CURLOPT_PROGRESSFUNCTION` in cURL, except that it receives the PSR-7 request object instead of a cURL handle as the first argument. Please note that the request object passed to the callback is not necessarily same instance that was originally passed to the `sendRequest` method. This is because PSR-7 request objects are immutable, so the client will create a new request object if changes are necessary (e.g. to add default headers).

### Sending a request

[](#sending-a-request)

```
$factory = new \Aternos\CurlPsr\Psr17\Psr17Factory();

$request = $factory->createRequest("GET", "https://example.com")
    ->withHeader("X-Some-Header", "Some Value");
    ->withBody($streamFactory->createStream("Some body"));

$response = $client->sendRequest($request);

$headers = $response->getHeaders();
$stream = $response->getBody();

echo $stream->getContents();
```

CurlPsr can send any PSR-7 request object and return a PSR-7 response object. For more information on how to use PSR-7 objects, see the [PSR-7 documentation](https://www.php-fig.org/psr/psr-7/).

###  Health Score

49

—

FairBetter than 95% of packages

Maintenance79

Regular maintenance activity

Popularity27

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 96.4% of commits — single point of failure

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 ~33 days

Recently: every ~22 days

Total

14

Last Release

111d ago

Major Versions

v1.3.5 → v2.0.02026-01-28

PHP version history (2 changes)v1.0.1PHP &gt;=8.3.0

v2.0.0PHP &gt;=8.5

### Community

Maintainers

![](https://www.gravatar.com/avatar/182e603c02f308d1036a1ecaba0b994665e87d13a86ff4550a96c9189a92c544?d=identicon)[aternos](/maintainers/aternos)

---

Top Contributors

[![KurtThiemann](https://avatars.githubusercontent.com/u/26512466?v=4)](https://github.com/KurtThiemann "KurtThiemann (27 commits)")[![JulianVennen](https://avatars.githubusercontent.com/u/45244473?v=4)](https://github.com/JulianVennen "JulianVennen (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/aternos-curl-psr/health.svg)

```
[![Health](https://phpackages.com/badges/aternos-curl-psr/health.svg)](https://phpackages.com/packages/aternos-curl-psr)
```

###  Alternatives

[laudis/neo4j-php-client

Neo4j-PHP-Client is the most advanced PHP Client for Neo4j

184616.9k31](/packages/laudis-neo4j-php-client)[shopify/shopify-api

Shopify API Library for PHP

4634.8M16](/packages/shopify-shopify-api)[spiral/roadrunner-http

RoadRunner: HTTP and PSR-7 worker

799.2M48](/packages/spiral-roadrunner-http)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28137.8k](/packages/phpro-http-tools)[mezzio/mezzio-authentication-oauth2

OAuth2 (server) authentication middleware for Mezzio and PSR-7 applications.

28483.0k2](/packages/mezzio-mezzio-authentication-oauth2)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

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