1--TEST--
2Curl option CURLOPT_PREREQFUNCTION
3--EXTENSIONS--
4curl
5filter
6--SKIPIF--
7<?php
8$curl_version = curl_version();
9if ($curl_version['version_number'] < 0x075000) die("skip: test works only with curl >= 7.80.0");
10?>
11--FILE--
12<?php
13include 'server.inc';
14
15$host = curl_cli_server_start();
16$port = (int) (explode(':', $host))[1];
17
18$ch = curl_init();
19curl_setopt($ch, CURLOPT_URL, "{$host}/get.inc?test=file");
20curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
21
22$result = curl_exec($ch);
23
24var_dump(CURLOPT_PREREQFUNCTION);
25var_dump(CURL_PREREQFUNC_OK);
26var_dump(CURL_PREREQFUNC_ABORT);
27
28$returnValue = CURL_PREREQFUNC_ABORT;
29
30echo "\nTesting with CURL_PREREQFUNC_ABORT\n";
31$callback = function() use ($port, &$returnValue) {
32	var_dump('callback');
33	var_dump(func_num_args());
34	$args = func_get_args();
35	var_dump(get_class($args[0]));
36	var_dump(filter_var($args[1], FILTER_VALIDATE_IP) !== false);
37	var_dump(filter_var($args[2], FILTER_VALIDATE_IP) !== false);
38	var_dump($port === $args[3]);
39	var_dump(is_int($args[4]));
40
41	return $returnValue;
42};
43
44curl_setopt($ch, CURLOPT_PREREQFUNCTION, $callback);
45
46$result = curl_exec($ch);
47
48var_dump($result);
49var_dump(curl_error($ch));
50var_dump(curl_errno($ch));
51
52$returnValue = CURL_PREREQFUNC_OK;
53
54echo "\nTesting with CURL_PREREQFUNC_OK\n";
55$result = curl_exec($ch);
56
57var_dump($result);
58var_dump(curl_error($ch));
59var_dump(curl_errno($ch));
60
61echo "\nTesting with curl_copy_handle\n";
62$ch2 = curl_copy_handle($ch);
63$result = curl_exec($ch2);
64var_dump($result);
65var_dump(curl_error($ch2));
66var_dump(curl_errno($ch2));
67
68echo "\nTesting with no return type\n";
69curl_setopt($ch, CURLOPT_PREREQFUNCTION, function() use ($port) {
70	// returns nothing
71});
72try {
73    curl_exec($ch);
74} catch (\TypeError $e) {
75    echo $e->getMessage() . \PHP_EOL;
76}
77
78echo "\nTesting with invalid type\n";
79curl_setopt($ch, CURLOPT_PREREQFUNCTION, function() use ($port) {
80	return 'this should be an integer';
81});
82try {
83    curl_exec($ch);
84} catch (\TypeError $e) {
85    echo $e->getMessage() . \PHP_EOL;
86}
87
88echo "\nTesting with invalid value\n";
89curl_setopt($ch, CURLOPT_PREREQFUNCTION, function() use ($port) {
90	return 42;
91});
92try {
93    curl_exec($ch);
94} catch (\ValueError $e) {
95    echo $e->getMessage() . \PHP_EOL;
96}
97
98echo "\nTesting with invalid option value\n";
99try {
100    curl_setopt($ch, CURLOPT_PREREQFUNCTION, 42);
101} catch (\TypeError $e) {
102    echo $e->getMessage() . \PHP_EOL;
103}
104
105echo "\nTesting with invalid option callback\n";
106try {
107    curl_setopt($ch, CURLOPT_PREREQFUNCTION, 'function_does_not_exist');
108} catch (\TypeError $e) {
109    echo $e->getMessage() . \PHP_EOL;
110}
111
112echo "\nTesting with null as the callback\n";
113var_dump(curl_setopt($ch, CURLOPT_PREREQFUNCTION, null));
114var_dump(curl_exec($ch));
115var_dump(curl_error($ch));
116var_dump(curl_errno($ch));
117
118echo "\nDone";
119?>
120--EXPECT--
121int(20312)
122int(0)
123int(1)
124
125Testing with CURL_PREREQFUNC_ABORT
126string(8) "callback"
127int(5)
128string(10) "CurlHandle"
129bool(true)
130bool(true)
131bool(true)
132bool(true)
133bool(false)
134string(41) "operation aborted by pre-request callback"
135int(42)
136
137Testing with CURL_PREREQFUNC_OK
138string(8) "callback"
139int(5)
140string(10) "CurlHandle"
141bool(true)
142bool(true)
143bool(true)
144bool(true)
145string(0) ""
146string(0) ""
147int(0)
148
149Testing with curl_copy_handle
150string(8) "callback"
151int(5)
152string(10) "CurlHandle"
153bool(true)
154bool(true)
155bool(true)
156bool(true)
157string(0) ""
158string(0) ""
159int(0)
160
161Testing with no return type
162The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT
163
164Testing with invalid type
165The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT
166
167Testing with invalid value
168The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT
169
170Testing with invalid option value
171curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_PREREQFUNCTION, no array or string given
172
173Testing with invalid option callback
174curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_PREREQFUNCTION, function "function_does_not_exist" not found or invalid function name
175
176Testing with null as the callback
177bool(true)
178string(0) ""
179string(0) ""
180int(0)
181
182Done
183