Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
7ee1317
[WIP] Version 4.0
kodeart Jan 25, 2022
60cabab
- added github actions
kodeart Dec 25, 2022
716c49a
Major upgrade (work in progress)
kodeart Mar 14, 2023
5cfcf08
- updates CI actions
kodeart Nov 1, 2023
64f423a
- fixes the method declaration
kodeart Nov 1, 2023
7204e6b
- updates for v4.0
kodeart Nov 2, 2023
17d56f0
- re-added tests
kodeart Nov 2, 2023
c6aa559
- upgrades to psr/http-message v2
kodeart Nov 2, 2023
e64c329
- updates methods for pst/http-message v2
kodeart Nov 2, 2023
2af4ee6
- chore: cleanup
kodeart Nov 2, 2023
ff5ca57
- updates methods for pst/http-message v2
kodeart Nov 2, 2023
4038625
- updates
kodeart Nov 2, 2023
185da62
- fix: package name typo
kodeart Feb 22, 2024
c1fd987
- fix: reverted isXHR() method; keep it simple
kodeart Mar 1, 2024
253abec
- fix: reverted isXHR() method (updated unit tests)
kodeart Mar 13, 2024
d6ef02b
- fix: use provided $input, or create from POST if empty
kodeart Mar 13, 2024
e9281ad
- fix: use provided $input, or create from POST if empty
kodeart Mar 13, 2024
a7af2dc
- year bump
kodeart Mar 13, 2024
d346e9e
- added PHP 8.3
kodeart Mar 13, 2024
d8a3141
- updated test for seek()
kodeart Mar 13, 2024
acc6692
- chore: message update
kodeart Mar 13, 2024
689fb14
- tests updates
kodeart Mar 13, 2024
3d2c6b4
- fix: reverted isXHR() method (updated unit tests)
kodeart Mar 13, 2024
3aa9483
chore: changed syntax
kodeart Mar 16, 2024
5a99900
- fix: as PSR method signature
kodeart Mar 16, 2024
c2dcb72
- WEBDAV_METHODS uses enums now
kodeart Mar 16, 2024
34f42c1
- chore: prepare for returnTransfer() method
kodeart Mar 16, 2024
d206cf1
- updates: added support for PUT and PATCH request (body) handling
kodeart Mar 16, 2024
ddddf56
- [wip]: prepare for extensibility
kodeart Mar 17, 2024
3c6b0d8
- a lot of everything
kodeart Jun 23, 2025
daf93d9
- update: another dumb integration test to ignore
kodeart Jun 23, 2025
94ffc3b
- fix: cleanup
kodeart Jun 23, 2025
56b0971
- update: more dumb integration tests to ignore
kodeart Jun 23, 2025
357e1f6
feat(HTTPError): added \Stringable implementation
kodeart Aug 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
*.php diff=php

