zend_object_value _http_message_object_new(zend_class_entry *ce TSRMLS_DC)
{
- return http_message_object_new_ex(ce, NULL);
+ return http_message_object_new_ex(ce, NULL, NULL);
}
-zend_object_value _http_message_object_new_ex(zend_class_entry *ce, http_message *msg TSRMLS_DC)
+zend_object_value _http_message_object_new_ex(zend_class_entry *ce, http_message *msg, http_message_object **ptr TSRMLS_DC)
{
zend_object_value ov;
http_message_object *o;
o = ecalloc(1, sizeof(http_message_object));
o->zo.ce = ce;
+
+ if (ptr) {
+ *ptr = o;
+ }
if (msg) {
o->message = msg;
if (msg->parent) {
- o->parent = http_message_object_from_msg(msg->parent);
+ o->parent = http_message_object_new_ex(ce, msg->parent, NULL);
}
}
return ov;
}
-zend_object_value _http_message_object_clone(zval *this_ptr TSRMLS_DC)
+zend_object_value _http_message_object_clone_obj(zval *this_ptr TSRMLS_DC)
{
- return http_message_object_clone_obj(this_ptr TSRMLS_CC);
+ getObject(http_message_object, obj);
+ return http_message_object_new_ex(Z_OBJCE_P(this_ptr), http_message_dup(obj->message), NULL);
}
static inline void _http_message_object_declare_default_properties(TSRMLS_D)
efree(o);
}
-static inline zend_object_value _http_message_object_clone_obj(zval *this_ptr TSRMLS_DC)
-{
- getObject(http_message_object, obj);
- return http_message_object_from_msg(http_message_dup(obj->message));
-}
-
static zval *_http_message_object_read_prop(zval *object, zval *member, int type TSRMLS_DC)
{
getObjectEx(http_message_object, obj, object);
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &message, &length) && message && length) {
if (obj->message = http_message_parse(message, length)) {
if (obj->message->parent) {
- obj->parent = http_message_object_from_msg(obj->message->parent);
+ obj->parent = http_message_object_new_ex(Z_OBJCE_P(getThis()), obj->message->parent, NULL);
}
}
} else if (!obj->message) {
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &string, &length)) {
if (msg = http_message_parse(string, length)) {
Z_TYPE_P(return_value) = IS_OBJECT;
- return_value->value.obj = http_message_object_from_msg(msg);
+ return_value->value.obj = http_message_object_new_ex(http_message_object_ce, msg, NULL);
}
}
SET_EH_NORMAL();
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_handlers.clone_obj = _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, curl_easy_init(), NULL);
+}
+
+zend_object_value _http_request_object_new_ex(zend_class_entry *ce, CURL *ch, http_request_object **ptr 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();
+ o->ch = ch;
+
+ if (ptr) {
+ *ptr = o;
+ }
phpstr_init(&o->history);
phpstr_init(&o->request);
return ov;
}
+zend_object_value _http_request_object_clone_obj(zval *this_ptr TSRMLS_DC)
+{
+ zend_object *old_zo;
+ zend_object_value new_ov;
+ http_request_object *new_obj;
+ getObject(http_request_object, old_obj);
+
+ old_zo = zend_objects_get_address(this_ptr TSRMLS_CC);
+ new_ov = http_request_object_new_ex(old_zo->ce, curl_easy_duphandle(old_obj->ch), &new_obj);
+
+ zend_objects_clone_members(&new_obj->zo, new_ov, old_zo, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
+ phpstr_append(&new_obj->history, old_obj->history.data, old_obj->history.used);
+ phpstr_append(&new_obj->request, old_obj->request.data, old_obj->request.used);
+ phpstr_append(&new_obj->response, old_obj->response.data, old_obj->response.used);
+
+ return new_ov;
+}
+
static inline void _http_request_object_declare_default_properties(TSRMLS_D)
{
zend_class_entry *ce = http_request_object_ce;
*resp = convert_to_type(IS_ARRAY, GET_PROP(obj, responseData)),
*info = convert_to_type(IS_ARRAY, GET_PROP(obj, responseInfo));
+ SEP_PROP(&resp);
+ SEP_PROP(&info);
+
if (zval_is_true(GET_PROP(obj, recordHistory))) {
/* we need to act like a zipper, as we'll receive
* the requests and the responses in separate chains
add_assoc_zval(resp, "headers", headers);
add_assoc_stringl(resp, "body", body, body_len, 0);
+ SET_PROP(obj, responseData, resp);
MAKE_STD_ZVAL(message);
- ZVAL_OBJVAL(message, http_message_object_from_msg(msg));
+ ZVAL_OBJVAL(message, http_message_object_new_ex(http_message_object_ce, msg, NULL));
SET_PROP(obj, responseMessage, message);
zval_ptr_dtor(&message);
}
old_opts = convert_to_type(IS_ARRAY, GET_PROP(obj, options));
-
+ SEP_PROP(&old_opts);
+
if (!opts || !zend_hash_num_elements(Z_ARRVAL_P(opts))) {
zend_hash_clean(Z_ARRVAL_P(old_opts));
+ SET_PROP(obj, options, old_opts);
RETURN_TRUE;
}
}
post = convert_to_type(IS_ARRAY, GET_PROP(obj, postFields));
- zend_hash_clean(Z_ARRVAL_P(post));
+ SEP_PROP(&post);
+ zend_hash_clean(Z_ARRVAL_P(post));
if (post_data && zend_hash_num_elements(Z_ARRVAL_P(post_data))) {
array_copy(post_data, post);
}
+ SET_PROP(obj, postFields, post);
RETURN_TRUE;
}
}
pFiles = convert_to_type(IS_ARRAY, GET_PROP(obj, postFiles));
- zend_hash_clean(Z_ARRVAL_P(pFiles));
+ SEP_PROP(&pFiles);
+ zend_hash_clean(Z_ARRVAL_P(pFiles));
if (files && zend_hash_num_elements(Z_ARRVAL_P(files))) {
array_copy(files, pFiles);
}
+ SET_PROP(obj, postFiles, pFiles);
RETURN_TRUE;
}
SET_EH_THROW_HTTP();
if (msg = http_message_parse(PHPSTR_VAL(&obj->request), PHPSTR_LEN(&obj->request))) {
- RETVAL_OBJVAL(http_message_object_from_msg(msg));
+ RETVAL_OBJVAL(http_message_object_new_ex(http_message_object_ce, msg, NULL));
}
SET_EH_NORMAL();
}
SET_EH_THROW_HTTP();
if (msg = http_message_parse(PHPSTR_VAL(&obj->history), PHPSTR_LEN(&obj->history))) {
- RETVAL_OBJVAL(http_message_object_from_msg(msg));
+ RETVAL_OBJVAL(http_message_object_new_ex(http_message_object_ce, msg, NULL));
}
SET_EH_NORMAL();
}
FD_ZERO(&E);
curl_multi_fdset(pool->ch, &R, &W, &E, &MAX);
+#ifdef PHP_WIN32
+ return (SOCKET_ERROR != select(MAX + 1, &R, &W, &E, &timeout)) ? SUCCESS : FAILURE;
+#else
return (-1 != select(MAX + 1, &R, &W, &E, &timeout)) ? SUCCESS : FAILURE;
+#endif
}
/* }}} */
{
HTTP_REGISTER_CLASS_EX(HttpRequestPool, http_requestpool_object, NULL, 0);
zend_class_implements(http_requestpool_object_ce TSRMLS_CC, 1, zend_ce_iterator);
+ http_requestpool_object_handlers.clone_obj = NULL;
return SUCCESS;
}
extern PHP_MINIT_FUNCTION(http_message_object);
-#define http_message_object_new _http_message_object_new
+#define http_message_object_new(ce) _http_message_object_new((ce) TSRMLS_CC)
extern zend_object_value _http_message_object_new(zend_class_entry *ce TSRMLS_DC);
-#define http_message_object_new_ex(ce, msg) _http_message_object_new_ex(ce, msg TSRMLS_CC)
-#define http_message_object_from_msg(msg) _http_message_object_new_ex(http_message_object_ce, msg TSRMLS_CC)
-extern zend_object_value _http_message_object_new_ex(zend_class_entry *ce, http_message *msg TSRMLS_DC);
-#define http_message_object_clone(zobj) _http_message_object_clone(zobj TSRMLS_CC)
-extern zend_object_value _http_message_object_clone(zval *object TSRMLS_DC);
-#define http_message_object_free _http_message_object_free
+#define http_message_object_new_ex(ce, msg, ptr) _http_message_object_new_ex((ce), (msg), (ptr) TSRMLS_CC)
+extern zend_object_value _http_message_object_new_ex(zend_class_entry *ce, http_message *msg, http_message_object **ptr TSRMLS_DC);
+#define http_message_object_clone(zobj) _http_message_object_clone_obj(zobj TSRMLS_CC)
+extern zend_object_value _http_message_object_clone_obj(zval *object TSRMLS_DC);
+#define http_message_object_free(o) _http_message_object_free((o) TSRMLS_CC)
extern void _http_message_object_free(zend_object *object TSRMLS_DC);
#define HTTP_MSG_PROPHASH_TYPE 276192743LU
extern PHP_MINIT_FUNCTION(http_request_object);
-#define http_request_object_new _http_request_object_new
+#define http_request_object_new(ce) _http_request_object_new((ce) TSRMLS_CC)
extern zend_object_value _http_request_object_new(zend_class_entry *ce TSRMLS_DC);
-#define http_request_object_free _http_request_object_free
+#define http_request_object_new_ex(ce, ch, ptr) _http_request_object_new_ex((ce), (ch), (ptr) TSRMLS_CC)
+extern zend_object_value _http_request_object_new_ex(zend_class_entry *ce, CURL *ch, http_request_object **ptr TSRMLS_DC);
+#define http_request_object_clone(zv) _http_request_object_clone_obj((zv) TSRMLS_CC)
+extern zend_object_value _http_request_object_clone_obj(zval *zobject TSRMLS_DC);
+#define http_request_object_free(o) _http_request_object_free((o) TSRMLS_CC)
extern void _http_request_object_free(zend_object *object TSRMLS_DC);
-#define http_request_object_clone(o) _http_request_object_clone((o) TSRMLS_CC)
-extern zend_object_value _http_request_object_clone(zval *object TSRMLS_DC);
#define http_request_object_requesthandler(req, this, body) _http_request_object_requesthandler((req), (this), (body) TSRMLS_CC)
extern STATUS _http_request_object_requesthandler(http_request_object *obj, zval *this_ptr, http_request_body *body TSRMLS_DC);
extern PHP_MINIT_FUNCTION(http_requestpool_object);
-#define http_requestpool_object_new _http_requestpool_object_new
+#define http_requestpool_object_new(ce) _http_requestpool_object_new(ce TSRMLS_CC)
extern zend_object_value _http_requestpool_object_new(zend_class_entry *ce TSRMLS_DC);
-#define http_requestpool_object_free _http_requestpool_object_free
+#define http_requestpool_object_free(o) _http_requestpool_object_free(o TSRMLS_CC)
extern void _http_requestpool_object_free(zend_object *object TSRMLS_DC);
PHP_METHOD(HttpRequestPool, __construct);
{ \
zend_class_entry ce; \
INIT_CLASS_ENTRY(ce, #classname, name## _fe); \
- ce.create_object = name## _new; \
+ ce.create_object = _ ##name## _new; \
name## _ce = zend_register_internal_class_ex(&ce, parent, NULL TSRMLS_CC); \
name## _ce->ce_flags |= flags; \
memcpy(& name## _handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); \
# define getObject(t, o) getObjectEx(t, o, getThis())
# define getObjectEx(t, o, v) t * o = ((t *) zend_object_store_get_object(v TSRMLS_CC))
-# define putObject(t, o) zend_objects_store_put(o, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) t## _free, NULL TSRMLS_CC);
+# define putObject(t, o) zend_objects_store_put(o, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) _ ##t## _free, NULL TSRMLS_CC);
# define OBJ_PROP(o) (o)->zo.properties
# define DCL_STATIC_PROP(a, t, n, v) zend_declare_property_ ##t(ce, (#n), sizeof(#n)-1, (v), (ZEND_ACC_ ##a | ZEND_ACC_STATIC) TSRMLS_CC)
} \
}
+/*
+ * the property *MUST* be updated after SEP_PROP()
+ */
+# define SEP_PROP(zpp) \
+ { \
+ zval **op = zpp; \
+ SEPARATE_ZVAL_IF_NOT_REF(zpp); \
+ if (op != zpp) { \
+ zval_ptr_dtor(op); \
+ } \
+ }
+
# define SET_EH_THROW() SET_EH_THROW_EX(zend_exception_get_default())
# define SET_EH_THROW_HTTP() SET_EH_THROW_EX(http_exception_get_default())
# define SET_EH_THROW_EX(ex) php_set_error_handling(EH_THROW, ex TSRMLS_CC)
--- /dev/null
+--TEST--
+cloning
+--SKIPIF--
+<?php
+include 'skip.inc';
+checkver(5);
+checkcls('HttpRequest');
+?>
+--FILE--
+<?php
+echo "-TEST\n";
+
+$r1 = new HttpRequest;
+$r2 = clone $r1;
+$r1->setOptions(array('redirect' => 3));
+var_dump($r1->getOptions() == $r2->getOptions());
+$r1->setUrl('http://www.google.com/');
+var_dump($r1->getUrl() == $r2->getUrl());
+$r1->send();
+var_dump($r1->getResponseInfo() == $r2->getResponseInfo());
+
+echo "Done\n";
+?>
+--EXPECTF--
+%sTEST
+bool(false)
+bool(false)
+bool(false)
+Done