X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http.c;h=e174ba11f241aa21e7efe0d2dd24a6173b1dad89;hp=ff61116a2470cb972ccb7fb2baa71a8672cd66dc;hb=2414448a15f7a9959dc41749dd938b6770843f0c;hpb=51f68d1c8028144d2db1e415fdf14afb1442649e diff --git a/http.c b/http.c index ff61116..e174ba1 100644 --- a/http.c +++ b/http.c @@ -155,6 +155,24 @@ function_entry http_functions[] = { # define SET_PROP(o, n, z) zend_update_property(o->zo.ce, getThis(), (#n), sizeof(#n), (z) TSRMLS_CC) # define GET_PROP(o, n) zend_read_property(o->zo.ce, getThis(), (#n), sizeof(#n), 0 TSRMLS_CC) +# define INIT_PARR(o, n) \ + { \ + zval *__tmp; \ + MAKE_STD_ZVAL(__tmp); \ + array_init(__tmp); \ + SET_PROP(o, n, __tmp); \ + } + +# define FREE_PARR(o, p) \ + { \ + zval *__tmp = NULL; \ + if (__tmp = GET_PROP(o, p)) { \ + zval_dtor(__tmp); \ + FREE_ZVAL(__tmp); \ + __tmp = NULL; \ + } \ + } + /* {{{ HTTPi */ zend_class_entry *httpi_ce; @@ -718,7 +736,7 @@ zend_class_entry *httpi_request_ce; static zend_object_handlers httpi_request_object_handlers; typedef struct { - zend_object zo; + zend_object zo; CURL *ch; } httpi_request_object; @@ -740,13 +758,21 @@ static inline void _httpi_request_declare_default_properties(zend_class_entry *c #define httpi_request_destroy_object _httpi_request_destroy_object void _httpi_request_destroy_object(void *object, zend_object_handle handle TSRMLS_DC) { - httpi_request_object *o = object; + zend_objects_destroy_object(object, handle TSRMLS_CC); +} + +#define httpi_request_free_object _httpi_request_free_object +void _httpi_request_free_object(zend_object /* void */ *object TSRMLS_DC) +{ + httpi_request_object *o = (httpi_request_object *) object; + if (OBJ_PROP(o)) { zend_hash_destroy(OBJ_PROP(o)); FREE_HASHTABLE(OBJ_PROP(o)); } if (o->ch) { curl_easy_cleanup(o->ch); + o->ch = NULL; } efree(o); } @@ -765,7 +791,7 @@ zend_object_value _httpi_request_new_object(zend_class_entry *ce TSRMLS_DC) zend_hash_init(OBJ_PROP(o), 0, NULL, ZVAL_PTR_DTOR, 0); zend_hash_copy(OBJ_PROP(o), &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); - ov.handle = zend_objects_store_put(o, httpi_request_destroy_object, NULL, NULL TSRMLS_CC); + ov.handle = zend_objects_store_put(o, httpi_request_destroy_object, httpi_request_free_object, NULL TSRMLS_CC); ov.handlers = &httpi_request_object_handlers; return ov; @@ -773,8 +799,8 @@ zend_object_value _httpi_request_new_object(zend_class_entry *ce TSRMLS_DC) zend_function_entry httpi_request_class_methods[] = { PHP_ME(HTTPi_Request, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) -/* PHP_ME(HTTPi_Request, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR) -*/ + PHP_ME(HTTPi_Request, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR) + PHP_ME(HTTPi_Request, setOptions, NULL, ZEND_ACC_PUBLIC) PHP_ME(HTTPi_Request, getOptions, NULL, ZEND_ACC_PUBLIC) @@ -823,9 +849,9 @@ PHP_METHOD(HTTPi_Request, __construct) return; } - MAKE_STD_ZVAL(opts); array_init(opts); SET_PROP(obj, options, opts); - MAKE_STD_ZVAL(info); array_init(info); SET_PROP(obj, responseInfo, info); - MAKE_STD_ZVAL(resp); array_init(resp); SET_PROP(obj, responseData, resp); + INIT_PARR(obj, options); + INIT_PARR(obj, responseInfo); + INIT_PARR(obj, responseData); if (URL) { UPD_PROP(obj, string, url, URL); @@ -836,6 +862,21 @@ PHP_METHOD(HTTPi_Request, __construct) } /* }}} */ +/* {{{ proto void HTTPi_Request::__destruct() + * + */ +PHP_METHOD(HTTPi_Request, __destruct) +{ + getObject(httpi_request_object, obj); + + NO_ARGS; + + FREE_PARR(obj, options); + FREE_PARR(obj, responseInfo); + FREE_PARR(obj, responseData); +} +/* }}} */ + /* {{{ proto bool HTTPi_Request::setOptions(array options) * */ @@ -843,13 +884,13 @@ PHP_METHOD(HTTPi_Request, setOptions) { zval *opts, *old_opts, **opt; getObject(httpi_request_object, obj); - + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &opts)) { RETURN_FALSE; } - + old_opts = GET_PROP(obj, options); - + /* headers and cookies need extra attention -- thus cannot use zend_hash_merge() or php_array_merge() directly */ for ( zend_hash_internal_pointer_reset(Z_ARRVAL_P(opts)); zend_hash_get_current_data(Z_ARRVAL_P(opts), (void **) &opt) == SUCCESS; @@ -874,7 +915,6 @@ PHP_METHOD(HTTPi_Request, setOptions) add_assoc_zval(old_opts, key, *opt); } } - RETURN_TRUE; } /* }}} */ @@ -886,9 +926,9 @@ PHP_METHOD(HTTPi_Request, getOptions) { zval *opts; getObject(httpi_request_object, obj); - + NO_ARGS; - + opts = GET_PROP(obj, options); array_init(return_value); array_copy(opts, return_value); @@ -1162,9 +1202,9 @@ PHP_METHOD(HTTPi_Request, getResponseInfo) { zval *info; getObject(httpi_request_object, obj); - + NO_ARGS; - + info = GET_PROP(obj, responseInfo); array_init(return_value); array_copy(info, return_value); @@ -1176,8 +1216,9 @@ PHP_METHOD(HTTPi_Request, getResponseInfo) */ PHP_METHOD(HTTPi_Request, send) { + STATUS status = FAILURE; zval *meth, *URL, *qdata, *opts, *info, *resp; - char *response_data, *request_uri; + char *response_data, *request_uri, *uri; size_t response_len; getObject(httpi_request_object, obj); @@ -1195,7 +1236,11 @@ PHP_METHOD(HTTPi_Request, send) info = GET_PROP(obj, responseInfo); resp = GET_PROP(obj, responseData); - request_uri = http_absolute_uri(Z_STRVAL_P(URL), NULL); + uri = http_absolute_uri(Z_STRVAL_P(URL), NULL); + request_uri = ecalloc(HTTP_URI_MAXLEN + 1, 1); + strcpy(request_uri, uri); + efree(uri); + if (Z_STRLEN_P(qdata) && (strlen(request_uri) < HTTP_URI_MAXLEN)) { if (!strchr(request_uri, '?')) { strcat(request_uri, "?"); @@ -1208,15 +1253,11 @@ PHP_METHOD(HTTPi_Request, send) switch (Z_LVAL_P(meth)) { case HTTP_GET: - if (SUCCESS != http_get_ex(obj->ch, request_uri, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &response_data, &response_len)) { - RETURN_FALSE; - } + status = http_get_ex(obj->ch, request_uri, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &response_data, &response_len); break; case HTTP_HEAD: - if (SUCCESS != http_head_ex(obj->ch, request_uri, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &response_data, &response_len)) { - RETURN_FALSE; - } + status = http_head_ex(obj->ch, request_uri, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &response_data, &response_len); break; case HTTP_POST: @@ -1226,8 +1267,12 @@ PHP_METHOD(HTTPi_Request, send) break; } + efree(request_uri); + /* final data handling */ - { + if (status != SUCCESS) { + RETURN_FALSE; + } else { zval *zheaders, *zbody; MAKE_STD_ZVAL(zbody); @@ -1238,12 +1283,15 @@ PHP_METHOD(HTTPi_Request, send) zval_dtor(zheaders); efree(zheaders), efree(zbody); + efree(response_data); RETURN_FALSE; } add_assoc_zval(resp, "headers", zheaders); add_assoc_zval(resp, "body", zbody); + efree(response_data); + RETURN_TRUE; } /* */