/build export-ignore
/Tests export-ignore
/vendor export-ignore
/diagrams export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/.env export-ignore
/phpunit.xml.dist export-ignore
/composer.lock export-ignore
/*.yml export-ignore
build/ export-ignore
tests/ export-ignore
vendor/ export-ignore
diagrams/ export-ignore
.git* export-ignore
.env export-ignore
*dist export-ignore
*.yml export-ignore
52 changes: 52 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: CI

on:
pull_request:
push:
branches:
- master

env:
timezone: UTC
REQUIRED_PHP_EXTENSIONS: 'curl fileinfo libxml mbstring zip'

concurrency:
cancel-in-progress: true
group: ${{ github.workflow }}-${{ github.ref }}

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php-version:
- '8.1'
- '8.2'
- '8.3'
- '8.4'

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PHP ${{ matrix.php-version }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
tools: composer:v2
ini_values: opcache.enable=0
coverage: pcov

- name: Install composer and update
uses: ramsey/composer-install@v2
with:
composer-options: '--prefer-dist --no-progress --no-interaction'
dependency-versions: highest

- name: Run unit test suite
run: vendor/bin/phpunit --exclude integration --verbose --coverage-text

- name: Run integration tests
if: success() || failure()
run: vendor/bin/phpunit --group integration --verbose
8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
build
vendor
build/
vendor/
.idea/
.vscode/
.fleet/
.DS_Store
.idea
.tmp
composer.lock
*.cache
4 changes: 2 additions & 2 deletions .scrutinizer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ build:
- php-scrutinizer-run
environment:
php:
version: '8.0.1'
version: '8.1.2'

before_commands:
- 'composer update -o --prefer-source --no-interaction'

filter:
excluded_paths:
- 'Tests/*'
- 'tests/*'
- 'vendor/*'
- 'diagrams/*'
- 'build/*'
Expand Down
10 changes: 5 additions & 5 deletions AcceptHeaderNegotiator.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
use Koded\Http\Interfaces\HttpStatus;
use function array_shift;
use function explode;
use function join;
use function implode;
use function parse_str;
use function preg_match;
use function preg_replace;
Expand Down Expand Up @@ -91,7 +91,7 @@ private function parse(string $header): Generator

abstract class AcceptHeader
{
private string $header = '';
protected string $header = '';
private string $separator = '/';
private string $type = '';
private string $subtype = '*';
Expand Down Expand Up @@ -131,7 +131,7 @@ public function __construct(string $header)
*/
$this->subtype = trim(explode('+', $subtype)[1] ?? $subtype);
$this->catchAll = ('*' === $this->type) && ('*' === $this->subtype);
parse_str(join('&', $bits), $this->params);
parse_str(implode('&', $bits), $this->params);
$this->quality = (float)($this->params['q'] ?? 1);
unset($this->params['q']);
}
Expand Down Expand Up @@ -180,13 +180,13 @@ public function is(string $type): bool
*
* @internal
*/
public function matches(AcceptHeader $accept, array &$matches = null): void
public function matches(AcceptHeader $accept, ?array &$matches = null): void
{
$matches = (array)$matches;
$accept = clone $accept;
$typeMatch = ($this->type === $accept->type);
if (1.0 === $accept->quality) {
$accept->quality = (float)$this->quality;
$accept->quality = $this->quality;
}
if ($accept->catchAll) {
$accept->type = $this->type;
Expand Down
51 changes: 33 additions & 18 deletions Client/ClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,61 +11,76 @@

namespace Koded\Http\Client;

use Koded\Http\Interfaces\{HttpRequestClient, Request};
use Koded\Http\Interfaces\{ClientType, HttpMethod, HttpRequestClient};
use InvalidArgumentException;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

class ClientFactory
{
const CURL = 0;
const PHP = 1;
private ClientType $clientType;

private int $clientType = self::CURL;

public function __construct(int $clientType = ClientFactory::CURL)
public function __construct(ClientType $type = ClientType::CURL)
{
$this->clientType = $clientType;
$this->clientType = $type;
}

public function get($uri, array $headers = []): HttpRequestClient
{
return $this->new(Request::GET, $uri, null, $headers);
return $this->new(HttpMethod::GET, $uri, null, $headers);
}

public function post($uri, $body, array $headers = []): HttpRequestClient
{
return $this->new(Request::POST, $uri, $body, $headers);
return $this->new(HttpMethod::POST, $uri, $body, $headers);
}

public function put($uri, $body, array $headers = []): HttpRequestClient
{
return $this->new(Request::PUT, $uri, $body, $headers);
return $this->new(HttpMethod::PUT, $uri, $body, $headers);
}

public function patch($uri, $body, array $headers = []): HttpRequestClient
{
return $this->new(Request::PATCH, $uri, $body, $headers);
return $this->new(HttpMethod::PATCH, $uri, $body, $headers);
}

public function delete($uri, array $headers = []): HttpRequestClient
{
return $this->new(Request::DELETE, $uri, null, $headers);
return $this->new(HttpMethod::DELETE, $uri, null, $headers);
}

public function head($uri, array $headers = []): HttpRequestClient
{
return $this->new(Request::HEAD, $uri, null, $headers)->maxRedirects(0);
return $this->new(HttpMethod::HEAD, $uri, null, $headers)->maxRedirects(0);
}

public function client(): HttpRequestClient
{
return $this->new('HEAD', '');
return $this->new(HttpMethod::HEAD, '');
}

protected function new(string $method, $uri, $body = null, array $headers = []): HttpRequestClient
// FIXME: implement this?
// public function sendRequest(RequestInterface $request): ResponseInterface
// {
// return $this->new(
// HttpMethod::tryFrom($request->getMethod()),
// $request->getUri(),
// $request->getBody()->getContents(),
// $request->getHeaders()
// )->read();
// }

protected function new(
HttpMethod $method,
$uri,
$body = null,
array $headers = []): HttpRequestClient
{
return match ($this->clientType) {
self::CURL => new CurlClient($method, $uri, $body, $headers),
self::PHP => new PhpClient($method, $uri, $body, $headers),
default => throw new \InvalidArgumentException("{$this->clientType} is not a valid HTTP client"),
ClientType::CURL => new CurlClient($method, $uri, $body, $headers),
ClientType::PHP => new PhpClient($method, $uri, $body, $headers),
default => throw new InvalidArgumentException("{$this->clientType} is not a valid HTTP client"),
};
}
}
Loading
Loading