This source file includes following definitions.
- PHP_FUNCTION
- PHP_FUNCTION
- _php_curl_multi_cleanup_list
- curl_compare_resources
- PHP_FUNCTION
- _make_timeval_struct
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- _php_curl_multi_close
- PHP_FUNCTION
- _php_curl_multi_setopt
- PHP_FUNCTION
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "php.h"
28
29 #if HAVE_CURL
30
31 #include "php_curl.h"
32
33 #include <curl/curl.h>
34 #include <curl/multi.h>
35
36 #ifdef HAVE_SYS_SELECT_H
37 #include <sys/select.h>
38 #endif
39
40 #ifdef HAVE_SYS_TIME_H
41 #include <sys/time.h>
42 #endif
43
44 #ifdef HAVE_SYS_TYPES_H
45 #include <sys/types.h>
46 #endif
47
48 #ifdef HAVE_UNISTD_H
49 #include <unistd.h>
50 #endif
51
52
53
54 PHP_FUNCTION(curl_multi_init)
55 {
56 php_curlm *mh;
57
58 if (zend_parse_parameters_none() == FAILURE) {
59 return;
60 }
61
62 mh = ecalloc(1, sizeof(php_curlm));
63 mh->multi = curl_multi_init();
64
65 zend_llist_init(&mh->easyh, sizeof(zval), _php_curl_multi_cleanup_list, 0);
66
67 RETURN_RES(zend_register_resource(mh, le_curl_multi_handle));
68 }
69
70
71
72
73 PHP_FUNCTION(curl_multi_add_handle)
74 {
75 zval *z_mh;
76 zval *z_ch;
77 php_curlm *mh;
78 php_curl *ch;
79 zval tmp_val;
80
81 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &z_mh, &z_ch) == FAILURE) {
82 return;
83 }
84
85 if ((mh = (php_curlm *)zend_fetch_resource(Z_RES_P(z_mh), le_curl_multi_handle_name, le_curl_multi_handle)) == NULL) {
86 RETURN_FALSE;
87 }
88
89 if ((ch = (php_curl *)zend_fetch_resource(Z_RES_P(z_ch), le_curl_name, le_curl)) == NULL) {
90 RETURN_FALSE;
91 }
92
93 _php_curl_cleanup_handle(ch);
94
95
96 ZVAL_DUP(&tmp_val, z_ch);
97
98 zend_llist_add_element(&mh->easyh, &tmp_val);
99
100 RETURN_LONG((zend_long)curl_multi_add_handle(mh->multi, ch->cp));
101 }
102
103
104 void _php_curl_multi_cleanup_list(void *data)
105 {
106 zval *z_ch = (zval *)data;
107 php_curl *ch;
108
109 if (!z_ch) {
110 return;
111 }
112 if (!Z_RES_P(z_ch)->ptr) {
113 return;
114 }
115 if ((ch = (php_curl *)zend_fetch_resource(Z_RES_P(z_ch), le_curl_name, le_curl)) == NULL) {
116 return;
117 }
118
119 zend_list_delete(Z_RES_P(z_ch));
120 }
121
122
123
124 static int curl_compare_resources( zval *z1, zval *z2 )
125 {
126 return (Z_TYPE_P(z1) == Z_TYPE_P(z2) &&
127 Z_TYPE_P(z1) == IS_RESOURCE &&
128 Z_RES_P(z1) == Z_RES_P(z2));
129 }
130
131
132
133
134 PHP_FUNCTION(curl_multi_remove_handle)
135 {
136 zval *z_mh;
137 zval *z_ch;
138 php_curlm *mh;
139 php_curl *ch;
140
141 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &z_mh, &z_ch) == FAILURE) {
142 return;
143 }
144
145 if ((mh = (php_curlm *)zend_fetch_resource(Z_RES_P(z_mh), le_curl_multi_handle_name, le_curl_multi_handle)) == NULL) {
146 RETURN_FALSE;
147 }
148
149 if ((ch = (php_curl *)zend_fetch_resource(Z_RES_P(z_ch), le_curl_name, le_curl)) == NULL) {
150 RETURN_FALSE;
151 }
152
153 RETVAL_LONG((zend_long)curl_multi_remove_handle(mh->multi, ch->cp));
154 zend_llist_del_element(&mh->easyh, z_ch, (int (*)(void *, void *))curl_compare_resources);
155
156 }
157
158
159 static void _make_timeval_struct(struct timeval *to, double timeout)
160 {
161 unsigned long conv;
162
163 conv = (unsigned long) (timeout * 1000000.0);
164 to->tv_sec = conv / 1000000;
165 to->tv_usec = conv % 1000000;
166 }
167
168
169
170
171 PHP_FUNCTION(curl_multi_select)
172 {
173 zval *z_mh;
174 php_curlm *mh;
175 fd_set readfds;
176 fd_set writefds;
177 fd_set exceptfds;
178 int maxfd;
179 double timeout = 1.0;
180 struct timeval to;
181
182 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|d", &z_mh, &timeout) == FAILURE) {
183 return;
184 }
185
186 if ((mh = (php_curlm *)zend_fetch_resource(Z_RES_P(z_mh), le_curl_multi_handle_name, le_curl_multi_handle)) == NULL) {
187 RETURN_FALSE;
188 }
189
190 _make_timeval_struct(&to, timeout);
191
192 FD_ZERO(&readfds);
193 FD_ZERO(&writefds);
194 FD_ZERO(&exceptfds);
195
196 curl_multi_fdset(mh->multi, &readfds, &writefds, &exceptfds, &maxfd);
197 if (maxfd == -1) {
198 RETURN_LONG(-1);
199 }
200 RETURN_LONG(select(maxfd + 1, &readfds, &writefds, &exceptfds, &to));
201 }
202
203
204
205
206 PHP_FUNCTION(curl_multi_exec)
207 {
208 zval *z_mh;
209 zval *z_still_running;
210 php_curlm *mh;
211 int still_running;
212 int result;
213
214 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz/", &z_mh, &z_still_running) == FAILURE) {
215 return;
216 }
217
218 if ((mh = (php_curlm *)zend_fetch_resource(Z_RES_P(z_mh), le_curl_multi_handle_name, le_curl_multi_handle)) == NULL) {
219 RETURN_FALSE;
220 }
221
222 {
223 zend_llist_position pos;
224 php_curl *ch;
225 zval *pz_ch;
226
227 for (pz_ch = (zval *)zend_llist_get_first_ex(&mh->easyh, &pos); pz_ch;
228 pz_ch = (zval *)zend_llist_get_next_ex(&mh->easyh, &pos)) {
229
230 if ((ch = (php_curl *)zend_fetch_resource(Z_RES_P(pz_ch), le_curl_name, le_curl)) == NULL) {
231 RETURN_FALSE;
232 }
233
234 _php_curl_verify_handlers(ch, 1);
235 }
236 }
237
238 convert_to_long(z_still_running);
239 still_running = Z_LVAL_P(z_still_running);
240 result = curl_multi_perform(mh->multi, &still_running);
241 ZVAL_LONG(z_still_running, still_running);
242
243 RETURN_LONG(result);
244 }
245
246
247
248
249 PHP_FUNCTION(curl_multi_getcontent)
250 {
251 zval *z_ch;
252 php_curl *ch;
253
254 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_ch) == FAILURE) {
255 return;
256 }
257
258 if ((ch = (php_curl *)zend_fetch_resource(Z_RES_P(z_ch), le_curl_name, le_curl)) == NULL) {
259 RETURN_FALSE;
260 }
261
262 if (ch->handlers->write->method == PHP_CURL_RETURN) {
263 if (!ch->handlers->write->buf.s) {
264 RETURN_EMPTY_STRING();
265 }
266 smart_str_0(&ch->handlers->write->buf);
267 RETURN_STR_COPY(ch->handlers->write->buf.s);
268 }
269
270 RETURN_NULL();
271 }
272
273
274
275
276 PHP_FUNCTION(curl_multi_info_read)
277 {
278 zval *z_mh;
279 php_curlm *mh;
280 CURLMsg *tmp_msg;
281 int queued_msgs;
282 zval *zmsgs_in_queue = NULL;
283
284 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|z/", &z_mh, &zmsgs_in_queue) == FAILURE) {
285 return;
286 }
287
288 if ((mh = (php_curlm *)zend_fetch_resource(Z_RES_P(z_mh), le_curl_multi_handle_name, le_curl_multi_handle)) == NULL) {
289 RETURN_FALSE;
290 }
291
292 tmp_msg = curl_multi_info_read(mh->multi, &queued_msgs);
293 if (tmp_msg == NULL) {
294 RETURN_FALSE;
295 }
296 if (zmsgs_in_queue) {
297 zval_dtor(zmsgs_in_queue);
298 ZVAL_LONG(zmsgs_in_queue, queued_msgs);
299 }
300
301 array_init(return_value);
302 add_assoc_long(return_value, "msg", tmp_msg->msg);
303 add_assoc_long(return_value, "result", tmp_msg->data.result);
304
305
306 {
307 zend_llist_position pos;
308 php_curl *ch;
309 zval *pz_ch;
310
311
312 for(pz_ch = (zval *)zend_llist_get_first_ex(&mh->easyh, &pos); pz_ch;
313 pz_ch = (zval *)zend_llist_get_next_ex(&mh->easyh, &pos)) {
314
315 if ((ch = (php_curl *)zend_fetch_resource(Z_RES_P(pz_ch), le_curl_name, le_curl)) == NULL) {
316 RETURN_FALSE;
317 }
318 if (ch->cp == tmp_msg->easy_handle) {
319
320
321
322
323
324
325
326
327 Z_ADDREF_P(pz_ch);
328
329
330
331
332 add_assoc_zval(return_value, "handle", pz_ch);
333
334 break;
335 }
336 }
337 }
338 }
339
340
341
342
343 PHP_FUNCTION(curl_multi_close)
344 {
345 zval *z_mh;
346 php_curlm *mh;
347
348 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_mh) == FAILURE) {
349 return;
350 }
351
352 if ((mh = (php_curlm *)zend_fetch_resource(Z_RES_P(z_mh), le_curl_multi_handle_name, le_curl_multi_handle)) == NULL) {
353 RETURN_FALSE;
354 }
355
356 zend_list_close(Z_RES_P(z_mh));
357 }
358
359
360 void _php_curl_multi_close(zend_resource *rsrc)
361 {
362 php_curlm *mh = (php_curlm *)rsrc->ptr;
363 if (mh) {
364 zend_llist_position pos;
365 php_curl *ch;
366 zval *pz_ch;
367
368 for (pz_ch = (zval *)zend_llist_get_first_ex(&mh->easyh, &pos); pz_ch;
369 pz_ch = (zval *)zend_llist_get_next_ex(&mh->easyh, &pos)) {
370
371 if (Z_RES_P(pz_ch)->ptr) {
372 if ((ch = (php_curl *) zend_fetch_resource(Z_RES_P(pz_ch), le_curl_name, le_curl))) {
373 _php_curl_verify_handlers(ch, 0);
374 }
375 }
376 }
377
378 curl_multi_cleanup(mh->multi);
379 zend_llist_clean(&mh->easyh);
380 efree(mh);
381 rsrc->ptr = NULL;
382 }
383 }
384
385
386 #if LIBCURL_VERSION_NUM >= 0x070c00
387
388
389 PHP_FUNCTION(curl_multi_strerror)
390 {
391 zend_long code;
392 const char *str;
393
394 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &code) == FAILURE) {
395 return;
396 }
397
398 str = curl_multi_strerror(code);
399 if (str) {
400 RETURN_STRING(str);
401 } else {
402 RETURN_NULL();
403 }
404 }
405
406 #endif
407
408 #if LIBCURL_VERSION_NUM >= 0x070f04
409 static int _php_curl_multi_setopt(php_curlm *mh, zend_long option, zval *zvalue, zval *return_value)
410 {
411 CURLMcode error = CURLM_OK;
412
413 switch (option) {
414 #if LIBCURL_VERSION_NUM >= 0x071000
415 case CURLMOPT_PIPELINING:
416 #endif
417 #if LIBCURL_VERSION_NUM >= 0x071003
418 case CURLMOPT_MAXCONNECTS:
419 #endif
420 error = curl_multi_setopt(mh->multi, option, zval_get_long(zvalue));
421 break;
422
423 default:
424 php_error_docref(NULL, E_WARNING, "Invalid curl multi configuration option");
425 error = CURLM_UNKNOWN_OPTION;
426 break;
427 }
428
429 if (error != CURLM_OK) {
430 return 1;
431 } else {
432 return 0;
433 }
434 }
435
436
437
438
439 PHP_FUNCTION(curl_multi_setopt)
440 {
441 zval *z_mh, *zvalue;
442 zend_long options;
443 php_curlm *mh;
444
445 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlz", &z_mh, &options, &zvalue) == FAILURE) {
446 return;
447 }
448
449 if ((mh = (php_curlm *)zend_fetch_resource(Z_RES_P(z_mh), le_curl_multi_handle_name, le_curl_multi_handle)) == NULL) {
450 RETURN_FALSE;
451 }
452
453 if (!_php_curl_multi_setopt(mh, options, zvalue, return_value)) {
454 RETURN_TRUE;
455 } else {
456 RETURN_FALSE;
457 }
458 }
459
460 #endif
461
462 #endif
463
464
465
466
467
468
469
470
471