Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0023a71

Browse files
Thomas Talbotnicolas-grekas
Thomas Talbot
authored andcommitted
[FrameworkBundle] Add integration of http-client component
1 parent3abf9eb commit0023a71

19 files changed

+512
-3
lines changed

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

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
useSymfony\Bundle\FullStack;
1818
useSymfony\Component\Asset\Package;
1919
useSymfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
20+
useSymfony\Component\Config\Definition\Builder\NodeBuilder;
2021
useSymfony\Component\Config\Definition\Builder\TreeBuilder;
2122
useSymfony\Component\Config\Definition\ConfigurationInterface;
2223
useSymfony\Component\DependencyInjection\Exception\LogicException;
@@ -109,6 +110,7 @@ public function getConfigTreeBuilder()
109110
$this->addLockSection($rootNode);
110111
$this->addMessengerSection($rootNode);
111112
$this->addRobotsIndexSection($rootNode);
113+
$this->addHttpClientSection($rootNode);
112114

113115
return$treeBuilder;
114116
}
@@ -1170,4 +1172,124 @@ private function addRobotsIndexSection(ArrayNodeDefinition $rootNode)
11701172
->end()
11711173
;
11721174
}
1175+
1176+
privatefunctionaddHttpClientSection(ArrayNodeDefinition$rootNode)
1177+
{
1178+
$subNode =$rootNode
1179+
->children()
1180+
->arrayNode('http_client')
1181+
->info('HTTP Client configuration')
1182+
->canBeEnabled()
1183+
->fixXmlConfig('client')
1184+
->children();
1185+
1186+
$this->addHttpClientOptionsSection($subNode);
1187+
1188+
$subNode =$subNode
1189+
->arrayNode('clients')
1190+
->useAttributeAsKey('name')
1191+
->normalizeKeys(false)
1192+
->arrayPrototype()
1193+
->children();
1194+
1195+
$this->addHttpClientOptionsSection($subNode);
1196+
1197+
$subNode =$subNode
1198+
->end()
1199+
->end()
1200+
->end()
1201+
->end()
1202+
->end()
1203+
->end()
1204+
;
1205+
}
1206+
1207+
privatefunctionaddHttpClientOptionsSection(NodeBuilder$rootNode)
1208+
{
1209+
$rootNode
1210+
->integerNode('max_host_connections')
1211+
->info('The maximum number of connections to a single host.')
1212+
->end()
1213+
->arrayNode('default_options')
1214+
->fixXmlConfig('header')
1215+
->children()
1216+
->scalarNode('auth')
1217+
->info('An HTTP Basic authentication "username:password".')
1218+
->end()
1219+
->arrayNode('query')
1220+
->info('Associative array of query string values merged with URL parameters.')
1221+
->useAttributeAsKey('key')
1222+
->normalizeKeys(false)
1223+
->scalarPrototype()->end()
1224+
->end()
1225+
->arrayNode('headers')
1226+
->info('Associative array: header => value(s).')
1227+
->useAttributeAsKey('name')
1228+
->normalizeKeys(false)
1229+
->variablePrototype()->end()
1230+
->end()
1231+
->integerNode('max_redirects')
1232+
->info('The maximum number of redirects to follow.')
1233+
->end()
1234+
->scalarNode('http_version')
1235+
->info('The default HTTP version, typically 1.1 or 2.0. Leave to null for the best version.')
1236+
->end()
1237+
->scalarNode('base_uri')
1238+
->info('The URI to resolve relative URLs, following rules in RFC 3986, section 2.')
1239+
->end()
1240+
->booleanNode('buffer')
1241+
->info('Indicates if the response should be buffered or not.')
1242+
->end()
1243+
->arrayNode('resolve')
1244+
->info('Associative array: domain => IP.')
1245+
->useAttributeAsKey('host')
1246+
->normalizeKeys(false)
1247+
->scalarPrototype()->end()
1248+
->end()
1249+
->scalarNode('proxy')
1250+
->info('The URL of the proxy to pass requests through or null for automatic detection.')
1251+
->end()
1252+
->scalarNode('no_proxy')
1253+
->info('A comma separated list of hosts that do not require a proxy to be reached.')
1254+
->end()
1255+
->floatNode('timeout')
1256+
->info('Defaults to "default_socket_timeout" ini parameter.')
1257+
->end()
1258+
->scalarNode('bindto')
1259+
->info('A network interface name, IP address, a host name or a UNIX socket to bind to.')
1260+
->end()
1261+
->booleanNode('verify_peer')
1262+
->info('Indicates if the peer should be verified in a SSL/TLS context.')
1263+
->end()
1264+
->booleanNode('verify_host')
1265+
->info('Indicates if the host should exist as a certificate common name.')
1266+
->end()
1267+
->scalarNode('cafile')
1268+
->info('A certificate authority file.')
1269+
->end()
1270+
->scalarNode('capath')
1271+
->info('A directory that contains multiple certificate authority files.')
1272+
->end()
1273+
->scalarNode('local_cert')
1274+
->info('A PEM formatted certificate file.')
1275+
->end()
1276+
->scalarNode('local_pk')
1277+
->info('A private key file.')
1278+
->end()
1279+
->scalarNode('passphrase')
1280+
->info('The passphrase used to encrypt the "local_pk" file.')
1281+
->end()
1282+
->scalarNode('ciphers')
1283+
->info('A list of SSL/TLS ciphers separated by colons, commas or spaces (e.g. "RC4-SHA:TLS13-AES-128-GCM-SHA256"...)')
1284+
->end()
1285+
->arrayNode('peer_fingerprint')
1286+
->info('Associative array: hashing algorithm => hash(es).')
1287+
->useAttributeAsKey('algo')
1288+
->normalizeKeys(false)
1289+
->variablePrototype()->end()
1290+
->end()
1291+
->end()
1292+
->end()
1293+
;
1294+
}
11731295
}

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
useDoctrine\Common\Annotations\Reader;
1616
usePsr\Cache\CacheItemPoolInterface;
1717
usePsr\Container\ContainerInterfaceasPsrContainerInterface;
18+
usePsr\Http\Client\ClientInterface;
1819
usePsr\Log\LoggerAwareInterface;
1920
useSymfony\Bridge\Monolog\Processor\DebugProcessor;
2021
useSymfony\Bridge\Twig\Extension\CsrfExtension;
@@ -57,6 +58,9 @@
5758
useSymfony\Component\Form\FormTypeExtensionInterface;
5859
useSymfony\Component\Form\FormTypeGuesserInterface;
5960
useSymfony\Component\Form\FormTypeInterface;
61+
useSymfony\Component\HttpClient\HttpClient;
62+
useSymfony\Component\HttpClient\HttpClientTrait;
63+
useSymfony\Component\HttpClient\Psr18Client;
6064
useSymfony\Component\HttpKernel\CacheClearer\CacheClearerInterface;
6165
useSymfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
6266
useSymfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
@@ -110,6 +114,8 @@
110114
useSymfony\Component\Yaml\Command\LintCommandasBaseYamlLintCommand;
111115
useSymfony\Component\Yaml\Yaml;
112116
useSymfony\Contracts\Cache\CacheInterface;
117+
useSymfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
118+
useSymfony\Contracts\HttpClient\HttpClientInterface;
113119
useSymfony\Contracts\Service\ResetInterface;
114120
useSymfony\Contracts\Service\ServiceSubscriberInterface;
115121

@@ -301,6 +307,10 @@ public function load(array $configs, ContainerBuilder $container)
301307
$this->registerLockConfiguration($config['lock'],$container,$loader);
302308
}
303309

310+
if ($this->isConfigEnabled($container,$config['http_client'])) {
311+
$this->registerHttpClientConfiguration($config['http_client'],$container,$loader);
312+
}
313+
304314
if ($this->isConfigEnabled($container,$config['web_link'])) {
305315
if (!class_exists(HttpHeaderSerializer::class)) {
306316
thrownewLogicException('WebLink support cannot be enabled as the WebLink component is not installed. Try running "composer require symfony/weblink".');
@@ -1747,6 +1757,48 @@ private function registerCacheConfiguration(array $config, ContainerBuilder $con
17471757
}
17481758
}
17491759

1760+
privatefunctionregisterHttpClientConfiguration(array$config,ContainerBuilder$container,XmlFileLoader$loader)
1761+
{
1762+
if (!class_exists(HttpClient::class)) {
1763+
thrownewLogicException('HttpClient support cannot be enabled as the component is not installed. Try running "composer require symfony/http-client".');
1764+
}
1765+
1766+
$loader->load('http_client.xml');
1767+
1768+
$merger =newclass() {
1769+
use HttpClientTrait;
1770+
1771+
publicfunctionmerge(array$options,array$defaultOptions)
1772+
{
1773+
try {
1774+
[,$options] =$this->prepareRequest(null,null,$options,$defaultOptions);
1775+
1776+
return$options;
1777+
}catch (TransportExceptionInterface$e) {
1778+
thrownewInvalidArgumentException($e->getMessage(),0,$e);
1779+
}
1780+
}
1781+
};
1782+
1783+
$defaultOptions =$merger->merge($config['default_options'] ?? [], []);
1784+
$container->getDefinition('http_client')->setArguments([$defaultOptions,$config['max_host_connections'] ??6]);
1785+
1786+
foreach ($config['clients']as$name =>$clientConfig) {
1787+
$options =$merger->merge($clientConfig['default_options'] ?? [],$defaultOptions);
1788+
1789+
$container->register($name, HttpClientInterface::class)
1790+
->setFactory([HttpClient::class,'create'])
1791+
->setArguments([$options,$clientConfig['max_host_connections'] ??$config['max_host_connections'] ??6]);
1792+
1793+
$container->register('psr18.'.$name, Psr18Client::class)
1794+
->setAutowired(true)
1795+
->setArguments([newReference($name)]);
1796+
1797+
$container->registerAliasForArgument($name, HttpClientInterface::class);
1798+
$container->registerAliasForArgument('psr18.'.$name, ClientInterface::class,$name);
1799+
}
1800+
}
1801+
17501802
/**
17511803
* Returns the base path for the XSD files.
17521804
*
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" ?>
2+
3+
<containerxmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
6+
7+
<services>
8+
<serviceid="http_client"class="Symfony\Contracts\HttpClient\HttpClientInterface">
9+
<factoryclass="Symfony\Component\HttpClient\HttpClient"method="create" />
10+
<argumenttype="collection" /><!-- default options-->
11+
<argument /><!-- max host connections-->
12+
</service>
13+
<serviceid="Symfony\Contracts\HttpClient\HttpClientInterface"alias="http_client" />
14+
15+
<serviceid="psr18.http_client"class="Symfony\Component\HttpClient\Psr18Client"autowire="true">
16+
<argumenttype="service"id="http_client" />
17+
</service>
18+
<serviceid="Psr\Http\Client\ClientInterface"alias="psr18.http_client" />
19+
</services>
20+
</container>

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

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
<xsd:elementname="php-errors"type="php-errors"minOccurs="0"maxOccurs="1" />
3333
<xsd:elementname="lock"type="lock"minOccurs="0"maxOccurs="1" />
3434
<xsd:elementname="messenger"type="messenger"minOccurs="0"maxOccurs="1" />
35+
<xsd:elementname="http_client"type="http_client"minOccurs="0"maxOccurs="1" />
3536
</xsd:choice>
3637

3738
<xsd:attributename="http-method-override"type="xsd:boolean" />
@@ -444,4 +445,64 @@
444445
</xsd:sequence>
445446
<xsd:attributename="id"type="xsd:string"use="required"/>
446447
</xsd:complexType>
448+
449+
<xsd:complexTypename="http_client">
450+
<xsd:sequence>
451+
<xsd:elementname="max_host_connections"type="xsd:integer"minOccurs="0" />
452+
<xsd:elementname="default_options"type="http_client_options"minOccurs="0" />
453+
<xsd:elementname="client"type="http_client_client"minOccurs="0"maxOccurs="unbounded" />
454+
</xsd:sequence>
455+
<xsd:attributename="enabled"type="xsd:boolean" />
456+
</xsd:complexType>
457+
458+
<xsd:complexTypename="http_client_options">
459+
<xsd:sequence>
460+
<xsd:elementname="auth"type="xsd:string"minOccurs="0" />
461+
<xsd:elementname="query"type="http_query"minOccurs="0" />
462+
<xsd:elementname="headers"type="http_headers"minOccurs="0" />
463+
<xsd:elementname="max_redirects"type="xsd:integer"minOccurs="0" />
464+
<xsd:elementname="http_version"type="xsd:string"minOccurs="0" />
465+
<xsd:elementname="base_uri"type="xsd:string"minOccurs="0" />
466+
<xsd:elementname="buffer"type="xsd:boolean"minOccurs="0" />
467+
<xsd:elementname="resolve"type="metadata"minOccurs="0"maxOccurs="unbounded" />
468+
<xsd:elementname="proxy"type="xsd:string"minOccurs="0" />
469+
<xsd:elementname="no_proxy"type="xsd:string"minOccurs="0" />
470+
<xsd:elementname="timeout"type="xsd:float"minOccurs="0" />
471+
<xsd:elementname="bindto"type="xsd:string"minOccurs="0" />
472+
<xsd:elementname="verify_peer"type="xsd:boolean"minOccurs="0" />
473+
<xsd:elementname="verify_host"type="xsd:boolean"minOccurs="0" />
474+
<xsd:elementname="cafile"type="xsd:string"minOccurs="0" />
475+
<xsd:elementname="capath"type="xsd:string"minOccurs="0" />
476+
<xsd:elementname="local_cert"type="xsd:string"minOccurs="0" />
477+
<xsd:elementname="local_pk"type="xsd:string"minOccurs="0" />
478+
<xsd:elementname="passphrase"type="xsd:string"minOccurs="0" />
479+
<xsd:elementname="ciphers"type="xsd:string"minOccurs="0" />
480+
<xsd:elementname="peer_fingerprint"type="fingerprint"minOccurs="0"maxOccurs="unbounded" />
481+
</xsd:sequence>
482+
</xsd:complexType>
483+
484+
<xsd:complexTypename="http_client_client">
485+
<xsd:sequence>
486+
<xsd:elementname="default_options"type="http_client_options"minOccurs="0" />
487+
</xsd:sequence>
488+
<xsd:attributename="name"type="xsd:string" />
489+
</xsd:complexType>
490+
491+
<xsd:complexTypename="fingerprint">
492+
<xsd:sequence>
493+
<xsd:anyminOccurs="0"processContents="lax"maxOccurs="unbounded" />
494+
</xsd:sequence>
495+
</xsd:complexType>
496+
497+
<xsd:complexTypename="http_query">
498+
<xsd:sequence>
499+
<xsd:anyminOccurs="0"processContents="lax"maxOccurs="unbounded" />
500+
</xsd:sequence>
501+
</xsd:complexType>
502+
503+
<xsd:complexTypename="http_headers">
504+
<xsd:sequence>
505+
<xsd:anyminOccurs="0"processContents="lax"maxOccurs="unbounded" />
506+
</xsd:sequence>
507+
</xsd:complexType>
447508
</xsd:schema>

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,11 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor
331331
'buses' => ['messenger.bus.default' => ['default_middleware' =>true,'middleware' => []]],
332332
],
333333
'disallow_search_engine_index' =>true,
334+
'http_client' => [
335+
'enabled' =>false,
336+
'max_host_connections' =>6,
337+
'clients' => [],
338+
],
334339
];
335340
}
336341
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', [
4+
'http_client' => [
5+
'max_host_connections' =>4,
6+
'default_options' =>null,
7+
'clients' => [
8+
'foo' => [
9+
'default_options' =>null,
10+
],
11+
],
12+
],
13+
]);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', [
4+
'http_client' => [
5+
'default_options' => [
6+
'auth' =>'foo:bar',
7+
'query' => ['foo' =>'bar','bar' =>'baz'],
8+
'headers' => ['X-powered' =>'PHP'],
9+
'max_redirects' =>2,
10+
'http_version' =>'2.0',
11+
'base_uri' =>'http://example.com',
12+
'buffer' =>true,
13+
'resolve' => ['localhost' =>'127.0.0.1'],
14+
'proxy' =>'proxy.org',
15+
'timeout' =>3.5,
16+
'bindto' =>'127.0.0.1',
17+
'verify_peer' =>true,
18+
'verify_host' =>true,
19+
'cafile' =>'/etc/ssl/cafile',
20+
'capath' =>'/etc/ssl',
21+
'local_cert' =>'/etc/ssl/cert.pem',
22+
'local_pk' =>'/etc/ssl/private_key.pem',
23+
'passphrase' =>'password123456',
24+
'ciphers' =>'RC4-SHA:TLS13-AES-128-GCM-SHA256',
25+
'peer_fingerprint' => [
26+
'pin-sha256' => ['14s5erg62v1v8471g2revg48r7==','jsda84hjtyd4821bgfesd215bsfg5412='],
27+
'md5' =>'sdhtb481248721thbr=',
28+
],
29+
],
30+
],
31+
]);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', [
4+
'http_client' => [
5+
'default_options' => [
6+
'headers' => ['foo' =>'bar'],
7+
],
8+
'clients' => [
9+
'foo' => [
10+
'default_options' => [
11+
'headers' => ['bar' =>'baz'],
12+
],
13+
],
14+
],
15+
],
16+
]);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp