|
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