🌐 AI搜索 & 代理 主页
Skip to content

Commit c9a4bbd

Browse files
committed
Add option honor_request_http_version to control how the request HTTP version is handled in HttplugClient and Psr18Client
1 parent 23337bb commit c9a4bbd

File tree

5 files changed

+93
-2
lines changed

5 files changed

+93
-2
lines changed

src/Symfony/Component/HttpClient/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* Deprecate using amphp/http-client < 5
88
* Add RFC 9111–based caching support to `CachingHttpClient`
99
* Deprecate passing an instance of `StoreInterface` as `$cache` argument to `CachingHttpClient` constructor
10+
* Add option `honor_request_http_version` to control how the request HTTP version is handled in `HttplugClient` and `Psr18Client`
1011

1112
7.3
1213
---

src/Symfony/Component/HttpClient/HttplugClient.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ final class HttplugClient implements ClientInterface, HttpAsyncClient, RequestFa
6161
private HttpClientInterface $client;
6262
private ResponseFactoryInterface $responseFactory;
6363
private StreamFactoryInterface $streamFactory;
64+
private ?bool $honorRequestHttpVersion = null;
6465

6566
/**
6667
* @var \SplObjectStorage<ResponseInterface, array{RequestInterface, Promise}>|null
@@ -95,7 +96,13 @@ public function __construct(?HttpClientInterface $client = null, ?ResponseFactor
9596

9697
public function withOptions(array $options): static
9798
{
99+
if (\array_key_exists('honor_request_http_version', $options)) {
100+
$honorRequestHttpVersion = (bool) $options['honor_request_http_version'];
101+
unset($options['honor_request_http_version']);
102+
}
103+
98104
$clone = clone $this;
105+
$clone->honorRequestHttpVersion = $honorRequestHttpVersion ?? $this->honorRequestHttpVersion;
99106
$clone->client = $clone->client->withOptions($options);
100107

101108
return $clone;
@@ -265,7 +272,9 @@ private function sendPsr7Request(RequestInterface $request, ?bool $buffer = null
265272
'buffer' => $buffer,
266273
];
267274

268-
if ('1.0' === $request->getProtocolVersion()) {
275+
if ($this->honorRequestHttpVersion) {
276+
$options['http_version'] = $request->getProtocolVersion();
277+
} elseif ('1.0' === $request->getProtocolVersion() && null === $this->honorRequestHttpVersion) {
269278
$options['http_version'] = '1.0';
270279
}
271280

src/Symfony/Component/HttpClient/Psr18Client.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ final class Psr18Client implements ClientInterface, RequestFactoryInterface, Str
5353
private HttpClientInterface $client;
5454
private ResponseFactoryInterface $responseFactory;
5555
private StreamFactoryInterface $streamFactory;
56+
private ?bool $honorRequestHttpVersion = null;
5657

5758
public function __construct(?HttpClientInterface $client = null, ?ResponseFactoryInterface $responseFactory = null, ?StreamFactoryInterface $streamFactory = null)
5859
{
@@ -78,7 +79,13 @@ public function __construct(?HttpClientInterface $client = null, ?ResponseFactor
7879

7980
public function withOptions(array $options): static
8081
{
82+
if (\array_key_exists('honor_request_http_version', $options)) {
83+
$honorRequestHttpVersion = (bool) $options['honor_request_http_version'];
84+
unset($options['honor_request_http_version']);
85+
}
86+
8187
$clone = clone $this;
88+
$clone->honorRequestHttpVersion = $honorRequestHttpVersion ?? $this->honorRequestHttpVersion;
8289
$clone->client = $clone->client->withOptions($options);
8390

8491
return $clone;
@@ -128,7 +135,9 @@ public function sendRequest(RequestInterface $request): ResponseInterface
128135
'body' => $body,
129136
];
130137

131-
if ('1.0' === $request->getProtocolVersion()) {
138+
if ($this->honorRequestHttpVersion) {
139+
$options['http_version'] = $request->getProtocolVersion();
140+
} elseif ('1.0' === $request->getProtocolVersion() && null === $this->honorRequestHttpVersion) {
132141
$options['http_version'] = '1.0';
133142
}
134143

src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,4 +299,40 @@ public function testResponseReasonPhrase()
299299
$resultResponse = $client->sendRequest($request);
300300
$this->assertSame('Very Early Hints', $resultResponse->getReasonPhrase());
301301
}
302+
303+
public function testHonoringRequestHttpVersion()
304+
{
305+
$clientWithoutOption = new HttplugClient(new MockHttpClient(function (string $method, string $url, array $options) {
306+
return new MockResponse(json_encode([
307+
'SERVER_PROTOCOL' => 'HTTP/'.$options['http_version'] ?? '',
308+
]), [
309+
'response_headers' => [
310+
'Content-Type' => 'application/json',
311+
],
312+
]);
313+
}));
314+
$clientWithOptionTrue = $clientWithoutOption->withOptions(['honor_request_http_version' => true]);
315+
$clientWithOptionFalse = $clientWithoutOption->withOptions(['honor_request_http_version' => false]);
316+
317+
foreach (['1.0', '1.1', '2.0', '3.0'] as $httpVersion) {
318+
$request = $clientWithoutOption->createRequest('GET', 'http://localhost:8057')
319+
->withProtocolVersion($httpVersion);
320+
321+
$responseWithoutOption = $clientWithoutOption->sendRequest($request);
322+
$bodyWithoutOption = json_decode((string) $responseWithoutOption->getBody(), true);
323+
if ('1.0' === $httpVersion) {
324+
$this->assertSame('HTTP/1.0', $bodyWithoutOption['SERVER_PROTOCOL']);
325+
} else {
326+
$this->assertSame('HTTP/', $bodyWithoutOption['SERVER_PROTOCOL']);
327+
}
328+
329+
$responseWithOptionTrue = $clientWithOptionTrue->sendRequest($request);
330+
$bodyWithOptionTrue = json_decode((string) $responseWithOptionTrue->getBody(), true);
331+
$this->assertSame('HTTP/'.$httpVersion, $bodyWithOptionTrue['SERVER_PROTOCOL']);
332+
333+
$responseWithOptionFalse = $clientWithOptionFalse->sendRequest($request);
334+
$bodyWithOptionFalse = json_decode((string) $responseWithOptionFalse->getBody(), true);
335+
$this->assertSame('HTTP/', $bodyWithOptionFalse['SERVER_PROTOCOL']);
336+
}
337+
}
302338
}

src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,40 @@ public function testResponseReasonPhrase()
118118
$resultResponse = $client->sendRequest($request);
119119
$this->assertSame('Very Early Hints', $resultResponse->getReasonPhrase());
120120
}
121+
122+
public function testHonoringRequestHttpVersion()
123+
{
124+
$clientWithoutOption = new Psr18Client(new MockHttpClient(function (string $method, string $url, array $options) {
125+
return new MockResponse(json_encode([
126+
'SERVER_PROTOCOL' => 'HTTP/'.$options['http_version'] ?? '',
127+
]), [
128+
'response_headers' => [
129+
'Content-Type' => 'application/json',
130+
],
131+
]);
132+
}));
133+
$clientWithOptionTrue = $clientWithoutOption->withOptions(['honor_request_http_version' => true]);
134+
$clientWithOptionFalse = $clientWithoutOption->withOptions(['honor_request_http_version' => false]);
135+
136+
foreach (['1.0', '1.1', '2.0', '3.0'] as $httpVersion) {
137+
$request = $clientWithoutOption->createRequest('GET', 'http://localhost:8057')
138+
->withProtocolVersion($httpVersion);
139+
140+
$responseWithoutOption = $clientWithoutOption->sendRequest($request);
141+
$bodyWithoutOption = json_decode((string) $responseWithoutOption->getBody(), true);
142+
if ('1.0' === $httpVersion) {
143+
$this->assertSame('HTTP/1.0', $bodyWithoutOption['SERVER_PROTOCOL']);
144+
} else {
145+
$this->assertSame('HTTP/', $bodyWithoutOption['SERVER_PROTOCOL']);
146+
}
147+
148+
$responseWithOptionTrue = $clientWithOptionTrue->sendRequest($request);
149+
$bodyWithOptionTrue = json_decode((string) $responseWithOptionTrue->getBody(), true);
150+
$this->assertSame('HTTP/'.$httpVersion, $bodyWithOptionTrue['SERVER_PROTOCOL']);
151+
152+
$responseWithOptionFalse = $clientWithOptionFalse->sendRequest($request);
153+
$bodyWithOptionFalse = json_decode((string) $responseWithOptionFalse->getBody(), true);
154+
$this->assertSame('HTTP/', $bodyWithOptionFalse['SERVER_PROTOCOL']);
155+
}
156+
}
121157
}

0 commit comments

Comments
 (0)