2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.0 of the PHP license, that |
6 | is bundled with this package in the file LICENSE, and is available |
7 | through the world-wide-web at http://www.php.net/license/3_0.txt. |
8 | If you did not receive a copy of the PHP license and are unable to |
9 | obtain it through the world-wide-web, please send a note to |
10 | license@php.net so we can mail you a copy immediately. |
11 +----------------------------------------------------------------------+
12 | Copyright (c) 2004-2005 Michael Wallner <mike@php.net> |
13 +----------------------------------------------------------------------+
24 # define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
25 # include <winsock2.h>
26 # include <sys/types.h>
29 #include <curl/curl.h>
30 #include <curl/easy.h>
34 #include "php_http_api.h"
35 #include "php_http_curl_api.h"
37 #include "ext/standard/php_smart_str.h"
39 ZEND_DECLARE_MODULE_GLOBALS(http
)
41 #define http_curl_initbuf() _http_curl_initbuf_ex(0 TSRMLS_CC)
42 #define http_curl_initbuf_ex(s) _http_curl_initbuf_ex((s) TSRMLS_CC)
43 static inline void _http_curl_initbuf_ex(size_t chunk_size TSRMLS_DC
);
45 #define http_curl_freebuf() _http_curl_freebuf(TSRMLS_C)
46 static inline void _http_curl_freebuf(TSRMLS_D
);
47 #define http_curl_sizebuf(l) _http_curl_sizebuf((l) TSRMLS_CC)
48 static inline void _http_curl_sizebuf(size_t len TSRMLS_DC
);
49 #define http_curl_movebuf(d, l) _http_curl_movebuf((d), (l) TSRMLS_CC)
50 static inline void _http_curl_movebuf(char **data
, size_t *data_len TSRMLS_DC
);
51 #define http_curl_copybuf(d, l) _http_curl_copybuf((d), (l) TSRMLS_CC)
52 static inline void _http_curl_copybuf(char **data
, size_t *data_len TSRMLS_DC
);
53 #define http_curl_setopts(c, u, o) _http_curl_setopts((c), (u), (o) TSRMLS_CC)
54 static inline void _http_curl_setopts(CURL
*ch
, const char *url
, HashTable
*options TSRMLS_DC
);
56 #define http_curl_getopt(o, k) _http_curl_getopt((o), (k) TSRMLS_CC, 0)
57 #define http_curl_getopt1(o, k, t1) _http_curl_getopt((o), (k) TSRMLS_CC, 1, (t1))
58 #define http_curl_getopt2(o, k, t1, t2) _http_curl_getopt((o), (k) TSRMLS_CC, 2, (t1), (t2))
59 static inline zval
*_http_curl_getopt(HashTable
*options
, char *key TSRMLS_DC
, int checks
, ...);
61 static size_t http_curl_body_callback(char *, size_t, size_t, void *);
62 static size_t http_curl_hdrs_callback(char *, size_t, size_t, void *);
64 #define http_curl_getinfo(c, h) _http_curl_getinfo((c), (h) TSRMLS_CC)
65 static inline void _http_curl_getinfo(CURL
*ch
, HashTable
*info TSRMLS_DC
);
66 #define http_curl_getinfo_ex(c, i, a) _http_curl_getinfo_ex((c), (i), (a) TSRMLS_CC)
67 static inline void _http_curl_getinfo_ex(CURL
*ch
, CURLINFO i
, zval
*array TSRMLS_DC
);
68 #define http_curl_getinfoname(i) _http_curl_getinfoname((i) TSRMLS_CC)
69 static inline char *_http_curl_getinfoname(CURLINFO i TSRMLS_DC
);
71 /* {{{ static inline void http_curl_initbuf(size_t chunk_size) */
72 static inline void _http_curl_initbuf_ex(size_t chunk_size TSRMLS_DC
)
74 size_t size
= (chunk_size
> 0) ? chunk_size
: HTTP_CURLBUF_SIZE
;
78 HTTP_G(curlbuf
).data
= emalloc(size
);
79 HTTP_G(curlbuf
).free
= size
;
80 HTTP_G(curlbuf
).size
= size
;
84 /* {{{ static inline void http_curl_freebuf(void) */
85 static inline void _http_curl_freebuf(TSRMLS_D
)
87 if (HTTP_G(curlbuf
).data
) {
88 efree(HTTP_G(curlbuf
).data
);
89 HTTP_G(curlbuf
).data
= NULL
;
91 HTTP_G(curlbuf
).used
= 0;
92 HTTP_G(curlbuf
).free
= 0;
93 HTTP_G(curlbuf
).size
= 0;
97 /* {{{ static inline void http_curl_copybuf(char **, size_t *) */
98 static inline void _http_curl_copybuf(char **data
, size_t *data_len TSRMLS_DC
)
100 *data_len
= HTTP_G(curlbuf
).used
;
102 *data
= ecalloc(1, HTTP_G(curlbuf
).used
+ 1);
103 memcpy(*data
, HTTP_G(curlbuf
).data
, *data_len
);
107 /* {{{ static inline void http_curl_movebuf(char **, size_t *) */
108 static inline void _http_curl_movebuf(char **data
, size_t *data_len TSRMLS_DC
)
110 http_curl_copybuf(data
, data_len
);
115 /* {{{ static inline void http_curl_sizebuf(size_t len) */
116 static inline void _http_curl_sizebuf(size_t len TSRMLS_DC
)
118 if (len
> HTTP_G(curlbuf
).free
) {
119 size_t bsize
= HTTP_G(curlbuf
).size
;
120 while (bsize
< len
) {
123 HTTP_G(curlbuf
).data
= erealloc(HTTP_G(curlbuf
).data
, HTTP_G(curlbuf
).used
+ bsize
);
124 HTTP_G(curlbuf
).free
+= bsize
;
129 /* {{{ static size_t http_curl_body_callback(char *, size_t, size_t, void *) */
130 static size_t http_curl_body_callback(char *buf
, size_t len
, size_t n
, void *s
)
134 http_curl_sizebuf(len
*= n
);
136 memcpy(HTTP_G(curlbuf
).data
+ HTTP_G(curlbuf
).used
, buf
, len
);
137 HTTP_G(curlbuf
).free
-= len
;
138 HTTP_G(curlbuf
).used
+= len
;
143 /* {{{ static size_t http_curl_hdrs_callback(char *, size_t, size_t, void *) */
144 static size_t http_curl_hdrs_callback(char *buf
, size_t len
, size_t n
, void *s
)
148 /* discard previous headers */
149 if ((HTTP_G(curlbuf
).used
) && (!strncmp(buf
, "HTTP/1.", sizeof("HTTP/1.") - 1))) {
152 http_curl_sizebuf(len
*= n
);
154 memcpy(HTTP_G(curlbuf
).data
+ HTTP_G(curlbuf
).used
, buf
, len
);
155 HTTP_G(curlbuf
).free
-= len
;
156 HTTP_G(curlbuf
).used
+= len
;
161 /* {{{ static inline zval *http_curl_getopt(HashTable *, char *, int, ...) */
162 static inline zval
*_http_curl_getopt(HashTable
*options
, char *key TSRMLS_DC
, int checks
, ...)
168 if (SUCCESS
!= zend_hash_find(options
, key
, strlen(key
) + 1, (void **) &zoption
)) {
175 va_start(types
, checks
);
176 for (i
= 0; i
< checks
; ++i
) {
177 if ((va_arg(types
, int)) == (Z_TYPE_PP(zoption
))) {
187 /* {{{ static inline void http_curl_setopts(CURL *, char *, HashTable *) */
188 static inline void _http_curl_setopts(CURL
*ch
, const char *url
, HashTable
*options TSRMLS_DC
)
192 /* standard options */
193 curl_easy_setopt(ch
, CURLOPT_URL
, url
);
194 curl_easy_setopt(ch
, CURLOPT_HEADER
, 0);
195 curl_easy_setopt(ch
, CURLOPT_NOPROGRESS
, 1);
196 curl_easy_setopt(ch
, CURLOPT_AUTOREFERER
, 1);
197 curl_easy_setopt(ch
, CURLOPT_WRITEFUNCTION
, http_curl_body_callback
);
198 curl_easy_setopt(ch
, CURLOPT_HEADERFUNCTION
, http_curl_hdrs_callback
);
199 #if defined(ZTS) && (LIBCURL_VERSION_NUM >= 0x070a00)
200 curl_easy_setopt(ch
, CURLOPT_NOSIGNAL
, 1);
203 if ((!options
) || (1 > zend_hash_num_elements(options
))) {
207 /* redirects, defaults to 0 */
208 if (zoption
= http_curl_getopt1(options
, "redirect", IS_LONG
)) {
209 curl_easy_setopt(ch
, CURLOPT_FOLLOWLOCATION
, Z_LVAL_P(zoption
) ? 1 : 0);
210 curl_easy_setopt(ch
, CURLOPT_MAXREDIRS
, Z_LVAL_P(zoption
));
211 if (zoption
= http_curl_getopt2(options
, "unrestrictedauth", IS_LONG
, IS_BOOL
)) {
212 curl_easy_setopt(ch
, CURLOPT_UNRESTRICTED_AUTH
, Z_LVAL_P(zoption
));
215 curl_easy_setopt(ch
, CURLOPT_FOLLOWLOCATION
, 0);
219 if (zoption
= http_curl_getopt1(options
, "proxyhost", IS_STRING
)) {
220 curl_easy_setopt(ch
, CURLOPT_PROXY
, Z_STRVAL_P(zoption
));
222 if (zoption
= http_curl_getopt1(options
, "proxyport", IS_LONG
)) {
223 curl_easy_setopt(ch
, CURLOPT_PROXYPORT
, Z_LVAL_P(zoption
));
226 if (zoption
= http_curl_getopt1(options
, "proxyauth", IS_STRING
)) {
227 curl_easy_setopt(ch
, CURLOPT_PROXYUSERPWD
, Z_STRVAL_P(zoption
));
229 #if LIBCURL_VERSION_NUM > 0x070a06
231 if (zoption
= http_curl_getopt1(options
, "proxyauthtype", IS_LONG
)) {
232 curl_easy_setopt(ch
, CURLOPT_PROXYAUTH
, Z_LVAL_P(zoption
));
238 if (zoption
= http_curl_getopt1(options
, "httpauth", IS_STRING
)) {
239 curl_easy_setopt(ch
, CURLOPT_USERPWD
, Z_STRVAL_P(zoption
));
241 #if LIBCURL_VERSION_NUM > 0x070a05
242 if (zoption
= http_curl_getopt1(options
, "httpauthtype", IS_LONG
)) {
243 curl_easy_setopt(ch
, CURLOPT_HTTPAUTH
, Z_LVAL_P(zoption
));
247 /* compress, enabled by default (empty string enables deflate and gzip) */
248 if (zoption
= http_curl_getopt2(options
, "compress", IS_LONG
, IS_BOOL
)) {
249 if (Z_LVAL_P(zoption
)) {
250 curl_easy_setopt(ch
, CURLOPT_ENCODING
, "");
253 curl_easy_setopt(ch
, CURLOPT_ENCODING
, "");
257 if (zoption
= http_curl_getopt1(options
, "port", IS_LONG
)) {
258 curl_easy_setopt(ch
, CURLOPT_PORT
, Z_LVAL_P(zoption
));
262 if (zoption
= http_curl_getopt1(options
, "referer", IS_STRING
)) {
263 curl_easy_setopt(ch
, CURLOPT_REFERER
, Z_STRVAL_P(zoption
));
266 /* useragent, default "PECL::HTTP/version (PHP/version)" */
267 if (zoption
= http_curl_getopt1(options
, "useragent", IS_STRING
)) {
268 curl_easy_setopt(ch
, CURLOPT_USERAGENT
, Z_STRVAL_P(zoption
));
270 curl_easy_setopt(ch
, CURLOPT_USERAGENT
,
271 "PECL::HTTP/" PHP_EXT_HTTP_VERSION
" (PHP/" PHP_VERSION
")");
274 /* cookies, array('name' => 'value') */
275 if (zoption
= http_curl_getopt1(options
, "cookies", IS_ARRAY
)) {
279 smart_str qstr
= {0};
281 zend_hash_internal_pointer_reset(Z_ARRVAL_P(zoption
));
282 while (HASH_KEY_NON_EXISTANT
!= (key_type
= zend_hash_get_current_key_type(Z_ARRVAL_P(zoption
)))) {
283 if (key_type
== HASH_KEY_IS_STRING
) {
284 zend_hash_get_current_key(Z_ARRVAL_P(zoption
), &cookie_key
, NULL
, 0);
285 zend_hash_get_current_data(Z_ARRVAL_P(zoption
), (void **) &cookie_val
);
286 smart_str_appends(&qstr
, cookie_key
);
287 smart_str_appendl(&qstr
, "=", 1);
288 smart_str_appendl(&qstr
, Z_STRVAL_PP(cookie_val
), Z_STRLEN_PP(cookie_val
));
289 smart_str_appendl(&qstr
, "; ", 2);
290 zend_hash_move_forward(Z_ARRVAL_P(zoption
));
296 curl_easy_setopt(ch
, CURLOPT_COOKIE
, qstr
.c
);
297 /* FIXXXME: mem-leak */
302 if (zoption
= http_curl_getopt1(options
, "cookiestore", IS_STRING
)) {
303 curl_easy_setopt(ch
, CURLOPT_COOKIEFILE
, Z_STRVAL_P(zoption
));
304 curl_easy_setopt(ch
, CURLOPT_COOKIEJAR
, Z_STRVAL_P(zoption
));
307 /* additional headers, array('name' => 'value') */
308 if (zoption
= http_curl_getopt1(options
, "headers", IS_ARRAY
)) {
310 char *header_key
, header
[1024] = {0};
312 struct curl_slist
*headers
= NULL
;
314 zend_hash_internal_pointer_reset(Z_ARRVAL_P(zoption
));
315 while (HASH_KEY_NON_EXISTANT
!= (key_type
= zend_hash_get_current_key_type(Z_ARRVAL_P(zoption
)))) {
316 if (key_type
== HASH_KEY_IS_STRING
) {
317 zend_hash_get_current_key(Z_ARRVAL_P(zoption
), &header_key
, NULL
, 0);
318 zend_hash_get_current_data(Z_ARRVAL_P(zoption
), (void **) &header_val
);
319 snprintf(header
, 1023, "%s: %s", header_key
, Z_STRVAL_PP(header_val
));
320 headers
= curl_slist_append(headers
, header
);
321 zend_hash_move_forward(Z_ARRVAL_P(zoption
));
325 curl_easy_setopt(ch
, CURLOPT_HTTPHEADER
, headers
);
331 /* {{{ static inline char *http_curl_getinfoname(CURLINFO) */
332 static inline char *_http_curl_getinfoname(CURLINFO i TSRMLS_DC
)
334 #define CASE(I) case CURLINFO_ ##I : { static char I[] = #I; return pretty_key(I, sizeof(#I)-1, 0, 0); }
337 /* CURLINFO_EFFECTIVE_URL = CURLINFO_STRING +1, */
339 /* CURLINFO_RESPONSE_CODE = CURLINFO_LONG +2, */
340 #if LIBCURL_VERSION_NUM > 0x070a06
345 /* CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE +3, */
347 /* CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE +4, */
348 CASE(NAMELOOKUP_TIME
);
349 /* CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE +5, */
351 /* CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE +6, */
352 CASE(PRETRANSFER_TIME
);
353 /* CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE +7, */
355 /* CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE +8, */
357 /* CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE +9, */
358 CASE(SPEED_DOWNLOAD
);
359 /* CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE +10, */
361 /* CURLINFO_HEADER_SIZE = CURLINFO_LONG +11, */
363 /* CURLINFO_REQUEST_SIZE = CURLINFO_LONG +12, */
365 /* CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG +13, */
366 CASE(SSL_VERIFYRESULT
);
367 /* CURLINFO_FILETIME = CURLINFO_LONG +14, */
369 /* CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE +15, */
370 CASE(CONTENT_LENGTH_DOWNLOAD
);
371 /* CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE +16, */
372 CASE(CONTENT_LENGTH_UPLOAD
);
373 /* CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE +17, */
374 CASE(STARTTRANSFER_TIME
);
375 /* CURLINFO_CONTENT_TYPE = CURLINFO_STRING +18, */
377 /* CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE +19, */
379 /* CURLINFO_REDIRECT_COUNT = CURLINFO_LONG +20, */
380 CASE(REDIRECT_COUNT
);
381 /* CURLINFO_PRIVATE = CURLINFO_STRING +21, * (mike) /
383 /* CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG +22, */
384 CASE(HTTP_CONNECTCODE
);
385 #if LIBCURL_VERSION_NUM > 0x070a07
386 /* CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG +23, */
387 CASE(HTTPAUTH_AVAIL
);
388 /* CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG +24, */
389 CASE(PROXYAUTH_AVAIL
);
397 /* {{{ static inline void http_curl_getinfo_ex(CURL, CURLINFO, zval *) */
398 static inline void _http_curl_getinfo_ex(CURL
*ch
, CURLINFO i
, zval
*array TSRMLS_DC
)
401 if (key
= http_curl_getinfoname(i
)) {
402 switch (i
& ~CURLINFO_MASK
)
404 case CURLINFO_STRING
:
407 if (CURLE_OK
== curl_easy_getinfo(ch
, i
, &c
)) {
408 add_assoc_string(array
, key
, c
? c
: "", 1);
413 case CURLINFO_DOUBLE
:
416 if (CURLE_OK
== curl_easy_getinfo(ch
, i
, &d
)) {
417 add_assoc_double(array
, key
, d
);
425 if (CURLE_OK
== curl_easy_getinfo(ch
, i
, &l
)) {
426 add_assoc_long(array
, key
, l
);
435 /* {{{ static inline http_curl_getinfo(CURL, HashTable *) */
436 static inline void _http_curl_getinfo(CURL
*ch
, HashTable
*info TSRMLS_DC
)
439 Z_ARRVAL(array
) = info
;
441 #define INFO(I) http_curl_getinfo_ex(ch, CURLINFO_ ##I , &array)
442 /* CURLINFO_EFFECTIVE_URL = CURLINFO_STRING +1, */
444 #if LIBCURL_VERSION_NUM > 0x070a06
445 /* CURLINFO_RESPONSE_CODE = CURLINFO_LONG +2, */
450 /* CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE +3, */
452 /* CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE +4, */
453 INFO(NAMELOOKUP_TIME
);
454 /* CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE +5, */
456 /* CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE +6, */
457 INFO(PRETRANSFER_TIME
);
458 /* CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE +7, */
460 /* CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE +8, */
462 /* CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE +9, */
463 INFO(SPEED_DOWNLOAD
);
464 /* CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE +10, */
466 /* CURLINFO_HEADER_SIZE = CURLINFO_LONG +11, */
468 /* CURLINFO_REQUEST_SIZE = CURLINFO_LONG +12, */
470 /* CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG +13, */
471 INFO(SSL_VERIFYRESULT
);
472 /* CURLINFO_FILETIME = CURLINFO_LONG +14, */
474 /* CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE +15, */
475 INFO(CONTENT_LENGTH_DOWNLOAD
);
476 /* CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE +16, */
477 INFO(CONTENT_LENGTH_UPLOAD
);
478 /* CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE +17, */
479 INFO(STARTTRANSFER_TIME
);
480 /* CURLINFO_CONTENT_TYPE = CURLINFO_STRING +18, */
482 /* CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE +19, */
484 /* CURLINFO_REDIRECT_COUNT = CURLINFO_LONG +20, */
485 INFO(REDIRECT_COUNT
);
486 /* CURLINFO_PRIVATE = CURLINFO_STRING +21, */
488 /* CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG +22, */
489 INFO(HTTP_CONNECTCODE
);
490 #if LIBCURL_VERSION_NUM > 0x070a07
491 /* CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG +23, */
492 INFO(HTTPAUTH_AVAIL
);
493 /* CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG +24, */
494 INFO(PROXYAUTH_AVAIL
);
502 /* {{{ STATUS http_get(char *, HashTable *, HashTable *, char **, size_t *) */
503 PHP_HTTP_API STATUS
_http_get(const char *URL
, HashTable
*options
,
504 HashTable
*info
, char **data
, size_t *data_len TSRMLS_DC
)
507 CURL
*ch
= curl_easy_init();
510 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not initialize curl");
514 rs
= http_get_ex(ch
, URL
, options
, info
, data
, data_len
);
515 curl_easy_cleanup(ch
);
520 /* {{{ STATUS http_get_ex(CURL *, char *, HashTable *, HashTable *, char **, size_t *) */
521 PHP_HTTP_API STATUS
_http_get_ex(CURL
*ch
, const char *URL
, HashTable
*options
,
522 HashTable
*info
, char **data
, size_t *data_len TSRMLS_DC
)
525 http_curl_setopts(ch
, URL
, options
);
526 curl_easy_setopt(ch
, CURLOPT_NOBODY
, 0);
527 curl_easy_setopt(ch
, CURLOPT_POST
, 0);
529 if (CURLE_OK
!= curl_easy_perform(ch
)) {
531 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not perform request");
535 http_curl_getinfo(ch
, info
);
537 http_curl_movebuf(data
, data_len
);
541 /* {{{ STATUS http_head(char *, HashTable *, HashTable *, char **data, size_t *) */
542 PHP_HTTP_API STATUS
_http_head(const char *URL
, HashTable
*options
,
543 HashTable
*info
, char **data
, size_t *data_len TSRMLS_DC
)
546 CURL
*ch
= curl_easy_init();
549 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not initialize curl");
553 rs
= http_head_ex(ch
, URL
, options
, info
, data
, data_len
);
554 curl_easy_cleanup(ch
);
559 /* {{{ STATUS http_head_ex(CURL *, char *, HashTable *, HashTable *, char **data, size_t *) */
560 PHP_HTTP_API STATUS
_http_head_ex(CURL
*ch
, const char *URL
, HashTable
*options
,
561 HashTable
*info
, char **data
, size_t *data_len TSRMLS_DC
)
564 http_curl_setopts(ch
, URL
, options
);
565 curl_easy_setopt(ch
, CURLOPT_NOBODY
, 1);
566 curl_easy_setopt(ch
, CURLOPT_POST
, 0);
568 if (CURLE_OK
!= curl_easy_perform(ch
)) {
570 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not perform request");
574 http_curl_getinfo(ch
, info
);
576 http_curl_movebuf(data
, data_len
);
580 /* {{{ STATUS http_post_data(char *, char *, size_t, HashTable *, HashTable *, char **, size_t *) */
581 PHP_HTTP_API STATUS
_http_post_data(const char *URL
, char *postdata
,
582 size_t postdata_len
, HashTable
*options
, HashTable
*info
, char **data
,
583 size_t *data_len TSRMLS_DC
)
586 CURL
*ch
= curl_easy_init();
589 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not initialize curl");
592 rs
= http_post_data_ex(ch
, URL
, postdata
, postdata_len
, options
, info
, data
, data_len
);
593 curl_easy_cleanup(ch
);
598 /* {{{ STATUS http_post_data_ex(CURL *, char *, char *, size_t, HashTable *, HashTable *, char **, size_t *) */
599 PHP_HTTP_API STATUS
_http_post_data_ex(CURL
*ch
, const char *URL
, char *postdata
,
600 size_t postdata_len
, HashTable
*options
, HashTable
*info
, char **data
,
601 size_t *data_len TSRMLS_DC
)
604 http_curl_setopts(ch
, URL
, options
);
605 curl_easy_setopt(ch
, CURLOPT_POST
, 1);
606 curl_easy_setopt(ch
, CURLOPT_POSTFIELDS
, postdata
);
607 curl_easy_setopt(ch
, CURLOPT_POSTFIELDSIZE
, postdata_len
);
609 if (CURLE_OK
!= curl_easy_perform(ch
)) {
611 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not perform request");
615 http_curl_getinfo(ch
, info
);
617 http_curl_movebuf(data
, data_len
);
622 /* {{{ STATUS http_post_array_ex(CURL *, char *, HashTable *, HashTable *, HashTable *, char **, size_t *) */
623 PHP_HTTP_API STATUS
_http_post_array_ex(CURL
*ch
, const char *URL
, HashTable
*postarray
,
624 HashTable
*options
, HashTable
*info
, char **data
, size_t *data_len TSRMLS_DC
)
626 smart_str qstr
= {0};
629 HTTP_URL_ARGSEP_OVERRIDE
;
630 if (php_url_encode_hash_ex(postarray
, &qstr
, NULL
,0,NULL
,0,NULL
,0,NULL TSRMLS_CC
) != SUCCESS
) {
634 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not encode post data");
635 HTTP_URL_ARGSEP_RESTORE
;
639 HTTP_URL_ARGSEP_RESTORE
;
642 status
= http_post_data_ex(ch
, URL
, qstr
.c
, qstr
.len
, options
, info
, data
, data_len
);
644 status
= http_post_data(URL
, qstr
.c
, qstr
.len
, options
, info
, data
, data_len
);
654 /* {{{ STATUS http_post_curldata_ex(CURL *, char *, curl_httppost *, HashTable *, HashTable *, char **, size_t *) */
655 PHP_HTTP_API STATUS
_http_post_curldata_ex(CURL
*ch
, const char *URL
,
656 struct curl_httppost
*curldata
, HashTable
*options
, HashTable
*info
,
657 char **data
, size_t *data_len TSRMLS_DC
)
660 http_curl_setopts(ch
, URL
, options
);
661 curl_easy_setopt(ch
, CURLOPT_POST
, 1);
662 curl_easy_setopt(ch
, CURLOPT_HTTPPOST
, curldata
);
664 if (CURLE_OK
!= curl_easy_perform(ch
)) {
666 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not perform request");
670 http_curl_getinfo(ch
, info
);
672 http_curl_movebuf(data
, data_len
);
682 * vim600: noet sw=4 ts=4 fdm=marker
683 * vim<600: noet sw=4 ts=4