|
15 | 15 | use Symfony\Component\HttpClient\Chunk\FirstChunk; |
16 | 16 | use Symfony\Component\HttpClient\Chunk\InformationalChunk; |
17 | 17 | use Symfony\Component\HttpClient\Exception\TransportException; |
| 18 | +use Symfony\Component\HttpClient\Internal\Canary; |
18 | 19 | use Symfony\Component\HttpClient\Internal\ClientState; |
19 | 20 | use Symfony\Component\HttpClient\Internal\CurlClientState; |
20 | 21 | use Symfony\Contracts\HttpClient\ResponseInterface; |
@@ -149,6 +150,31 @@ public function __construct(CurlClientState $multi, $ch, array $options = null, |
149 | 150 | // Schedule the request in a non-blocking way |
150 | 151 | $multi->openHandles[$id] = [$ch, $options]; |
151 | 152 | curl_multi_add_handle($multi->handle, $ch); |
| 153 | + |
| 154 | + $this->canary = new Canary(static function () use ($ch, $multi, $id) { |
| 155 | + unset($multi->openHandles[$id], $multi->handlesActivity[$id]); |
| 156 | + curl_setopt($ch, \CURLOPT_PRIVATE, '_0'); |
| 157 | + |
| 158 | + if (self::$performing) { |
| 159 | + return; |
| 160 | + } |
| 161 | + |
| 162 | + curl_multi_remove_handle($multi->handle, $ch); |
| 163 | + curl_setopt_array($ch, [ |
| 164 | + \CURLOPT_NOPROGRESS => true, |
| 165 | + \CURLOPT_PROGRESSFUNCTION => null, |
| 166 | + \CURLOPT_HEADERFUNCTION => null, |
| 167 | + \CURLOPT_WRITEFUNCTION => null, |
| 168 | + \CURLOPT_READFUNCTION => null, |
| 169 | + \CURLOPT_INFILE => null, |
| 170 | + ]); |
| 171 | + |
| 172 | + if (!$multi->openHandles) { |
| 173 | + // Schedule DNS cache eviction for the next request |
| 174 | + $multi->dnsCache->evictions = $multi->dnsCache->evictions ?: $multi->dnsCache->removals; |
| 175 | + $multi->dnsCache->removals = $multi->dnsCache->hostnames = []; |
| 176 | + } |
| 177 | + }); |
152 | 178 | } |
153 | 179 |
|
154 | 180 | /** |
@@ -199,48 +225,11 @@ public function getContent(bool $throw = true): string |
199 | 225 |
|
200 | 226 | public function __destruct() |
201 | 227 | { |
202 | | - try { |
203 | | - if (null === $this->timeout) { |
204 | | - return; // Unused pushed response |
205 | | - } |
206 | | - |
207 | | - $this->doDestruct(); |
208 | | - } finally { |
209 | | - $multi = clone $this->multi; |
210 | | - |
211 | | - $this->close(); |
212 | | - |
213 | | - if (!$this->multi->openHandles) { |
214 | | - // Schedule DNS cache eviction for the next request |
215 | | - $this->multi->dnsCache->evictions = $this->multi->dnsCache->evictions ?: $this->multi->dnsCache->removals; |
216 | | - $this->multi->dnsCache->removals = $this->multi->dnsCache->hostnames = []; |
217 | | - } |
218 | | - |
219 | | - $this->multi = $multi; |
220 | | - } |
221 | | - } |
222 | | - |
223 | | - /** |
224 | | - * {@inheritdoc} |
225 | | - */ |
226 | | - private function close(): void |
227 | | - { |
228 | | - unset($this->multi->openHandles[$this->id], $this->multi->handlesActivity[$this->id]); |
229 | | - curl_setopt($this->handle, \CURLOPT_PRIVATE, '_0'); |
230 | | - |
231 | | - if (self::$performing) { |
232 | | - return; |
| 228 | + if (null === $this->timeout) { |
| 229 | + return; // Unused pushed response |
233 | 230 | } |
234 | 231 |
|
235 | | - curl_multi_remove_handle($this->multi->handle, $this->handle); |
236 | | - curl_setopt_array($this->handle, [ |
237 | | - \CURLOPT_NOPROGRESS => true, |
238 | | - \CURLOPT_PROGRESSFUNCTION => null, |
239 | | - \CURLOPT_HEADERFUNCTION => null, |
240 | | - \CURLOPT_WRITEFUNCTION => null, |
241 | | - \CURLOPT_READFUNCTION => null, |
242 | | - \CURLOPT_INFILE => null, |
243 | | - ]); |
| 232 | + $this->doDestruct(); |
244 | 233 | } |
245 | 234 |
|
246 | 235 | /** |
|
0 commit comments