1212namespace Symfony \Component \HttpClient ;
1313
1414use Amp \CancelledException ;
15+ use Amp \DeferredFuture ;
1516use Amp \Http \Client \DelegateHttpClient ;
1617use Amp \Http \Client \InterceptedHttpClient ;
1718use Amp \Http \Client \PooledHttpClient ;
1819use Amp \Http \Client \Request ;
20+ use Amp \Http \HttpMessage ;
1921use Amp \Http \Tunnel \Http1TunnelConnector ;
20- use Amp \Promise ;
2122use Psr \Log \LoggerAwareInterface ;
2223use Psr \Log \LoggerAwareTrait ;
2324use Symfony \Component \HttpClient \Exception \TransportException ;
24- use Symfony \Component \HttpClient \Internal \AmpClientState ;
25- use Symfony \Component \HttpClient \Response \AmpResponse ;
25+ use Symfony \Component \HttpClient \Internal \AmpClientStateV4 ;
26+ use Symfony \Component \HttpClient \Internal \AmpClientStateV5 ;
27+ use Symfony \Component \HttpClient \Response \AmpResponseV4 ;
28+ use Symfony \Component \HttpClient \Response \AmpResponseV5 ;
2629use Symfony \Component \HttpClient \Response \ResponseStream ;
2730use Symfony \Contracts \HttpClient \HttpClientInterface ;
2831use Symfony \Contracts \HttpClient \ResponseInterface ;
3336 throw new \LogicException ('You cannot use "Symfony\Component\HttpClient\AmpHttpClient" as the "amphp/http-client" package is not installed. Try running "composer require amphp/http-client:^4.2.1". ' );
3437}
3538
36- if (! interface_exists (Promise ::class)) {
37- throw new \LogicException ('You cannot use "Symfony\Component\HttpClient\AmpHttpClient" as the installed " amphp/http-client" is not compatible with this version of "symfony/http-client". Try downgrading " amphp/http-client" to " ^4.2.1". ' );
39+ if (\ PHP_VERSION_ID < 80400 && is_subclass_of (Request::class, HttpMessage ::class)) {
40+ throw new \LogicException ('Using "Symfony\Component\HttpClient\AmpHttpClient" with amphp/http-client >= 5 requires PHP >= 8.4. Try running "composer require amphp/http-client: ^4.2.1" or upgrade to PHP >= 8.4 . ' );
3841}
3942
4043/**
@@ -53,7 +56,7 @@ final class AmpHttpClient implements HttpClientInterface, LoggerAwareInterface,
5356
5457 private array $ defaultOptions = self ::OPTIONS_DEFAULTS ;
5558 private static array $ emptyDefaults = self ::OPTIONS_DEFAULTS ;
56- private AmpClientState $ multi ;
59+ private AmpClientStateV4 | AmpClientStateV5 $ multi ;
5760
5861 /**
5962 * @param array $defaultOptions Default requests' options
@@ -72,7 +75,11 @@ public function __construct(array $defaultOptions = [], ?callable $clientConfigu
7275 [, $ this ->defaultOptions ] = self ::prepareRequest (null , null , $ defaultOptions , $ this ->defaultOptions );
7376 }
7477
75- $ this ->multi = new AmpClientState ($ clientConfigurator , $ maxHostConnections , $ maxPendingPushes , $ this ->logger );
78+ if (is_subclass_of (Request::class, HttpMessage::class)) {
79+ $ this ->multi = new AmpClientStateV5 ($ clientConfigurator , $ maxHostConnections , $ maxPendingPushes , $ this ->logger );
80+ } else {
81+ $ this ->multi = new AmpClientStateV4 ($ clientConfigurator , $ maxHostConnections , $ maxPendingPushes , $ this ->logger );
82+ }
7683 }
7784
7885 /**
@@ -132,9 +139,10 @@ public function request(string $method, string $url, array $options = []): Respo
132139 $ request ->addHeader ($ h [0 ], $ h [1 ]);
133140 }
134141
135- $ request ->setTcpConnectTimeout (1000 * $ options ['timeout ' ]);
136- $ request ->setTlsHandshakeTimeout (1000 * $ options ['timeout ' ]);
137- $ request ->setTransferTimeout (1000 * $ options ['max_duration ' ]);
142+ $ coef = $ request instanceof HttpMessage ? 1 : 1000 ;
143+ $ request ->setTcpConnectTimeout ($ coef * $ options ['timeout ' ]);
144+ $ request ->setTlsHandshakeTimeout ($ coef * $ options ['timeout ' ]);
145+ $ request ->setTransferTimeout ($ coef * $ options ['max_duration ' ]);
138146 if (method_exists ($ request , 'setInactivityTimeout ' )) {
139147 $ request ->setInactivityTimeout (0 );
140148 }
@@ -145,25 +153,37 @@ public function request(string $method, string $url, array $options = []): Respo
145153 $ request ->setHeader ('Authorization ' , 'Basic ' .base64_encode (implode (': ' , $ auth )));
146154 }
147155
148- return new AmpResponse ($ this ->multi , $ request , $ options , $ this ->logger );
156+ if ($ request instanceof HttpMessage) {
157+ return new AmpResponseV5 ($ this ->multi , $ request , $ options , $ this ->logger );
158+ }
159+
160+ return new AmpResponseV4 ($ this ->multi , $ request , $ options , $ this ->logger );
149161 }
150162
151163 public function stream (ResponseInterface |iterable $ responses , ?float $ timeout = null ): ResponseStreamInterface
152164 {
153- if ($ responses instanceof AmpResponse ) {
165+ if ($ responses instanceof AmpResponseV4 || $ responses instanceof AmpResponseV5 ) {
154166 $ responses = [$ responses ];
155167 }
156168
157- return new ResponseStream (AmpResponse::stream ($ responses , $ timeout ));
169+ if ($ this ->multi instanceof AmpClientStateV5) {
170+ return new ResponseStream (AmpResponseV5::stream ($ responses , $ timeout ));
171+ }
172+
173+ return new ResponseStream (AmpResponseV4::stream ($ responses , $ timeout ));
158174 }
159175
160176 public function reset (): void
161177 {
162178 $ this ->multi ->dnsCache = [];
163179
164- foreach ($ this ->multi ->pushedResponses as $ authority => $ pushedResponses ) {
180+ foreach ($ this ->multi ->pushedResponses as $ pushedResponses ) {
165181 foreach ($ pushedResponses as [$ pushedUrl , $ pushDeferred ]) {
166- $ pushDeferred ->fail (new CancelledException ());
182+ if ($ pushDeferred instanceof DeferredFuture) {
183+ $ pushDeferred ->error (new CancelledException ());
184+ } else {
185+ $ pushDeferred ->fail (new CancelledException ());
186+ }
167187
168188 $ this ->logger ?->debug(sprintf ('Unused pushed response: "%s" ' , $ pushedUrl ));
169189 }
0 commit comments