- start thinking about cloning
[m6w6/ext-http] / http_request_object.c
index 37e2a58bd75c031f3b8a11828ca75ecf647b2eac..459536a573fd9d427be7fb6bfe03480a47b7f807 100644 (file)
@@ -23,6 +23,8 @@
 
 #if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
 
+#include "zend_interfaces.h"
+
 #include "php_http_std_defs.h"
 #include "php_http_request_object.h"
 #include "php_http_request_api.h"
@@ -52,6 +54,7 @@ HTTP_EMPTY_ARGS(__destruct, 0);
 HTTP_BEGIN_ARGS(__construct, 0, 0)
        HTTP_ARG_VAL(url, 0)
        HTTP_ARG_VAL(method, 0)
+       HTTP_ARG_VAL(options, 0)
 HTTP_END_ARGS;
 
 HTTP_EMPTY_ARGS(getOptions, 0);
@@ -219,6 +222,8 @@ HTTP_END_ARGS;
 
 #define http_request_object_declare_default_properties() _http_request_object_declare_default_properties(TSRMLS_C)
 static inline void _http_request_object_declare_default_properties(TSRMLS_D);
+#define http_request_object_clone_obj _http_request_object_clone_obj
+static inline zend_object_value _http_request_object_clone_obj(zval *object TSRMLS_DC);
 
 zend_class_entry *http_request_object_ce;
 zend_function_entry http_request_object_fe[] = {
@@ -295,19 +300,31 @@ zend_function_entry http_request_object_fe[] = {
 };
 static zend_object_handlers http_request_object_handlers;
 
-void _http_request_object_init(INIT_FUNC_ARGS)
+PHP_MINIT_FUNCTION(http_request_object)
 {
        HTTP_REGISTER_CLASS_EX(HttpRequest, http_request_object, NULL, 0);
+       http_request_object_handlers.clone_obj = NULL; /* http_request_object_clone_obj; */
+       return SUCCESS;
 }
 
 zend_object_value _http_request_object_new(zend_class_entry *ce TSRMLS_DC)
+{
+       return http_request_object_new_ex(ce, NULL);
+}
+
+zend_object_value _http_request_object_new_ex(zend_class_entry *ce, CURL* ch TSRMLS_DC)
 {
        zend_object_value ov;
        http_request_object *o;
 
        o = ecalloc(1, sizeof(http_request_object));
        o->zo.ce = ce;
-       o->ch = curl_easy_init();
+       
+       if (ch) {
+               o->ch = ch;
+       } else {
+               o->ch = curl_easy_init();
+       }
 
        phpstr_init(&o->history);
        phpstr_init(&o->request);
@@ -323,6 +340,39 @@ zend_object_value _http_request_object_new(zend_class_entry *ce TSRMLS_DC)
        return ov;
 }
 
+zend_object_value _http_request_object_clone(zval *object TSRMLS_DC)
+{
+       return http_request_object_clone_obj(object TSRMLS_CC);
+}
+
+static inline zend_object_value _http_request_object_clone_obj(zval *object TSRMLS_DC)
+{
+       zval clone;
+       getObjectEx(http_request_object, obj, object);
+       
+       INIT_PZVAL(&clone);
+       clone.value.obj = http_request_object_new_ex(Z_OBJCE_P(object), curl_easy_duphandle(obj->ch));
+       {
+               getObjectEx(http_request_object, cobj, &clone);
+               
+               /* copy history */
+               phpstr_append(&cobj->history, PHPSTR_VAL(&obj->history), PHPSTR_LEN(&obj->history));
+               /*
+               phpstr_append(&cobj->request, PHPSTR_VAL(&obj->request), PHPSTR_LEN(&obj->request));
+               phpstr_append(&obj->response, PHPSTR_VAL(&obj->response), PHPSTR_ÖEN(&obj->response));
+               */
+               /* copy properties */
+               zend_hash_copy(OBJ_PROP(cobj), OBJ_PROP(obj), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+               
+               /* attach to pool */
+               if (obj->pool) {
+                       http_request_pool_attach(obj->pool, &clone);
+               }
+       }
+       
+       return clone.value.obj;
+}
+
 static inline void _http_request_object_declare_default_properties(TSRMLS_D)
 {
        zend_class_entry *ce = http_request_object_ce;
@@ -646,13 +696,14 @@ static inline void _http_request_get_options_subr(INTERNAL_FUNCTION_PARAMETERS,
 
 /* ### USERLAND ### */
 
-/* {{{ proto void HttpRequest::__construct([string url[, int request_method = HTTP_METH_GET]])
+/* {{{ proto void HttpRequest::__construct([string url[, int request_method = HTTP_METH_GET[, array options]]])
  *
  * Instantiate a new HttpRequest object.
  * 
  * Accepts a string as optional parameter containing the target request url.
  * Additianally accepts an optional int parameter specifying the request method
- * to use.
+ * to use and an associative array as optional third parameter which will be
+ * passed to HttpRequest::setOptions(). 
  * 
  * Throws HttpException.
  */
@@ -661,10 +712,11 @@ PHP_METHOD(HttpRequest, __construct)
        char *URL = NULL;
        int URL_len;
        long meth = -1;
+       zval *options = NULL;
        getObject(http_request_object, obj);
 
        SET_EH_THROW_HTTP();
-       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sl", &URL, &URL_len, &meth)) {
+       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sla", &URL, &URL_len, &meth, &options)) {
                INIT_PARR(obj, options);
                INIT_PARR(obj, responseInfo);
                INIT_PARR(obj, responseData);
@@ -677,6 +729,9 @@ PHP_METHOD(HttpRequest, __construct)
                if (meth > -1) {
                        UPD_PROP(obj, long, method, meth);
                }
+               if (options) {
+                       zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "setoptions", NULL, options);
+               }
        }
        SET_EH_NORMAL();
 }