Skip to content

Commit 97a3aac

Browse files
committed
[HttpClient] add "max_duration" option
1 parent f830226 commit 97a3aac

File tree

15 files changed

+79
-3
lines changed

15 files changed

+79
-3
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,10 @@ private function addHttpClientSection(ArrayNodeDefinition $rootNode)
13641364
->info('A comma separated list of hosts that do not require a proxy to be reached.')
13651365
->end()
13661366
->floatNode('timeout')
1367-
->info('Defaults to "default_socket_timeout" ini parameter.')
1367+
->info('The inactivity timeout. Defaults to "default_socket_timeout" ini parameter.')
1368+
->end()
1369+
->floatNode('max_duration')
1370+
->info('The maximum execution time for the request+response as a whole.')
13681371
->end()
13691372
->scalarNode('bindto')
13701373
->info('A network interface name, IP address, a host name or a UNIX socket to bind to.')

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,7 @@
494494
<xsd:attribute name="proxy" type="xsd:string" />
495495
<xsd:attribute name="no-proxy" type="xsd:string" />
496496
<xsd:attribute name="timeout" type="xsd:float" />
497+
<xsd:attribute name="max-duration" type="xsd:float" />
497498
<xsd:attribute name="bindto" type="xsd:string" />
498499
<xsd:attribute name="verify-peer" type="xsd:boolean" />
499500
<xsd:attribute name="verify-host" type="xsd:boolean" />

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/http_client_full_default_options.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
'resolve' => ['localhost' => '127.0.0.1'],
1010
'proxy' => 'proxy.org',
1111
'timeout' => 3.5,
12+
'max_duration' => 10.1,
1213
'bindto' => '127.0.0.1',
1314
'verify_peer' => true,
1415
'verify_host' => true,

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/http_client_full_default_options.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
proxy="proxy.org"
1212
bindto="127.0.0.1"
1313
timeout="3.5"
14+
max-duration="10.1"
1415
verify-peer="true"
1516
max-redirects="2"
1617
http-version="2.0"

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/http_client_full_default_options.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ framework:
88
resolve: {'localhost': '127.0.0.1'}
99
proxy: proxy.org
1010
timeout: 3.5
11+
max_duration: 10.1
1112
bindto: 127.0.0.1
1213
verify_peer: true
1314
verify_host: true

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,6 +1553,7 @@ public function testHttpClientFullDefaultOptions()
15531553
$this->assertSame(['localhost' => '127.0.0.1'], $defaultOptions['resolve']);
15541554
$this->assertSame('proxy.org', $defaultOptions['proxy']);
15551555
$this->assertSame(3.5, $defaultOptions['timeout']);
1556+
$this->assertSame(10.1, $defaultOptions['max_duration']);
15561557
$this->assertSame('127.0.0.1', $defaultOptions['bindto']);
15571558
$this->assertTrue($defaultOptions['verify_peer']);
15581559
$this->assertTrue($defaultOptions['verify_host']);

src/Symfony/Component/HttpClient/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ CHANGELOG
99
* added support for NTLM authentication
1010
* added `$response->toStream()` to cast responses to regular PHP streams
1111
* made `Psr18Client` implement relevant PSR-17 factories and have streaming responses
12+
* added `max_duration` option
1213

1314
4.3.0
1415
-----

src/Symfony/Component/HttpClient/CurlHttpClient.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,10 @@ public function request(string $method, string $url, array $options = []): Respo
284284
$curlopts[file_exists($options['bindto']) ? CURLOPT_UNIX_SOCKET_PATH : CURLOPT_INTERFACE] = $options['bindto'];
285285
}
286286

287+
if (0 < $options['max_duration']) {
288+
$curlopts[CURLOPT_TIMEOUT_MS] = 1000 * $options['max_duration'];
289+
}
290+
287291
$ch = curl_init();
288292

289293
foreach ($curlopts as $opt => $value) {

src/Symfony/Component/HttpClient/HttpClientTrait.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ private static function prepareRequest(?string $method, ?string $url, array $opt
113113
// Finalize normalization of options
114114
$options['http_version'] = (string) ($options['http_version'] ?? '') ?: null;
115115
$options['timeout'] = (float) ($options['timeout'] ?? ini_get('default_socket_timeout'));
116+
$options['max_duration'] = isset($options['max_duration']) ? (float) $options['max_duration'] : 0;
116117

117118
return [$url, $options];
118119
}

src/Symfony/Component/HttpClient/NativeHttpClient.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,12 @@ public function request(string $method, string $url, array $options = []): Respo
113113
if ($onProgress = $options['on_progress']) {
114114
// Memoize the last progress to ease calling the callback periodically when no network transfer happens
115115
$lastProgress = [0, 0];
116-
$onProgress = static function (...$progress) use ($onProgress, &$lastProgress, &$info) {
116+
$maxDuration = 0 < $options['max_duration'] ? $options['max_duration'] : INF;
117+
$onProgress = static function (...$progress) use ($onProgress, &$lastProgress, &$info, $maxDuration) {
118+
if ($info['total_time'] >= $maxDuration) {
119+
throw new TransportException(sprintf('Max duration was reached for "%s".', implode('', $info['url'])));
120+
}
121+
117122
$progressInfo = $info;
118123
$progressInfo['url'] = implode('', $info['url']);
119124
unset($progressInfo['size_body']);
@@ -127,6 +132,13 @@ public function request(string $method, string $url, array $options = []): Respo
127132

128133
$onProgress($lastProgress[0], $lastProgress[1], $progressInfo);
129134
};
135+
} elseif (0 < $options['max_duration']) {
136+
$maxDuration = $options['max_duration'];
137+
$onProgress = static function () use (&$info, $maxDuration): void {
138+
if ($info['total_time'] >= $maxDuration) {
139+
throw new TransportException(sprintf('Max duration was reached for "%s".', implode('', $info['url'])));
140+
}
141+
};
130142
}
131143

132144
// Always register a notification callback to compute live stats about the response
@@ -166,6 +178,10 @@ public function request(string $method, string $url, array $options = []): Respo
166178
$options['headers'][] = 'User-Agent: Symfony HttpClient/Native';
167179
}
168180

181+
if (0 < $options['max_duration']) {
182+
$options['timeout'] = min($options['max_duration'], $options['timeout']);
183+
}
184+
169185
$context = [
170186
'http' => [
171187
'protocol_version' => $options['http_version'] ?: '1.1',

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy