* Added request options:
[m6w6/ext-http] / http_request_object.c
index 1b2a543bc5dd803d4d63c87b7511174e3fc96f19..09c43a56ae1a527ef59df29fe07057930e601f79 100644 (file)
@@ -81,11 +81,10 @@ HTTP_BEGIN_ARGS(addCookies, 1)
 HTTP_END_ARGS;
 
 HTTP_EMPTY_ARGS(enableCookies);
-#if HTTP_CURL_VERSION(7,14,1)
 HTTP_BEGIN_ARGS(resetCookies, 0)
        HTTP_ARG_VAL(session_only, 0)
 HTTP_END_ARGS;
-#endif
+HTTP_EMPTY_ARGS(flushCookies);
 
 HTTP_EMPTY_ARGS(getUrl);
 HTTP_BEGIN_ARGS(setUrl, 1)
@@ -242,7 +241,7 @@ HTTP_BEGIN_ARGS(methodExists, 1)
        HTTP_ARG_VAL(method, 0)
 HTTP_END_ARGS;
 
-#if defined(HAVE_CURL_GETFORMDATA) || defined(HAVE_CURL_FORMGET)
+#ifdef HAVE_CURL_FORMGET
 HTTP_BEGIN_ARGS(encodeBody, 2)
        HTTP_ARG_VAL(fields, 0)
        HTTP_ARG_VAL(files, 0)
