X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http.c;h=4f375f709ff38db43dbc33e06d69edb820fe6430;hp=ff61116a2470cb972ccb7fb2baa71a8672cd66dc;hb=39b61c66aae3c34246d4c1ab267160c704c7ada5;hpb=51f68d1c8028144d2db1e415fdf14afb1442649e diff --git a/http.c b/http.c index ff61116..4f375f7 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; @@ -737,16 +755,18 @@ static inline void _httpi_request_declare_default_properties(zend_class_entry *c DCL_PROP(PROTECTED, string, postData, ""); } -#define httpi_request_destroy_object _httpi_request_destroy_object -void _httpi_request_destroy_object(void *object, zend_object_handle handle TSRMLS_DC) +#define httpi_request_free_object _httpi_request_free_object +void _httpi_request_free_object(zend_object /* void */ *object TSRMLS_DC) { - httpi_request_object *o = object; + 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 +785,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, (zend_objects_store_dtor_t) zend_objects_destroy_object, httpi_request_free_object, NULL TSRMLS_CC); ov.handlers = &httpi_request_object_handlers; return ov; @@ -773,8 +793,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 +843,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 +856,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 +878,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 +909,6 @@ PHP_METHOD(HTTPi_Request, setOptions) add_assoc_zval(old_opts, key, *opt); } } - RETURN_TRUE; } /* }}} */ @@ -886,9 +920,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 +1196,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 +1210,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 +1230,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 +1247,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 +1261,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 +1277,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; } /* */ @@ -2224,7 +2266,7 @@ PHP_MINIT_FUNCTION(http) ZEND_INIT_MODULE_GLOBALS(http, php_http_init_globals, NULL); REGISTER_INI_ENTRIES(); -#ifdef HTTP_HAVE_CURL +#if defined(HTTP_HAVE_CURL) && (LIBCURL_VERSION_NUM >= 0x070a05) REGISTER_LONG_CONSTANT("HTTP_AUTH_BASIC", CURLAUTH_BASIC, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("HTTP_AUTH_DIGEST", CURLAUTH_DIGEST, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("HTTP_AUTH_NTLM", CURLAUTH_NTLM, CONST_CS | CONST_PERSISTENT);