Skip to content

Commit 5ed212d

Browse files
committed
New history option: Options::$history to define max size of history
New property `History::$size` to define the retention of history New `Berlioz\Http\Client\Discovery\BerliozDiscovery` discovery class for `php-http/discovery` package New class `HarFactory` to manage HAR files Remove `psr/log-implementation` composer entry Deprecate `Session::createFromHar()`, use `HarFactory::createSession()` instead Deprecate `Session::createFromHarFile()`, use `HarFactory::createSessionFromFile()` instead Deprecate `Session::getHar()`, use `HarFactory::createHarFromSession()` instead Deprecate `Session::writeHar()`, use `HarFactory::writeHarFromSession()` instead
1 parent 2d9377a commit 5ed212d

File tree

13 files changed

+451
-191
lines changed

13 files changed

+451
-191
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file. This projec
44
to [Semantic Versioning] (http://semver.org/). For change log format,
55
use [Keep a Changelog] (http://keepachangelog.com/).
66

7+
## [2.4.0] - 2025-05-12
8+
9+
### Added
10+
11+
- New history option: `Options::$history` to define max size of history
12+
- New property `History::$size` to define the retention of history
13+
- `Berlioz\Http\Client\Discovery\BerliozDiscovery` discovery class for `php-http/discovery` package
14+
- New class `HarFactory` to manage HAR files
15+
16+
### Removed
17+
18+
- `psr/log-implementation` composer entry
19+
20+
### Deprecated
21+
22+
- `Session::createFromHar()`, use `HarFactory::createSession()` instead
23+
- `Session::createFromHarFile()`, use `HarFactory::createSessionFromFile()` instead
24+
- `Session::getHar()`, use `HarFactory::createHarFromSession()` instead
25+
- `Session::writeHar()`, use `HarFactory::writeHarFromSession()` instead
26+
727
## [2.3.0] - 2025-03-14
828

929
### Changed

composer.json

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,50 @@
11
{
2-
"name": "berlioz/http-client",
3-
"description": "Berlioz HTTP Client is a PHP library to request HTTP server with continuous navigation, including cookies, sessions...",
4-
"minimum-stability": "beta",
5-
"prefer-stable": true,
6-
"license": "MIT",
7-
"homepage": "https://getberlioz.com",
8-
"authors": [
9-
{
10-
"name": "Ronan Giron",
11-
"email": "ronan@getberlioz.com"
2+
"name": "berlioz/http-client",
3+
"description": "Berlioz HTTP Client is a PHP library to request HTTP server with continuous navigation, including cookies, sessions...",
4+
"minimum-stability": "stable",
5+
"license": "MIT",
6+
"homepage": "https://getberlioz.com",
7+
"authors": [
8+
{
9+
"name": "Ronan Giron",
10+
"email": "ronan@getberlioz.com"
11+
}
12+
],
13+
"autoload": {
14+
"psr-4": {
15+
"Berlioz\\Http\\Client\\": "src/"
16+
}
17+
},
18+
"autoload-dev": {
19+
"psr-4": {
20+
"Berlioz\\Http\\Client\\Tests\\": "tests/"
21+
}
22+
},
23+
"require": {
24+
"php": "^8.0",
25+
"ext-mbstring": "*",
26+
"ext-zlib": "*",
27+
"berlioz/http-message": "^2.1",
28+
"elgigi/har-parser": "^1.0",
29+
"psr/http-client": "^1.0",
30+
"psr/log": "^1.0 || ^2.0 || ^3.0"
31+
},
32+
"require-dev": {
33+
"phpunit/phpunit": "^9.5",
34+
"symfony/process": "^5.0",
35+
"php-http/discovery": "^1.20"
36+
},
37+
"suggest": {
38+
"ext-curl": "To use CURL adapter",
39+
"berlioz/html-selector": "To query HTML result like jQuery in JavaScript."
40+
},
41+
"provide": {
42+
"psr/http-client-implementation": "1.0",
43+
"php-http/client-implementation": "1.0"
44+
},
45+
"config": {
46+
"allow-plugins": {
47+
"php-http/discovery": false
48+
}
1249
}
13-
],
14-
"autoload": {
15-
"psr-4": {
16-
"Berlioz\\Http\\Client\\": "src/"
17-
}
18-
},
19-
"autoload-dev": {
20-
"psr-4": {
21-
"Berlioz\\Http\\Client\\Tests\\": "tests/"
22-
}
23-
},
24-
"require": {
25-
"php": "^8.0",
26-
"ext-mbstring": "*",
27-
"ext-zlib": "*",
28-
"berlioz/http-message": "^2.1",
29-
"elgigi/har-parser": "^1.0",
30-
"psr/http-client": "^1.0",
31-
"psr/log": "^1.0 || ^2.0 || ^3.0"
32-
},
33-
"require-dev": {
34-
"phpunit/phpunit": "^9.5",
35-
"symfony/process": "^5.0"
36-
},
37-
"suggest": {
38-
"ext-curl": "To use CURL adapter",
39-
"berlioz/html-selector": "To query HTML result like jQuery in JavaScript."
40-
},
41-
"provide": {
42-
"psr/http-client-implementation": "^1.0",
43-
"psr/log-implementation": "^1.0"
44-
}
4550
}

src/Client.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public function __construct(Options|array|null $options = null, AdapterInterface
6767
$this->options = Options::make($options);
6868
$this->defaultHeaders = &$this->options->headers;
6969
$this->adapters = $adapter ?: [extension_loaded('curl') ? new CurlAdapter() : new StreamAdapter()];
70-
$this->session = new Session();
70+
$this->session = new Session(historySize: $this->options->history);
7171
}
7272

7373
/**

src/Discovery/BerliozDiscovery.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
/*
3+
* This file is part of Berlioz framework.
4+
*
5+
* @license https://opensource.org/licenses/MIT MIT License
6+
* @copyright 2025 Ronan GIRON
7+
* @author Ronan GIRON <https://github.com/ElGigi>
8+
*
9+
* For the full copyright and license information, please view the LICENSE
10+
* file that was distributed with this source code, to the root.
11+
*/
12+
13+
declare(strict_types=1);
14+
15+
namespace Berlioz\Http\Client\Discovery;
16+
17+
use Http\Discovery\ClassDiscovery;
18+
19+
class BerliozDiscovery
20+
{
21+
public static function register(): void
22+
{
23+
ClassDiscovery::prependStrategy(BerliozHttpClientStrategy::class);
24+
}
25+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
/*
3+
* This file is part of Berlioz framework.
4+
*
5+
* @license https://opensource.org/licenses/MIT MIT License
6+
* @copyright 2025 Ronan GIRON
7+
* @author Ronan GIRON <https://github.com/ElGigi>
8+
*
9+
* For the full copyright and license information, please view the LICENSE
10+
* file that was distributed with this source code, to the root.
11+
*/
12+
13+
declare(strict_types=1);
14+
15+
namespace Berlioz\Http\Client\Discovery;
16+
17+
use Berlioz\Http\Client\Client;
18+
use Http\Discovery\Strategy\DiscoveryStrategy;
19+
use Psr\Http\Client\ClientInterface;
20+
21+
class BerliozHttpClientStrategy implements DiscoveryStrategy
22+
{
23+
/**
24+
* @inheritDoc
25+
*/
26+
public static function getCandidates($type): array
27+
{
28+
if ($type === ClientInterface::class) {
29+
return [
30+
[
31+
'class' => Client::class,
32+
'condition' => [Client::class],
33+
],
34+
];
35+
}
36+
37+
return [];
38+
}
39+
}

src/Har/HarFactory.php

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
/*
3+
* This file is part of Berlioz framework.
4+
*
5+
* @license https://opensource.org/licenses/MIT MIT License
6+
* @copyright 2025 Ronan GIRON
7+
* @author Ronan GIRON <https://github.com/ElGigi>
8+
*
9+
* For the full copyright and license information, please view the LICENSE
10+
* file that was distributed with this source code, to the root.
11+
*/
12+
13+
namespace Berlioz\Http\Client\Har;
14+
15+
use Berlioz\Http\Client\Exception\HttpClientException;
16+
use Berlioz\Http\Client\Session;
17+
use ElGigi\HarParser\Entities\Log;
18+
use ElGigi\HarParser\Exception\InvalidArgumentException;
19+
use ElGigi\HarParser\Parser;
20+
21+
class HarFactory
22+
{
23+
/**
24+
* Create HAR Log class from session.
25+
*
26+
* @param Session $session
27+
*
28+
* @return Log
29+
* @throws HttpClientException
30+
*/
31+
public static function createHarFromSession(Session $session): Log
32+
{
33+
$generator = new HarGenerator();
34+
$generator->handle($session);
35+
36+
return $generator->getHar();
37+
}
38+
39+
/**
40+
* Write HAR file.
41+
*
42+
* @param Session $session
43+
* @param resource $dst
44+
*
45+
* @return void
46+
* @throws HttpClientException
47+
*/
48+
public static function writeHarFromSession(Session $session, $dst): void
49+
{
50+
$generator = new HarGenerator();
51+
$generator->handle($session);
52+
$generator->writeHar($dst);
53+
}
54+
55+
/**
56+
* Create session from HAR Log class.
57+
*
58+
* @param Log $har
59+
*
60+
* @return Session
61+
* @throws HttpClientException
62+
*/
63+
public static function createSession(Log $har): Session
64+
{
65+
$harParser = new HarHandler();
66+
67+
return $harParser->handle($har);
68+
}
69+
70+
/**
71+
* Create session from HAR file.
72+
*
73+
* @param string $filename
74+
*
75+
* @return Session
76+
* @throws HttpClientException
77+
* @throws InvalidArgumentException
78+
*/
79+
public static function createSessionFromFile(string $filename): Session
80+
{
81+
$harParser = new Parser();
82+
83+
return static::createSession($harParser->parse($filename, true));
84+
}
85+
}

src/History/History.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,23 @@ class History implements Countable, IteratorAggregate
3030
/** @var HistoryEntry[] */
3131
protected array $history = [];
3232

33+
public function __construct(private int|float $size = INF)
34+
{
35+
}
36+
37+
public function setSize(int|float $size): void
38+
{
39+
$this->size = $size;
40+
$this->flush();
41+
}
42+
43+
public function flush(): void
44+
{
45+
if ($this->count() > $this->size) {
46+
$this->history = array_slice($this->history, -$this->size);
47+
}
48+
}
49+
3350
/**
3451
* @inheritDoc
3552
*/
@@ -71,6 +88,7 @@ public function add(
7188
public function addEntry(HistoryEntry $entry): void
7289
{
7390
$this->history[] = $entry;
91+
$this->flush();
7492
}
7593

7694
/**

src/Options.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,15 @@ public function __construct(
4747
public int $retryTime = 1000,
4848
// NULL: to use default cookie manager, FALSE: to not use cookies, a CookieManager object to use
4949
public CookiesManager|false|null $cookies = null,
50+
// History size (int)
51+
public int|float $history = INF,
5052
// Callback on each request
5153
public ?Closure $callback = null,
5254
// Callback on exception
5355
public ?Closure $callbackException = null,
5456
// Default headers
5557
public array $headers = self::DEFAULT_HEADERS,
58+
// HTTP context
5659
public ?HttpContext $context = null,
5760
...$userDefined,
5861
) {
@@ -80,6 +83,7 @@ public static function make(array|self|null $options = null, ?self $initial = nu
8083
logFile: $initial?->logFile,
8184
exceptions: $initial?->exceptions ?? true,
8285
cookies: $initial?->cookies,
86+
history: $initial?->history ?? INF,
8387
callback: $initial?->callback,
8488
callbackException: $initial?->callbackException,
8589
headers: $initial?->headers ?? self::DEFAULT_HEADERS,

0 commit comments

Comments
 (0)