#include "phpstr/phpstr.h"
-#ifdef HTTP_HAVE_CURL
-#ifdef ZEND_ENGINE_2
-static
-ZEND_BEGIN_ARG_INFO(http_request_info_ref_3, 0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(1)
-ZEND_END_ARG_INFO();
-
-static
-ZEND_BEGIN_ARG_INFO(http_request_info_ref_4, 0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(1)
-ZEND_END_ARG_INFO();
-
-static
-ZEND_BEGIN_ARG_INFO(http_request_info_ref_5, 0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(1)
-ZEND_END_ARG_INFO();
-#else
-static unsigned char http_request_info_ref_3[] = {3, BYREF_NONE, BYREF_NONE, BYREF_FORCE};
-static unsigned char http_request_info_ref_4[] = {4, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE};
-static unsigned char http_request_info_ref_5[] = {5, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE};
-#endif /* ZEND_ENGINE_2 */
-#endif /* HTTP_HAVE_CURL */
-
-ZEND_DECLARE_MODULE_GLOBALS(http)
+ZEND_DECLARE_MODULE_GLOBALS(http);
+HTTP_DECLARE_ARG_PASS_INFO();
#ifdef COMPILE_DL_HTTP
ZEND_GET_MODULE(http)
PHP_FE(http_get_request_headers, NULL)
PHP_FE(http_match_request_header, NULL)
#ifdef HTTP_HAVE_CURL
- PHP_FE(http_get, http_request_info_ref_3)
- PHP_FE(http_head, http_request_info_ref_3)
- PHP_FE(http_post_data, http_request_info_ref_4)
- PHP_FE(http_post_fields, http_request_info_ref_5)
- PHP_FE(http_put_file, http_request_info_ref_4)
- PHP_FE(http_put_stream, http_request_info_ref_4)
+ PHP_FE(http_get, http_arg_pass_ref_3)
+ PHP_FE(http_head, http_arg_pass_ref_3)
+ PHP_FE(http_post_data, http_arg_pass_ref_4)
+ PHP_FE(http_post_fields, http_arg_pass_ref_5)
+ PHP_FE(http_put_file, http_arg_pass_ref_4)
+ PHP_FE(http_put_stream, http_arg_pass_ref_4)
PHP_FE(http_request_method_register, NULL)
PHP_FE(http_request_method_unregister, NULL)
PHP_FE(http_request_method_exists, NULL)
int http_module_number;
-#ifdef HTTP_HAVE_CURL
-# ifdef HTTP_CURL_USE_ZEND_MM
-static void http_curl_free(void *p) { efree(p); }
-static char *http_curl_strdup(const char *p) { return estrdup(p); }
-static void *http_curl_malloc(size_t s) { return emalloc(s); }
-static void *http_curl_realloc(void *p, size_t s) { return erealloc(p, s); }
-static void *http_curl_calloc(size_t n, size_t s) { return ecalloc(n, s); }
-# endif /* HTTP_CURL_USE_ZEND_MM */
-static void http_curl_freestr(void *s) { efree(*(char **)s); }
-#endif /* HTTP_HAVE_CURL */
-
/* {{{ http_globals */
static inline void http_globals_init(zend_http_globals *G)
{
G->send.buffer_size = HTTP_SENDBUF_SIZE;
zend_hash_init(&G->request.methods.custom, 0, NULL, ZVAL_PTR_DTOR, 0);
#ifdef HTTP_HAVE_CURL
- zend_llist_init(&G->request.curl.copies, sizeof(char *), http_curl_freestr, 0);
+ zend_llist_init(&G->request.copies.strings, sizeof(char *), http_request_data_free_string, 0);
+ zend_llist_init(&G->request.copies.slists, sizeof(struct curl_slist *), http_request_data_free_slist, 0);
#endif
}
+
static inline void http_globals_free(zend_http_globals *G)
{
STR_FREE(G->send.content_type);
STR_FREE(G->send.unquoted_etag);
zend_hash_destroy(&G->request.methods.custom);
- zend_llist_clean(&G->request.curl.copies);
+ zend_llist_clean(&G->request.copies.strings);
+ zend_llist_clean(&G->request.copies.slists);
}
/* }}} */
REGISTER_INI_ENTRIES();
#ifdef HTTP_HAVE_CURL
-# ifdef HTTP_CURL_USE_ZEND_MM
- if (CURLE_OK != curl_global_init_mem(CURL_GLOBAL_ALL,
- http_curl_malloc,
- http_curl_free,
- http_curl_realloc,
- http_curl_strdup,
- http_curl_calloc)) {
+ if (SUCCESS != http_request_global_init()) {
return FAILURE;
}
-# endif /* HTTP_CURL_USE_ZEND_MM */
#endif /* HTTP_HAVE_CURL */
#ifdef ZEND_ENGINE_2
php_info_print_table_header(2, "Functionality", "Availability");
php_info_print_table_row(2, "Miscellaneous Utilities:", HTTP_FUNC_AVAIL("HttpUtil, HttpMessage"));
php_info_print_table_row(2, "Extended HTTP Responses:", HTTP_FUNC_AVAIL("HttpResponse"));
- php_info_print_table_row(2, "Extended HTTP Requests:", HTTP_CURL_AVAIL("HttpRequest"));
+ php_info_print_table_row(2, "Extended HTTP Requests:", HTTP_CURL_AVAIL("HttpRequest, HttpRequestPool"));
}
php_info_print_table_end();
#include "php_http_requestpool_object.h"
#include "php_http_url_api.h"
+#ifndef HTTP_CURL_USE_ZEND_MM
+# define HTTP_CURL_USE_ZEND_MM 0
+#endif
+
ZEND_EXTERN_MODULE_GLOBALS(http)
#if LIBCURL_VERSION_NUM < 0x070c00
{ \
char *c; \
if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_ ##I, &c)) { \
- add_assoc_string(&array, pretty_key(http_request_copystr(#X), sizeof(#X)-1, 0, 0), c ? c : "", 1); \
+ add_assoc_string(&array, pretty_key(http_request_data_copy(COPY_STRING, #X), sizeof(#X)-1, 0, 0), c ? c : "", 1); \
} \
} \
break; \
{ \
double d; \
if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_ ##I, &d)) { \
- add_assoc_double(&array, pretty_key(http_request_copystr(#X), sizeof(#X)-1, 0, 0), d); \
+ add_assoc_double(&array, pretty_key(http_request_data_copy(COPY_STRING, #X), sizeof(#X)-1, 0, 0), d); \
} \
} \
break; \
{ \
long l; \
if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_ ##I, &l)) { \
- add_assoc_long(&array, pretty_key(http_request_copystr(#X), sizeof(#X)-1, 0, 0), l); \
+ add_assoc_long(&array, pretty_key(http_request_data_copy(COPY_STRING, #X), sizeof(#X)-1, 0, 0), l); \
} \
} \
break; \
#define HTTP_CURL_OPT_STRING_EX(keyname, optname) \
if (!strcasecmp(key, #keyname)) { \
convert_to_string_ex(param); \
- HTTP_CURL_OPT(optname, http_request_copystr(Z_STRVAL_PP(param))); \
+ HTTP_CURL_OPT(optname, http_request_data_copy(COPY_STRING, Z_STRVAL_PP(param))); \
key = NULL; \
continue; \
}
static inline STATUS http_request_pool_select(http_request_pool *pool);
static inline void http_request_pool_perform(http_request_pool *pool);
-/* {{{ char *http_request_copystr(char *) */
-PHP_HTTP_API char *_http_request_copystr(const char *str TSRMLS_DC)
+#if HTTP_CURL_USE_ZEND_MM
+static void http_curl_free(void *p) { efree(p); }
+static char *http_curl_strdup(const char *p) { return estrdup(p); }
+static void *http_curl_malloc(size_t s) { return emalloc(s); }
+static void *http_curl_realloc(void *p, size_t s) { return erealloc(p, s); }
+static void *http_curl_calloc(size_t n, size_t s) { return ecalloc(n, s); }
+#endif
+
+/* {{{ STATUS http_request_global_init() */
+STATUS _http_request_global_init(void)
+{
+#if HTTP_CURL_USE_ZEND_MM
+ if (CURLE_OK != curl_global_init_mem(CURL_GLOBAL_ALL,
+ http_curl_malloc,
+ http_curl_free,
+ http_curl_realloc,
+ http_curl_strdup,
+ http_curl_calloc)) {
+ return FAILURE;
+ }
+#else
+ if (CURLE_OK != curl_global_init(CURL_GLOBAL_ALL)) {
+ return FAILURE;
+ }
+#endif
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ void *http_request_data_copy(int, void *) */
+void *_http_request_data_copy(int type, void *data TSRMLS_DC)
+{
+ switch (type)
+ {
+ case COPY_STRING:
+ {
+ char *new_str = estrdup((const char*) data);
+ zend_llist_add_element(&HTTP_G(request).copies.strings, &new_str);
+ return new_str;
+ }
+
+ case COPY_SLIST:
+ {
+ zend_llist_add_element(&HTTP_G(request).copies.slists, &data);
+ return data;
+ }
+
+ default:
+ {
+ return data;
+ }
+ }
+}
+/* }}} */
+
+/* {{{ void http_request_data_free_string(char **) */
+void _http_request_data_free_string(void *string)
+{
+ efree(*((char **)string));
+}
+/* }}} */
+
+/* {{{ void http_request_data_free_slist(struct curl_slist **) */
+void _http_request_data_free_slist(void *list)
{
- char *new_str = estrdup(str);
- zend_llist_add_element(&HTTP_G(request).curl.copies, &new_str);
- return new_str;
+ curl_slist_free_all(*((struct curl_slist **) list));
}
/* }}} */
/* set options */
if (url) {
- HTTP_CURL_OPT(URL, url);
+ HTTP_CURL_OPT(URL, http_request_data_copy(COPY_STRING, (void *) url));
}
if (response) {
/* proxy */
if (zoption = http_curl_getopt(options, "proxyhost", IS_STRING)) {
- HTTP_CURL_OPT(PROXY, http_request_copystr(Z_STRVAL_P(zoption)));
+ HTTP_CURL_OPT(PROXY, http_request_data_copy(COPY_STRING, Z_STRVAL_P(zoption)));
/* port */
if (zoption = http_curl_getopt(options, "proxyport", IS_LONG)) {
HTTP_CURL_OPT(PROXYPORT, Z_LVAL_P(zoption));
}
/* user:pass */
if (zoption = http_curl_getopt(options, "proxyauth", IS_STRING)) {
- HTTP_CURL_OPT(PROXYUSERPWD, http_request_copystr(Z_STRVAL_P(zoption)));
+ HTTP_CURL_OPT(PROXYUSERPWD, http_request_data_copy(COPY_STRING, Z_STRVAL_P(zoption)));
}
#if LIBCURL_VERSION_NUM >= 0x070a07
/* auth method */
/* outgoing interface */
if (zoption = http_curl_getopt(options, "interface", IS_STRING)) {
- HTTP_CURL_OPT(INTERFACE, http_request_copystr(Z_STRVAL_P(zoption)));
+ HTTP_CURL_OPT(INTERFACE, http_request_data_copy(COPY_STRING, Z_STRVAL_P(zoption)));
}
/* another port */
/* auth */
if (zoption = http_curl_getopt(options, "httpauth", IS_STRING)) {
- HTTP_CURL_OPT(USERPWD, http_request_copystr(Z_STRVAL_P(zoption)));
+ HTTP_CURL_OPT(USERPWD, http_request_data_copy(COPY_STRING, Z_STRVAL_P(zoption)));
}
#if LIBCURL_VERSION_NUM >= 0x070a06
if (zoption = http_curl_getopt(options, "httpauthtype", IS_LONG)) {
/* compress, empty string enables deflate and gzip */
if (zoption = http_curl_getopt(options, "compress", IS_BOOL)) {
if (Z_LVAL_P(zoption)) {
- HTTP_CURL_OPT(ENCODING, http_request_copystr(""));
+ HTTP_CURL_OPT(ENCODING, http_request_data_copy(COPY_STRING, ""));
}
}
/* referer */
if (zoption = http_curl_getopt(options, "referer", IS_STRING)) {
- HTTP_CURL_OPT(REFERER, http_request_copystr(Z_STRVAL_P(zoption)));
+ HTTP_CURL_OPT(REFERER, http_request_data_copy(COPY_STRING, Z_STRVAL_P(zoption)));
}
/* useragent, default "PECL::HTTP/version (PHP/version)" */
if (zoption = http_curl_getopt(options, "useragent", IS_STRING)) {
- HTTP_CURL_OPT(USERAGENT, http_request_copystr(Z_STRVAL_P(zoption)));
+ HTTP_CURL_OPT(USERAGENT, http_request_data_copy(COPY_STRING, Z_STRVAL_P(zoption)));
} else {
- HTTP_CURL_OPT(USERAGENT, "PECL::HTTP/" HTTP_PEXT_VERSION " (PHP/" PHP_VERSION ")");
+ HTTP_CURL_OPT(USERAGENT, http_request_data_copy(COPY_STRING, "PECL::HTTP/" HTTP_PEXT_VERSION " (PHP/" PHP_VERSION ")"));
}
/* additional headers, array('name' => 'value') */
if (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(zoption), (void **) &header_val)) {
char header[1024] = {0};
snprintf(header, 1023, "%s: %s", header_key, Z_STRVAL_PP(header_val));
- headers = curl_slist_append(headers, http_request_copystr(header));
+ headers = curl_slist_append(headers, http_request_data_copy(COPY_STRING, header));
}
/* reset */
}
if (headers) {
- HTTP_CURL_OPT(HTTPHEADER, headers);
+ HTTP_CURL_OPT(HTTPHEADER, http_request_data_copy(COPY_SLIST, headers));
}
+ } else {
+ HTTP_CURL_OPT(HTTPHEADER, NULL);
}
/* cookies, array('name' => 'value') */
if (qstr->used) {
phpstr_fix(qstr);
- HTTP_CURL_OPT(COOKIE, http_request_copystr(qstr->data));
+ HTTP_CURL_OPT(COOKIE, http_request_data_copy(COPY_STRING, qstr->data));
}
phpstr_free(qstr);
}
/* cookiestore */
if (zoption = http_curl_getopt(options, "cookiestore", IS_STRING)) {
- HTTP_CURL_OPT(COOKIEFILE, http_request_copystr(Z_STRVAL_P(zoption)));
- HTTP_CURL_OPT(COOKIEJAR, http_request_copystr(Z_STRVAL_P(zoption)));
+ HTTP_CURL_OPT(COOKIEFILE, http_request_data_copy(COPY_STRING, Z_STRVAL_P(zoption)));
+ HTTP_CURL_OPT(COOKIEJAR, http_request_data_copy(COPY_STRING, Z_STRVAL_P(zoption)));
}
/* resume */
{
zval *params_pass[4], params_local[4], retval;
HTTP_CURL_CALLBACK_DATA(data, zval *, func);
-
+
params_pass[0] = ¶ms_local[0];
params_pass[1] = ¶ms_local[1];
params_pass[2] = ¶ms_local[2];
}
strncat(request_uri, Z_STRVAL_P(qdata), HTTP_URI_MAXLEN - strlen(request_uri));
}
-
- uri = http_request_copystr(request_uri);
- efree(request_uri);
switch (Z_LVAL_P(meth))
{
case HTTP_GET:
case HTTP_HEAD:
body->type = -1;
- status = http_request_init(obj->ch, Z_LVAL_P(meth), uri, NULL, Z_ARRVAL_P(opts), &obj->response);
+ status = http_request_init(obj->ch, Z_LVAL_P(meth), request_uri, NULL, Z_ARRVAL_P(opts), &obj->response);
break;
case HTTP_PUT:
body->data = stream;
body->size = ssb.sb.st_size;
- status = http_request_init(obj->ch, HTTP_PUT, uri, body, Z_ARRVAL_P(opts), &obj->response);
+ status = http_request_init(obj->ch, HTTP_PUT, request_uri, body, Z_ARRVAL_P(opts), &obj->response);
} else {
status = FAILURE;
}
zval *fields = GET_PROP(obj, postFields), *files = GET_PROP(obj, postFiles);
if (SUCCESS == (status = http_request_body_fill(body, Z_ARRVAL_P(fields), Z_ARRVAL_P(files)))) {
- status = http_request_init(obj->ch, HTTP_POST, uri, body, Z_ARRVAL_P(opts), &obj->response);
+ status = http_request_init(obj->ch, HTTP_POST, request_uri, body, Z_ARRVAL_P(opts), &obj->response);
}
}
break;
break;
}
+ efree(request_uri);
return status;
}
STATUS _http_request_object_responsehandler(http_request_object *obj, zval *this_ptr, HashTable *info TSRMLS_DC)
{
http_message *msg;
-
+
phpstr_fix(&obj->response);
if (msg = http_message_parse(PHPSTR_VAL(&obj->response), PHPSTR_LEN(&obj->response))) {
#ifdef ZEND_ENGINE_2
-#ifdef HTTP_HAVE_CURL
-static
-ZEND_BEGIN_ARG_INFO(http_request_info_ref_3, 0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(1)
-ZEND_END_ARG_INFO();
-
-static
-ZEND_BEGIN_ARG_INFO(http_request_info_ref_4, 0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(1)
-ZEND_END_ARG_INFO();
-
-static
-ZEND_BEGIN_ARG_INFO(http_request_info_ref_5, 0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(0)
- ZEND_ARG_PASS_INFO(1)
-ZEND_END_ARG_INFO();
-#endif /* HTTP_HAVE_CURL */
+HTTP_DECLARE_ARG_PASS_INFO();
zend_class_entry *http_util_object_ce;
zend_function_entry http_util_object_fe[] = {
HTTP_STATIC_ME_ALIAS(parseHeaders, http_parse_headers, NULL)
HTTP_STATIC_ME_ALIAS(getRequestHeaders, http_get_request_headers, NULL)
#ifdef HTTP_HAVE_CURL
- HTTP_STATIC_ME_ALIAS(get, http_get, http_request_info_ref_3)
- HTTP_STATIC_ME_ALIAS(head, http_head, http_request_info_ref_3)
- HTTP_STATIC_ME_ALIAS(postData, http_post_data, http_request_info_ref_4)
- HTTP_STATIC_ME_ALIAS(postFields, http_post_fields, http_request_info_ref_5)
+ HTTP_STATIC_ME_ALIAS(get, http_get, http_arg_pass_ref_3)
+ HTTP_STATIC_ME_ALIAS(head, http_head, http_arg_pass_ref_3)
+ HTTP_STATIC_ME_ALIAS(postData, http_post_data, http_arg_pass_ref_4)
+ HTTP_STATIC_ME_ALIAS(postFields, http_post_fields, http_arg_pass_ref_5)
#endif /* HTTP_HAVE_CURL */
HTTP_STATIC_ME_ALIAS(authBasic, http_auth_basic, NULL)
HTTP_STATIC_ME_ALIAS(authBasicCallback, http_auth_basic_cb, NULL)
} methods;
#ifdef HTTP_HAVE_CURL
- struct _http_globals_request_curl {
- zend_llist copies;
+ struct _http_globlas_request_copies {
+ zend_llist strings;
+ zend_llist slists;
+ } copies;
# if LIBCURL_VERSION_NUM < 0x070c00
- char error[CURL_ERROR_SIZE + 1];
+ char error[CURL_ERROR_SIZE + 1];
# endif
- } curl;
#endif /* HTTP_HAVE_CURL */
} request;
int unfinished;
} http_request_pool;
-#define http_request_copystr(s) _http_request_copystr((s) TSRMLS_CC)
-PHP_HTTP_API char *_http_request_copystr(const char *string TSRMLS_DC);
+#define COPY_STRING 1
+#define COPY_SLIST 2
+#define http_request_data_copy(type, data) _http_request_data_copy((type), (data) TSRMLS_CC)
+extern void *_http_request_data_copy(int type, void *data TSRMLS_DC);
+#define http_request_data_free_string _http_request_data_free_string
+extern void _http_request_data_free_string(void *string);
+#define http_request_data_free_slist _http_request_data_free_slist
+extern void _http_request_data_free_slist(void *list);
+
+#define http_request_global_init _http_request_global_init
+extern STATUS _http_request_global_init(void);
#define http_request_method_name(m) _http_request_method_name((m) TSRMLS_CC)
PHP_HTTP_API const char *_http_request_method_name(http_request_method m TSRMLS_DC);
#define HTTP_E_URL 7L
#define HTTP_E_MSG 8L
+#ifdef HTTP_HAVE_CURL
+# ifdef ZEND_ENGINE_2
+# define HTTP_DECLARE_ARG_PASS_INFO() \
+ static \
+ ZEND_BEGIN_ARG_INFO(http_arg_pass_ref_3, 0) \
+ ZEND_ARG_PASS_INFO(0) \
+ ZEND_ARG_PASS_INFO(0) \
+ ZEND_ARG_PASS_INFO(1) \
+ ZEND_END_ARG_INFO(); \
+ \
+ static \
+ ZEND_BEGIN_ARG_INFO(http_arg_pass_ref_4, 0) \
+ ZEND_ARG_PASS_INFO(0) \
+ ZEND_ARG_PASS_INFO(0) \
+ ZEND_ARG_PASS_INFO(0) \
+ ZEND_ARG_PASS_INFO(1) \
+ ZEND_END_ARG_INFO(); \
+ \
+ static \
+ ZEND_BEGIN_ARG_INFO(http_arg_pass_ref_5, 0) \
+ ZEND_ARG_PASS_INFO(0) \
+ ZEND_ARG_PASS_INFO(0) \
+ ZEND_ARG_PASS_INFO(0) \
+ ZEND_ARG_PASS_INFO(0) \
+ ZEND_ARG_PASS_INFO(1) \
+ ZEND_END_ARG_INFO()
+# else
+# define HTTP_DECLARE_ARG_PASS_INFO() \
+ static unsigned char http_arg_pass_ref_3[] = {3, BYREF_NONE, BYREF_NONE, BYREF_FORCE}; \
+ static unsigned char http_arg_pass_ref_4[] = {4, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE}; \
+ static unsigned char http_arg_pass_ref_5[] = {5, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE}
+# endif /* ZEND_ENGINE_2 */
+#else
+# define HTTP_DECLARE_ARG_PASS_INFO()
+#endif /* HTTP_HAVE_CURL */
+
+
#endif /* PHP_HTTP_STD_DEFS_H */
/*