cloud-castle / http-client
PSR-18 HTTP-клиент для PHP 8.1+: cURL-транспорт, защита от SSRF, настройка таймаутов и опций запроса, обмен PSR-7 сообщениями. Реализует psr/http-client.
Requires
- php: >=8.1
- cloud-castle/http-request: ^1.0
- cloud-castle/http-response: ^1.0
- psr/http-client: ^1.0
- psr/http-factory: ^1.1
- psr/http-message: ^2.0
Requires (Dev)
- deptrac/deptrac: ^3.0 || ^4.0
- ergebnis/composer-normalize: ^2.45
- friendsofphp/php-cs-fixer: ^3.75
- icanhazstring/composer-unused: ^0.9
- infection/infection: ^0.29 || ^0.33
- php-parallel-lint/php-parallel-lint: ^1.4
- phpmd/phpmd: ^2.15
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^1.12 || ^2.1
- phpstan/phpstan-deprecation-rules: ^1.2 || ^2.0
- phpstan/phpstan-phpunit: ^1.4 || ^2.0
- phpstan/phpstan-strict-rules: ^1.6 || ^2.0
- phpunit/phpunit: ^10.5 || ^11.5
- psalm/plugin-phpunit: ^0.19 || ^0.20
- rector/rector: ^1.2 || ^2.0
- roave/security-advisories: dev-latest
- squizlabs/php_codesniffer: ^3.12 || ^4.0
- vimeo/psalm: ^6.0
- webmozart/assert: ^1.11
Provides
This package is auto-updated.
Last update: 2026-07-31 15:31:47 UTC
README
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano
CloudCastle Http Client
PSR-18 HTTP-клиент, устойчивый к SSRF: расширяемый конвейер middleware (повторы, безопасные перенаправления, авторизация, обработка ошибочных статусов), защита от обращений во внутреннюю сеть на каждом хопе, allow-list схем, таймауты и лимит размера ответа. Транспорт на cURL с подменяемой реализацией. Работает с любым PSR-7 запросом.
Установка
composer require cloud-castle/http-client
Требуется PHP 8.1+ и расширение ext-curl (для транспорта по умолчанию).
Фабрики PSR-7/17 берутся из cloud-castle/http-request и
cloud-castle/http-response (устанавливаются автоматически).
Быстрый старт
<?php
use CloudCastle\Http\Client\Client;
use CloudCastle\Http\Client\ClientOptions;
use CloudCastle\Http\Client\Middleware\AuthMiddleware;
use CloudCastle\Http\Client\Middleware\HttpErrorMiddleware;
use CloudCastle\Http\Client\Middleware\RetryMiddleware;
use CloudCastle\Http\Request\RequestFactory;
// Клиент по умолчанию: cURL, защита от SSRF, безопасные перенаправления.
$client = Client::create();
$request = (new RequestFactory())->createRequest('GET', 'https://api.example.com/users');
$response = $client->sendRequest($request);
echo $response->getStatusCode(); // 200
echo $response->getHeaderLine('Content-Type'); // application/json
// Конвейер middleware: повторы, авторизация, исключения на 4xx/5xx.
$client = Client::create(
new ClientOptions(timeout: 10, maxRedirects: 5),
new RetryMiddleware(maxRetries: 3),
AuthMiddleware::bearer('token'),
new HttpErrorMiddleware(),
);
Возможности
- PSR-18
ClientInterface—sendRequest, совместимый с любым PSR-7 стеком. - Конвейер middleware (
Contract\Middleware,MiddlewareStack) — типобезопасный аналог handler stack, каждое звено оборачивает ядро выполнения. - Повторы (
RetryMiddleware) — сетевые сбои и статусы 429/5xx с экспоненциальным backoff; функция задержки инъектируется. - Безопасные перенаправления (
RedirectMiddleware) — цепочка 3xx проходит повторную проверку SSRF на каждом хопе, при смене хоста снимаютсяAuthorization/Cookie, метод меняется по правилам 301/302/303 vs 307/308, относительныйLocationразрешается по RFC 3986. - Авторизация (
AuthMiddleware) — Basic (RFC 7617) и Bearer (RFC 6750). - Ошибочные статусы (
HttpErrorMiddleware) — 4xx/5xx вHttpExceptionс доступом к запросу и ответу. - Заголовки по умолчанию (
HeadersMiddleware) — общийUser-Agent/Acceptбез перезаписи явно заданных. - Базовый URI (
BaseUriMiddleware) — относительные пути запросов дополняются схемой и хостом по RFC 3986. - Cookie (
Cookie\CookieJar,CookieMiddleware) — управление cookies между запросами по RFC 6265: разборSet-Cookie, применимость по домену/пути/схеме, автоматические заголовки сессии. - Защита от SSRF (
SsrfGuard) — приватные/зарезервированные адреса и запрещённые схемы (file://,gopher://…) отклоняются; список схем настраивается. - Ограничения выполнения (
ClientOptions): таймаут запроса и соединения, размер ответа, перенаправления, проверка TLS-сертификата, версия протокола (HTTP/1.1, HTTP/2), декомпрессия ответа — с валидацией. - Подменяемый транспорт (
Contract\Transport): cURL по умолчанию,MockTransport— для тестов кода, использующего клиент. - Строгая классификация ошибок PSR-18:
NetworkExceptionInterface,RequestExceptionInterface,ClientExceptionInterface.
Middleware
Своё звено — это класс с одним методом либо замыкание через CallableMiddleware:
use CloudCastle\Http\Client\Middleware\CallableMiddleware;
$logging = new CallableMiddleware(function ($request, $options, $next) {
$started = hrtime(true);
$response = $next($request, $options);
// ... журналирование по ID запроса, без ПД и секретов ...
return $response;
});
$client = Client::create(null, $logging);
Первое звено — внешнее (получает управление первым, отдаёт последним).
Безопасность
- SSRF на каждом хопе. cURL-следование за редиректами отключено; за цепочкой
3xx следит
RedirectMiddleware, и каждый новый адрес заново проходитSsrfGuard. Это закрывает классический обход защиты редиректом наhttp://169.254.169.254илиhttp://localhost. - Утечка учётных данных. При смене хоста снимаются
AuthorizationиCookie. - Опасные схемы. По умолчанию допустимы только
http/https. - Fail-safe. Защита включена по умолчанию; ослабление (
allowPrivateNetwork: true, расширение списка схем) — осознанное решение для доверенных сценариев.
Уязвимости просим сообщать приватно — см. SECURITY.md.
Сравнение с аналогами
Возможности «из коробки», без доустановки пакетов и ручной сборки middleware.
| Возможность | http-client | Guzzle | Symfony HttpClient | Buzz | php-http/curl-client | WpOrg/Requests | 🏆 |
|---|---|---|---|---|---|---|---|
PSR-18 ClientInterface | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | — |
| Конвейер middleware | ✅ | ✅ | ⚠️ | ✅ | ❌ | ⚠️ | — |
| Повторы с backoff | ✅ | ⚠️ | ✅ | ❌ | ❌ | ❌ | — |
| SSRF-проверка на каждом редиректе | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | http-client |
| SSRF-защита из коробки | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | http-client |
| Allow-list схем | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | http-client |
| Снятие учётных данных при смене хоста | ✅ | ⚠️ | ⚠️ | ❌ | ❌ | ❌ | http-client |
| Лимит размера ответа | ✅ | ⚠️ | ⚠️ | ❌ | ❌ | ❌ | http-client |
| Авторизация Basic/Bearer | ✅ | ✅ | ✅ | ⚠️ | ❌ | ✅ | — |
| Исключения на 4xx/5xx | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | — |
| Управление cookies (RFC 6265) | ✅ | ✅ | ⚠️ | ❌ | ❌ | ✅ | — |
| Выбор версии HTTP (1.1/2) | ✅ | ✅ | ✅ | ❌ | ⚠️ | ⚠️ | — |
| Декомпрессия ответа | ✅ | ✅ | ✅ | ❌ | ⚠️ | ✅ | — |
| Runtime-зависимостей (минимум) | 2 | 3+ | 4+ | 1 | 2+ | 0 | Requests |
| Безопасность | http-client | Guzzle | Symfony | Buzz | curl-client | Requests | 🏆 |
|---|---|---|---|---|---|---|---|
| Фильтр приватных сетей | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | http-client |
| Защита от SSRF через редирект | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | http-client |
| Allow-list схем | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | http-client |
| Fail-safe по умолчанию | ✅ | ⚠️ | ⚠️ | ⚠️ | ⚠️ | ⚠️ | http-client |
| Ограничение размера ответа | ✅ | ⚠️ | ⚠️ | ❌ | ❌ | ❌ | http-client |
| Качество кода | http-client | Guzzle | Symfony | Buzz | curl-client | 🏆 |
|---|---|---|---|---|---|---|
| PHPStan max + strict | ✅ | ⚠️ | ⚠️ | ⚠️ | ⚠️ | http-client |
| Psalm errorLevel 1 | ✅ | ⚠️ | ❌ | ❌ | ⚠️ | http-client |
| Покрытие строк | 100% | ~80% | ~90% | ~85% | ~75% | http-client |
| Infection MSI | 100% | ⚠️ | ⚠️ | ❌ | ❌ | http-client |
Таблицы отражают поведение по умолчанию; конкуренты закрывают часть пунктов доустановкой middleware/декораторов — это честно отмечено значком ⚠️.
Плюсы и минусы
Плюсы
- Безопасность серверных исходящих запросов на уровне, которого нет у аналогов из коробки: SSRF-фильтр, проверка на каждом редиректе, allow-list схем, снятие учётных данных при смене хоста, лимит размера ответа.
- Расширяемость через типобезопасный конвейер middleware; повторы, авторизация, обработка ошибок — готовыми звеньями.
- Строгое качество: PHPStan max, Psalm errorLevel 1, покрытие 100%, MSI 100%.
- Минимум зависимостей — только экосистема cloud-castle и PSR.
Минусы
- Пакет моложе и менее распространён, чем Guzzle и Symfony HttpClient (меньше звёзд и установок, короче история).
- Для HTTP/2-мультиплексинга, промис-пулов и параллельных запросов пока берите Guzzle или Symfony HttpClient — эти сценарии здесь не покрыты (в развитии).
Рекомендации по применению
- Обработка недоверенных URL (webhook-адреса, загрузка по ссылке от пользователя, превью ссылок, SSRF-чувствительные интеграции) — основной сценарий: защита включена по умолчанию и действует на каждом редиректе.
- Финтех и обработка ПД — предсказуемый fail-safe клиент со строгой классификацией ошибок и без тяжёлого стека.
- Микросервисные интеграции — повторы и авторизация готовыми звеньями.
- Когда лучше другой инструмент — массовые параллельные выгрузки с HTTP/2 и промис-пулами: Guzzle или Symfony HttpClient.
Разработка
composer install
composer check # линтеры + статический анализ + тесты
composer fix # автоисправления (Rector, PHP CS Fixer, PHPCBF)
composer ci # полный CI-пайплайн локально
Полный список команд: composer run-script --list.
Документация
- Репозиторий: https://gitverse.ru/cloud-castle/http-client
- История изменений: CHANGELOG.md
- Как внести вклад: CONTRIBUTING.md
- Кодекс поведения: CODE_OF_CONDUCT.md
- Политика безопасности: SECURITY.md
Лицензия
MIT © CloudCastle (alex-4-17@yandex.ru)
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano