1--TEST-- 2Test trampoline for curl option CURLMOPT_PUSHFUNCTION 3--EXTENSIONS-- 4curl 5--XLEAK-- 6--SKIPIF-- 7<?php 8include 'skipif-nocaddy.inc'; 9 10$curl_version = curl_version(); 11if ($curl_version['version_number'] < 0x080100) { 12 exit("skip: test may crash with curl < 8.1.0"); 13} 14?> 15--FILE-- 16<?php 17 18class TrampolineTest { 19 public function __call(string $name, array $arguments) { 20 echo 'Trampoline for ', $name, PHP_EOL; 21 return CURL_PUSH_OK; 22 } 23} 24$o = new TrampolineTest(); 25$callback = [$o, 'trampoline']; 26 27$mh = curl_multi_init(); 28 29curl_multi_setopt($mh, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX); 30curl_multi_setopt($mh, CURLMOPT_PUSHFUNCTION, $callback); 31 32$ch = curl_init(); 33curl_setopt($ch, CURLOPT_URL, "https://localhost/serverpush"); 34curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); 35curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 36 37curl_multi_add_handle($mh, $ch); 38 39$responses = []; 40$active = null; 41do { 42 $status = curl_multi_exec($mh, $active); 43 44 do { 45 $info = curl_multi_info_read($mh); 46 if (false !== $info && $info['msg'] == CURLMSG_DONE) { 47 $handle = $info['handle']; 48 if ($handle !== null) { 49 $responses[] = curl_multi_getcontent($info['handle']); 50 curl_multi_remove_handle($mh, $handle); 51 curl_close($handle); 52 } 53 } 54 } while ($info); 55} while (count($responses) !== 2); 56 57curl_multi_close($mh); 58 59sort($responses); 60print_r($responses); 61?> 62--EXPECT-- 63Trampoline for trampoline 64Array 65( 66 [0] => main response 67 [1] => pushed response 68) 69