@@ -269,9 +268,8 @@ zend_function_entry http_request_object_fe[] = {
        HTTP_REQUEST_ME(setCookies, ZEND_ACC_PUBLIC)
 
        HTTP_REQUEST_ME(enableCookies, ZEND_ACC_PUBLIC)
-#if HTTP_CURL_VERSION(7,14,1)
        HTTP_REQUEST_ME(resetCookies, ZEND_ACC_PUBLIC)
-#endif
+       HTTP_REQUEST_ME(flushCookies, ZEND_ACC_PUBLIC)
 
        HTTP_REQUEST_ME(setMethod, ZEND_ACC_PUBLIC)
        HTTP_REQUEST_ME(getMethod, ZEND_ACC_PUBLIC)
@@ -338,7 +336,7 @@ zend_function_entry http_request_object_fe[] = {
        HTTP_REQUEST_ALIAS(methodUnregister, http_request_method_unregister)
        HTTP_REQUEST_ALIAS(methodName, http_request_method_name)
        HTTP_REQUEST_ALIAS(methodExists, http_request_method_exists)
-#if defined(HAVE_CURL_GETFORMDATA) || defined(HAVE_CURL_FORMGET)
+#ifdef HAVE_CURL_FORMGET
        HTTP_REQUEST_ALIAS(encodeBody, http_request_body_encode)
 #endif
        EMPTY_FUNCTION_ENTRY
@@ -431,6 +429,9 @@ PHP_MINIT_FUNCTION(http_request_object)
        */
        zend_declare_class_constant_long(THIS_CE, ZEND_STRS("AUTH_BASIC")-1, CURLAUTH_BASIC TSRMLS_CC);
        zend_declare_class_constant_long(THIS_CE, ZEND_STRS("AUTH_DIGEST")-1, CURLAUTH_DIGEST TSRMLS_CC);
+#if HTTP_CURL_VERSION(7,19,3)
+       zend_declare_class_constant_long(THIS_CE, ZEND_STRS("AUTH_DIGEST_IE")-1, CURLAUTH_DIGEST_IE TSRMLS_CC);
+#endif
        zend_declare_class_constant_long(THIS_CE, ZEND_STRS("AUTH_NTLM")-1, CURLAUTH_NTLM TSRMLS_CC);
        zend_declare_class_constant_long(THIS_CE, ZEND_STRS("AUTH_GSSNEG")-1, CURLAUTH_GSSNEGOTIATE TSRMLS_CC);
        zend_declare_class_constant_long(THIS_CE, ZEND_STRS("AUTH_ANY")-1, CURLAUTH_ANY TSRMLS_CC);
@@ -441,8 +442,15 @@ PHP_MINIT_FUNCTION(http_request_object)
 #      if HTTP_CURL_VERSION(7,15,2)
        zend_declare_class_constant_long(THIS_CE, ZEND_STRS("PROXY_SOCKS4")-1, CURLPROXY_SOCKS4 TSRMLS_CC);
 #      endif
+#if HTTP_CURL_VERSION(7,18,0)
+       zend_declare_class_constant_long(THIS_CE, ZEND_STRS("PROXY_SOCKS4A")-1, CURLPROXY_SOCKS5 TSRMLS_CC);
+       zend_declare_class_constant_long(THIS_CE, ZEND_STRS("PROXY_SOCKS5_HOSTNAME")-1, CURLPROXY_SOCKS5 TSRMLS_CC);
+#endif
        zend_declare_class_constant_long(THIS_CE, ZEND_STRS("PROXY_SOCKS5")-1, CURLPROXY_SOCKS5 TSRMLS_CC);
        zend_declare_class_constant_long(THIS_CE, ZEND_STRS("PROXY_HTTP")-1, CURLPROXY_HTTP TSRMLS_CC);
+#      if HTTP_CURL_VERSION(7,19,4)
+       zend_declare_class_constant_long(THIS_CE, ZEND_STRS("PROXY_HTTP_1_0")-1, CURLPROXY_HTTP_1_0 TSRMLS_CC);
+#      endif
 #endif /* WONKY */
        
        return SUCCESS;
@@ -551,12 +559,16 @@ static inline void _http_request_object_check_request_content_type(zval *this_pt
 STATUS _http_request_object_requesthandler(http_request_object *obj, zval *this_ptr TSRMLS_DC)
 {
        STATUS status = SUCCESS;
+       char *url = http_absolute_url(Z_STRVAL_P(zend_read_property(THIS_CE, getThis(), ZEND_STRS("url")-1, 0 TSRMLS_CC)));
 
+       if (!url) {
+               return FAILURE;
+       }
+       
        http_request_reset(obj->request);
+       obj->request->url = url;
        HTTP_CHECK_CURL_INIT(obj->request->ch, http_curl_init(obj->request), return FAILURE);
        
-       obj->request->url = http_absolute_url(Z_STRVAL_P(zend_read_property(THIS_CE, getThis(), ZEND_STRS("url")-1, 0 TSRMLS_CC)));
-       
        switch (obj->request->meth = Z_LVAL_P(zend_read_property(THIS_CE, getThis(), ZEND_STRS("method")-1, 0 TSRMLS_CC)))
        {
                case HTTP_GET:
@@ -635,7 +647,7 @@ STATUS _http_request_object_requesthandler(http_request_object *obj, zval *this_
                        
                        if (    (Z_TYPE_P(options) != IS_ARRAY)
                                ||      (SUCCESS != zend_hash_find(Z_ARRVAL_P(options), "onprogress", sizeof("onprogress"), (void *) &entry)
-                               ||      (!zval_is_true(*entry)))) {
+                               ||      (!IS_CALLABLE(*entry, 0, NULL)))) {
                                MAKE_STD_ZVAL(pcb);
                                array_init(pcb);
                                ZVAL_ADDREF(getThis());
@@ -670,7 +682,7 @@ STATUS _http_request_object_responsehandler(http_request_object *obj, zval *this
        if ((msg = http_message_parse(PHPSTR_VAL(&obj->request->conv.response), PHPSTR_LEN(&obj->request->conv.response)))) {
                zval *message;
 
-               if (zval_is_true(zend_read_property(THIS_CE, getThis(), ZEND_STRS("recordHistory")-1, 0 TSRMLS_CC))) {
+               if (i_zend_is_true(zend_read_property(THIS_CE, getThis(), ZEND_STRS("recordHistory")-1, 0 TSRMLS_CC))) {
                        zval *hist, *history = zend_read_property(THIS_CE, getThis(), ZEND_STRS("history")-1, 0 TSRMLS_CC);
                        http_message *response = http_message_parse(PHPSTR_VAL(&obj->request->conv.response), PHPSTR_LEN(&obj->request->conv.response));
                        http_message *request = http_message_parse(PHPSTR_VAL(&obj->request->conv.request), PHPSTR_LEN(&obj->request->conv.request));
@@ -706,7 +718,7 @@ STATUS _http_request_object_responsehandler(http_request_object *obj, zval *this
                zend_update_property_string(THIS_CE, getThis(), ZEND_STRS("responseStatus")-1, "" TSRMLS_CC);
                
                /* append request message to history */
-               if (zval_is_true(zend_read_property(THIS_CE, getThis(), ZEND_STRS("recordHistory")-1, 0 TSRMLS_CC))) {
+               if (i_zend_is_true(zend_read_property(THIS_CE, getThis(), ZEND_STRS("recordHistory")-1, 0 TSRMLS_CC))) {
                        http_message *request;
                        
                        if ((request = http_message_parse(PHPSTR_VAL(&obj->request->conv.request), PHPSTR_LEN(&obj->request->conv.request)))) {
@@ -743,7 +755,7 @@ STATUS _http_request_object_responsehandler(http_request_object *obj, zval *this
 
 static int apply_pretty_key(void *pDest, int num_args, va_list args, zend_hash_key *hash_key)
 {
-       if (hash_key->nKeyLength > 1) {
+       if (hash_key->arKey && hash_key->nKeyLength > 1) {
                hash_key->h = zend_hash_func(pretty_key(hash_key->arKey, hash_key->nKeyLength - 1, 1, 0), hash_key->nKeyLength);
        }
        return ZEND_HASH_APPLY_KEEP;
@@ -779,7 +791,7 @@ static inline void _http_request_object_set_options_subr(INTERNAL_FUNCTION_PARAM
                }
        } else if (opts) {
                if (prettify_keys) {
-                       zend_hash_apply_with_arguments(Z_ARRVAL_P(opts), apply_pretty_key, 0);
+                       zend_hash_apply_with_arguments(Z_ARRVAL_P(opts) HTTP_ZAPI_HASH_TSRMLS_CC, apply_pretty_key, 0, NULL);
                }
                ZVAL_ADDREF(opts);
                add_assoc_zval_ex(new_opts, key, len, opts);
@@ -893,26 +905,35 @@ PHP_METHOD(HttpRequest, setOptions)
        /* some options need extra attention -- thus cannot use array_merge() directly */
        FOREACH_KEYVAL(pos, opts, key, opt) {
                if (key.type == HASH_KEY_IS_STRING) {
-                       if (!strcmp(key.str, "headers")) {
+#define KEYMATCH(k, s) ((sizeof(s)==k.len) && !strcasecmp(k.str, s))
+                       if (KEYMATCH(key, "headers")) {
                                zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "addheaders", NULL, *opt);
-                       } else if (!strcmp(key.str, "cookies")) {
+                       } else if (KEYMATCH(key, "cookies")) {
                                zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "addcookies", NULL, *opt);
-                       } else if (!strcmp(key.str, "ssl")) {
+                       } else if (KEYMATCH(key, "ssl")) {
                                zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "addssloptions", NULL, *opt);
-                       } else if ((!strcasecmp(key.str, "url")) || (!strcasecmp(key.str, "uri"))) {
+                       } else if (KEYMATCH(key, "url") || KEYMATCH(key, "uri")) {
                                zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "seturl", NULL, *opt);
-                       } else if (!strcmp(key.str, "method")) {
+                       } else if (KEYMATCH(key, "method")) {
                                zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "setmethod", NULL, *opt);
-#if HTTP_CURL_VERSION(7,14,1)
-                       } else if (!strcmp(key.str, "resetcookies")) {
+                       } else if (KEYMATCH(key, "flushcookies")) {
                                getObject(http_request_object, obj);
-                               http_request_reset_cookies(obj->request, 0);
-#endif
-                       } else if (!strcmp(key.str, "enablecookies")) {
+                               if (i_zend_is_true(*opt)) {
+                                       http_request_flush_cookies(obj->request);
+                               }
+                       } else if (KEYMATCH(key, "resetcookies")) {
+                               getObject(http_request_object, obj);
+                               http_request_reset_cookies(obj->request, (zend_bool) i_zend_is_true(*opt));
+                       } else if (KEYMATCH(key, "enablecookies")) {
                                getObject(http_request_object, obj);
                                http_request_enable_cookies(obj->request);
-                       } else if (!strcasecmp(key.str, "recordHistory")) {
-                               zend_update_property_bool(THIS_CE, getThis(), ZEND_STRS("recordHistory")-1, 1 TSRMLS_CC);
+                       } else if (KEYMATCH(key, "recordHistory")) {
+                               zend_update_property(THIS_CE, getThis(), ZEND_STRS("recordHistory")-1, *opt TSRMLS_CC);
+                       } else if (Z_TYPE_PP(opt) == IS_NULL) {
+                               old_opts = zend_read_property(THIS_CE, getThis(), ZEND_STRS("options")-1, 0 TSRMLS_CC);
+                               if (Z_TYPE_P(old_opts) == IS_ARRAY) {
+                                       zend_hash_del(Z_ARRVAL_P(old_opts), key.str, key.len);
+                               }
                        } else {
                                ZVAL_ADDREF(*opt);
                                add_assoc_zval_ex(add_opts, key.str, key.len, *opt);
@@ -1042,6 +1063,17 @@ PHP_METHOD(HttpRequest, resetCookies)
 }
 /* }}} */
 
+/* {{{ proto bool HttpRequest::flushCookies()
+       Flush internal cookies to the cookiestore file */
+PHP_METHOD(HttpRequest, flushCookies)
+{
+       NO_ARGS {
+               getObject(http_request_object, obj);
+               RETURN_SUCCESS(http_request_flush_cookies(obj->request));
+       }
+}
+/* }}} */
+
 /* {{{ proto bool HttpRequest::setUrl(string url)
        Set the request URL. */
 PHP_METHOD(HttpRequest, setUrl)
@@ -1150,13 +1182,10 @@ PHP_METHOD(HttpRequest, setQueryData)
                zend_update_property_string(THIS_CE, getThis(), ZEND_STRS("queryData")-1, query_data TSRMLS_CC);
                efree(query_data);
        } else {
-               zval *orig = qdata;
+               zval *data = http_zsep(IS_STRING, qdata);
                
-               convert_to_string_ex(&qdata);
-               zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("queryData")-1, Z_STRVAL_P(qdata), Z_STRLEN_P(qdata) TSRMLS_CC);
-               if (orig != qdata) {
-                       zval_ptr_dtor(&qdata);
-               }
+               zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("queryData")-1, Z_STRVAL_P(data), Z_STRLEN_P(data) TSRMLS_CC);
+               zval_ptr_dtor(&data);
        }
        RETURN_TRUE;
 }
@@ -1291,14 +1320,14 @@ PHP_METHOD(HttpRequest, addBody)
        }
        
        if (data_len) {
-               zval *data = zend_read_property(THIS_CE, getThis(), ZEND_STRS("rrequestBody")-1, 0 TSRMLS_CC);
+               zval *data = zend_read_property(THIS_CE, getThis(), ZEND_STRS("requestBody")-1, 0 TSRMLS_CC);
                
                if (Z_STRLEN_P(data)) {
                        Z_STRVAL_P(data) = erealloc(Z_STRVAL_P(data), (Z_STRLEN_P(data) += data_len) + 1);
                        Z_STRVAL_P(data)[Z_STRLEN_P(data)] = '\0';
                        memcpy(Z_STRVAL_P(data) + Z_STRLEN_P(data) - data_len, raw_data, data_len);
                } else {
-                       zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("putData")-1, raw_data, data_len TSRMLS_CC);
+                       zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("requestBody")-1, raw_data, data_len TSRMLS_CC);
                }
        }
        
@@ -1561,10 +1590,9 @@ PHP_METHOD(HttpRequest, getResponseCookies)
                                if (allowed_extras_array) {
                                        allowed_extras = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(allowed_extras_array)) + 1, sizeof(char *));
                                        FOREACH_VAL(pos, allowed_extras_array, entry) {
-                                               ZVAL_ADDREF(*entry);
-                                               convert_to_string_ex(entry);
-                                               allowed_extras[i++] = estrndup(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry));
-                                               zval_ptr_dtor(entry);
+                                               zval *data = http_zsep(IS_STRING, *entry);
+                                               allowed_extras[i++] = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data));
+                                               zval_ptr_dtor(&data);
                                        }
                                }
                                
@@ -1576,9 +1604,9 @@ PHP_METHOD(HttpRequest, getResponseCookies)
                                                        zval **single_header;
                                                        
                                                        FOREACH_VAL(pos2, *header, single_header) {
-                                                               ZVAL_ADDREF(*single_header);
-                                                               convert_to_string_ex(single_header);
-                                                               if (http_parse_cookie_ex(&list, Z_STRVAL_PP(single_header), flags, allowed_extras)) {
+                                                               zval *data = http_zsep(IS_STRING, *single_header);
+                                                               
+                                                               if (http_parse_cookie_ex(&list, Z_STRVAL_P(data), flags, allowed_extras)) {
                                                                        zval *cookie;
                                                                        
                                                                        MAKE_STD_ZVAL(cookie);
@@ -1587,12 +1615,11 @@ PHP_METHOD(HttpRequest, getResponseCookies)
                                                                        add_next_index_zval(return_value, cookie);
                                                                        http_cookie_list_dtor(&list);
                                                                }
-                                                               zval_ptr_dtor(single_header);
+                                                               zval_ptr_dtor(&data);
                                                        }
                                                } else {
-                                                       ZVAL_ADDREF(*header);
-                                                       convert_to_string_ex(header);
-                                                       if (http_parse_cookie_ex(&list, Z_STRVAL_PP(header), flags, allowed_extras)) {
+                                                       zval *data = http_zsep(IS_STRING, *header);
+                                                       if (http_parse_cookie_ex(&list, Z_STRVAL_P(data), flags, allowed_extras)) {
                                                                zval *cookie;
                                                                
                                                                MAKE_STD_ZVAL(cookie);
@@ -1601,7 +1628,7 @@ PHP_METHOD(HttpRequest, getResponseCookies)
                                                                add_next_index_zval(return_value, cookie);
                                                                http_cookie_list_dtor(&list);
                                                        }
-                                                       zval_ptr_dtor(header);
+                                                       zval_ptr_dtor(&data);
                                                }
                                        }
                                }