+ HTTPi_ME(authBasic, http_auth_basic, NULL)
+ HTTPi_ME(authBasicCallback, http_auth_basic_cb, NULL)
+ {NULL, NULL, NULL}
+};
+/* }}} HTTPi */
+
+/* {{{ HTTPi_Response */
+
+zend_class_entry *httpi_response_ce;
+static zend_object_handlers httpi_response_object_handlers;
+
+typedef struct {
+ zend_object zo;
+} httpi_response_object;
+
+#define httpi_response_declare_default_properties(ce) _httpi_response_declare_default_properties(ce TSRMLS_CC)
+static inline void _httpi_response_declare_default_properties(zend_class_entry *ce TSRMLS_DC)
+{
+ DCL_PROP(PROTECTED, string, contentType, "application/x-octetstream");
+ DCL_PROP(PROTECTED, string, eTag, "");
+ DCL_PROP(PROTECTED, string, dispoFile, "");
+ DCL_PROP(PROTECTED, string, cacheControl, "public");
+ DCL_PROP(PROTECTED, string, data, "");
+ DCL_PROP(PROTECTED, string, file, "");
+ DCL_PROP(PROTECTED, long, stream, 0);
+ DCL_PROP(PROTECTED, long, lastModified, 0);
+ DCL_PROP(PROTECTED, long, dispoInline, 0);
+ DCL_PROP(PROTECTED, long, cache, 0);
+ DCL_PROP(PROTECTED, long, gzip, 0);
+
+ DCL_PROP(PRIVATE, long, raw_cache_header, 0);
+ DCL_PROP(PRIVATE, long, send_mode, -1);
+}
+
+#define httpi_response_destroy_object _httpi_response_destroy_object
+void _httpi_response_destroy_object(void *object, zend_object_handle handle TSRMLS_DC)
+{
+ httpi_response_object *o = object;
+ if (OBJ_PROP(o)) {
+ zend_hash_destroy(OBJ_PROP(o));
+ FREE_HASHTABLE(OBJ_PROP(o));
+ }
+ efree(o);
+}
+
+#define httpi_response_new_object _httpi_response_new_object
+zend_object_value _httpi_response_new_object(zend_class_entry *ce TSRMLS_DC)
+{
+ zend_object_value ov;
+ httpi_response_object *o;
+
+ o = ecalloc(sizeof(httpi_response_object), 1);
+ o->zo.ce = ce;
+
+ ALLOC_HASHTABLE(OBJ_PROP(o));
+ 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_response_destroy_object, NULL, NULL TSRMLS_CC);
+ ov.handlers = &httpi_response_object_handlers;
+
+ return ov;
+}
+
+zend_function_entry httpi_response_class_methods[] = {
+ PHP_ME(HTTPi_Response, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+/* PHP_ME(HTTPi_Response, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
+*/
+ PHP_ME(HTTPi_Response, setETag, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Response, getETag, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Response, setContentDisposition, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Response, getContentDisposition, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Response, setContentType, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Response, getContentType, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Response, setCache, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Response, getCache, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Response, setCacheControl, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Response, getCacheControl, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Response, setGzip, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Response, getGzip, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Response, setData, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Response, getData, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Response, setFile, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Response, getFile, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Response, setStream, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Response, getStream, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Response, send, NULL, ZEND_ACC_PUBLIC)
+
+ {NULL, NULL, NULL}
+};
+
+/* {{{ proto void HTTPi_Response::__construct(bool cache, bool gzip)
+ *
+ */
+PHP_METHOD(HTTPi_Response, __construct)
+{
+ zend_bool do_cache = 0, do_gzip = 0;
+ getObject(httpi_response_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bb", &do_cache, &do_gzip)) {
+ // throw exception
+ return;
+ }
+
+ UPD_PROP(obj, long, cache, do_cache);
+ UPD_PROP(obj, long, gzip, do_gzip);
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Response::setCache(bool cache)
+ *
+ */
+PHP_METHOD(HTTPi_Response, setCache)
+{
+ zend_bool do_cache = 0;
+ getObject(httpi_response_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &do_cache)) {
+ RETURN_FALSE;
+ }
+
+ UPD_PROP(obj, long, cache, do_cache);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Response::getCache()
+ *
+ */
+PHP_METHOD(HTTPi_Response, getCache)
+{
+ zval *do_cache = NULL;
+ getObject(httpi_response_object, obj);
+
+ NO_ARGS;
+
+ do_cache = GET_PROP(obj, cache);
+ RETURN_BOOL(Z_LVAL_P(do_cache));
+}
+/* }}}*/
+
+/* {{{ proto bool HTTPi_Response::setGzip(bool gzip)
+ *
+ */
+PHP_METHOD(HTTPi_Response, setGzip)
+{
+ zend_bool do_gzip = 0;
+ getObject(httpi_response_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &do_gzip)) {
+ RETURN_FALSE;
+ }
+
+ UPD_PROP(obj, long, gzip, do_gzip);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Response::getGzip()
+ *
+ */
+PHP_METHOD(HTTPi_Response, getGzip)
+{
+ zval *do_gzip = NULL;
+ getObject(httpi_response_object, obj);
+
+ NO_ARGS;
+
+ do_gzip = GET_PROP(obj, gzip);
+ RETURN_BOOL(Z_LVAL_P(do_gzip));
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Response::setCacheControl(string control[, bool raw = false])
+ *
+ */
+PHP_METHOD(HTTPi_Response, setCacheControl)
+{
+ char *ccontrol;
+ int cc_len;
+ zend_bool raw = 0;
+ getObject(httpi_response_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &ccontrol, &cc_len, &raw)) {
+ RETURN_FALSE;
+ }
+
+ if ((!raw) && (strcmp(ccontrol, "public") && strcmp(ccontrol, "private") && strcmp(ccontrol, "no-cache"))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cache-Control '%s' doesn't match public, private or no-cache", ccontrol);
+ RETURN_FALSE;
+ }
+
+ UPD_PROP(obj, long, raw_cache_header, raw);
+ UPD_PROP(obj, string, cacheControl, ccontrol);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto string HTTPi_Response::getCacheControl()
+ *
+ */
+PHP_METHOD(HTTPi_Response, getCacheControl)
+{
+ zval *ccontrol;
+ getObject(httpi_response_object, obj);
+
+ NO_ARGS;
+
+ ccontrol = GET_PROP(obj, cacheControl);
+ RETURN_STRINGL(Z_STRVAL_P(ccontrol), Z_STRLEN_P(ccontrol), 1);
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi::setContentType(string content_type)
+ *
+ */
+PHP_METHOD(HTTPi_Response, setContentType)
+{
+ char *ctype;
+ int ctype_len;
+ getObject(httpi_response_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &ctype, &ctype_len)) {
+ RETURN_FALSE;
+ }
+
+ if (!strchr(ctype, '/')) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Content type '%s' doesn't seem to contain a primary and a secondary part", ctype);
+ RETURN_FALSE;
+ }
+
+ UPD_PROP(obj, string, contentType, ctype);
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto string HTTPi_Response::getContentType()
+ *
+ */
+PHP_METHOD(HTTPi_Response, getContentType)
+{
+ zval *ctype;
+ getObject(httpi_response_object, obj);
+
+ NO_ARGS;
+
+ ctype = GET_PROP(obj, contentType);
+ RETURN_STRINGL(Z_STRVAL_P(ctype), Z_STRLEN_P(ctype), 1);
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Response::setContentDisposition(string filename[, bool inline = false])
+ *
+ */
+PHP_METHOD(HTTPi_Response, setContentDisposition)
+{
+ char *file;
+ int file_len;
+ zend_bool is_inline = 0;
+ getObject(httpi_response_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &file, &file_len, &is_inline)) {
+ RETURN_FALSE;
+ }
+
+ UPD_PROP(obj, string, dispoFile, file);
+ UPD_PROP(obj, long, dispoInline, is_inline);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto array HTTPi_Response::getContentDisposition()
+ *
+ */
+PHP_METHOD(HTTPi_Response, getContentDisposition)
+{
+ zval *file;
+ zval *is_inline;
+ getObject(httpi_response_object, obj);
+
+ if (ZEND_NUM_ARGS()) {
+ WRONG_PARAM_COUNT;
+ }
+
+ file = GET_PROP(obj, dispoFile);
+ is_inline = GET_PROP(obj, dispoInline);
+
+ array_init(return_value);
+ add_assoc_stringl(return_value, "filename", Z_STRVAL_P(file), Z_STRLEN_P(file), 1);
+ add_assoc_bool(return_value, "inline", Z_LVAL_P(is_inline));
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Response::setETag(string etag)
+ *
+ */
+PHP_METHOD(HTTPi_Response, setETag)
+{
+ char *etag;
+ int etag_len;
+ getObject(httpi_response_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &etag, &etag_len)) {
+ RETURN_FALSE;
+ }
+
+ UPD_PROP(obj, string, eTag, etag);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto string HTTPi_Response::getETag()
+ *
+ */
+PHP_METHOD(HTTPi_Response, getETag)
+{
+ zval *etag;
+ getObject(httpi_response_object, obj);
+
+ NO_ARGS;
+
+ etag = GET_PROP(obj, eTag);
+ RETURN_STRINGL(Z_STRVAL_P(etag), Z_STRLEN_P(etag), 1);
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Response::setData(string data)
+ *
+ */
+PHP_METHOD(HTTPi_Response, setData)
+{
+ zval *the_data;
+ char *etag;
+ getObject(httpi_response_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &the_data)) {
+ RETURN_FALSE;
+ }
+
+ convert_to_string_ex(&the_data);
+ SET_PROP(obj, data, the_data);
+ UPD_PROP(obj, long, lastModified, http_lmod(the_data, SEND_DATA));
+ UPD_PROP(obj, long, send_mode, SEND_DATA);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto string HTTPi_Response::getData()
+ *
+ */
+PHP_METHOD(HTTPi_Response, getData)
+{
+ zval *the_data;
+ getObject(httpi_response_object, obj);
+
+ NO_ARGS;
+
+ the_data = GET_PROP(obj, data);
+ RETURN_STRINGL(Z_STRVAL_P(the_data), Z_STRLEN_P(the_data), 1);
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Response::setStream(resource stream)
+ *
+ */
+PHP_METHOD(HTTPi_Response, setStream)
+{
+ zval *the_stream;
+ php_stream *the_real_stream;
+ char *etag;
+ getObject(httpi_response_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &the_stream)) {
+ RETURN_FALSE;
+ }
+
+ php_stream_from_zval(the_real_stream, &the_stream);
+
+ SET_PROP(obj, stream, the_stream);
+ UPD_PROP(obj, long, lastModified, http_lmod(the_real_stream, SEND_RSRC));
+ UPD_PROP(obj, long, send_mode, SEND_RSRC);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto resource HTTPi_Response::getStream()
+ *
+ */
+PHP_METHOD(HTTPi_Response, getStream)
+{
+ zval *the_stream;
+ getObject(httpi_response_object, obj);
+
+ NO_ARGS;
+
+ the_stream = GET_PROP(obj, stream);
+ RETURN_RESOURCE(Z_LVAL_P(the_stream));
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Response::setFile(string file)
+ *
+ */
+PHP_METHOD(HTTPi_Response, setFile)
+{
+ zval *the_file;
+ getObject(httpi_response_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &the_file)) {
+ RETURN_FALSE;
+ }
+
+ convert_to_string_ex(&the_file);
+
+ UPD_PROP(obj, string, file, Z_STRVAL_P(the_file));
+ UPD_PROP(obj, long, lastModified, http_lmod(the_file, -1));
+ UPD_PROP(obj, long, send_mode, -1);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto string HTTPi_Response::getFile()
+ *
+ */
+PHP_METHOD(HTTPi_Response, getFile)
+{
+ zval *the_file;
+ getObject(httpi_response_object, obj);
+
+ NO_ARGS;
+
+ the_file = GET_PROP(obj, file);
+ RETURN_STRINGL(Z_STRVAL_P(the_file), Z_STRLEN_P(the_file), 1);
+}
+/* }}} */
+
+PHP_METHOD(HTTPi_Response, send)
+{
+ zval *do_cache, *do_gzip;
+ getObject(httpi_response_object, obj);
+
+ do_cache = GET_PROP(obj, cache);
+ do_gzip = GET_PROP(obj, gzip);
+
+ /* caching */
+ if (Z_LVAL_P(do_cache)) {
+ zval *cctrl, *etag, *lmod, *ccraw;
+
+ etag = GET_PROP(obj, eTag);
+ lmod = GET_PROP(obj, lastModified);
+ cctrl = GET_PROP(obj, cacheControl);
+ ccraw = GET_PROP(obj, raw_cache_header);
+
+ if (Z_LVAL_P(ccraw)) {
+ http_cache_etag(Z_STRVAL_P(etag), Z_STRLEN_P(etag), Z_STRVAL_P(cctrl), Z_STRLEN_P(cctrl));
+ http_cache_last_modified(Z_LVAL_P(lmod), Z_LVAL_P(lmod) ? Z_LVAL_P(lmod) : time(NULL), Z_STRVAL_P(cctrl), Z_STRLEN_P(cctrl));
+ } else {
+ char cc_header[42] = {0};
+ sprintf(cc_header, "%s, must-revalidate, max-age=0", Z_STRVAL_P(cctrl));
+ http_cache_etag(Z_STRVAL_P(etag), Z_STRLEN_P(etag), cc_header, strlen(cc_header));
+ http_cache_last_modified(Z_LVAL_P(lmod), Z_LVAL_P(lmod) ? Z_LVAL_P(lmod) : time(NULL), cc_header, strlen(cc_header));
+ }
+ }
+
+ /* gzip */
+ if (Z_LVAL_P(do_gzip)) {
+ /* ... */
+ }
+
+ /* content type */
+ {
+ zval *ctype = GET_PROP(obj, contentType);
+ if (Z_STRLEN_P(ctype)) {
+ http_send_content_type(Z_STRVAL_P(ctype), Z_STRLEN_P(ctype));
+ } else {
+ http_send_content_type("application/x-octetstream", sizeof("application/x-octetstream") - 1);
+ }
+ }
+
+ /* content disposition */
+ {
+ zval *dispo_file = GET_PROP(obj, dispoFile);
+ if (Z_STRLEN_P(dispo_file)) {
+ zval *dispo_inline = GET_PROP(obj, dispoInline);
+ http_send_content_disposition(Z_STRVAL_P(dispo_file), Z_STRLEN_P(dispo_file), Z_LVAL_P(dispo_inline));
+ }
+ }
+
+ /* send */
+ {
+ zval *send_mode = GET_PROP(obj, send_mode);
+ switch (Z_LVAL_P(send_mode))
+ {
+ case SEND_DATA:
+ {
+ RETURN_SUCCESS(http_send_data(GET_PROP(obj, data)));
+ }
+
+ case SEND_RSRC:
+ {
+ php_stream *the_real_stream;
+ zval *the_stream = GET_PROP(obj, stream);
+ php_stream_from_zval(the_real_stream, &the_stream);
+ RETURN_SUCCESS(http_send_stream(the_real_stream));
+ }
+
+ default:
+ {
+ RETURN_SUCCESS(http_send_file(GET_PROP(obj, file)));
+ }
+ }
+ }
+}
+/* }}} */
+
+/* {{{ HTTPi_Request */
+#ifdef HTTP_HAVE_CURL
+
+zend_class_entry *httpi_request_ce;
+static zend_object_handlers httpi_request_object_handlers;
+
+typedef struct {
+ zend_object zo;
+ CURL *ch;
+} httpi_request_object;
+
+#define httpi_request_declare_default_properties(ce) _httpi_request_declare_default_properties(ce TSRMLS_CC)
+static inline void _httpi_request_declare_default_properties(zend_class_entry *ce TSRMLS_DC)
+{
+ DCL_PROP_N(PROTECTED, options);
+ DCL_PROP_N(PROTECTED, responseInfo);
+ DCL_PROP_N(PROTECTED, responseData);
+
+ DCL_PROP(PROTECTED, long, method, HTTP_GET);
+
+ DCL_PROP(PROTECTED, string, url, "");
+ DCL_PROP(PROTECTED, string, contentType, "");
+ DCL_PROP(PROTECTED, string, queryData, "");
+ DCL_PROP(PROTECTED, string, postData, "");
+}
+
+#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);
+}
+
+#define httpi_request_new_object _httpi_request_new_object
+zend_object_value _httpi_request_new_object(zend_class_entry *ce TSRMLS_DC)
+{
+ zend_object_value ov;
+ httpi_request_object *o;
+
+ o = ecalloc(sizeof(httpi_request_object), 1);
+ o->zo.ce = ce;
+ o->ch = curl_easy_init();
+
+ ALLOC_HASHTABLE(OBJ_PROP(o));
+ 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, zend_objects_destroy_object, httpi_request_free_object, NULL TSRMLS_CC);
+ ov.handlers = &httpi_request_object_handlers;
+
+ return ov;
+}
+
+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, setOptions, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Request, getOptions, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Request, setMethod, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Request, getMethod, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Request, setURL, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Request, getURL, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Request, setContentType, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Request, getContentType, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Request, setQueryData, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Request, getQueryData, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Request, addQueryData, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Request, unsetQueryData, NULL, ZEND_ACC_PUBLIC)
+/*
+ PHP_ME(HTTPi_Request, setPostData, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Request, addPostData, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Request, unsetPostData, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Request, addPostFile, NULL, ZEND_ACC_PUBLIC)
+*/
+ PHP_ME(HTTPi_Request, send, NULL, ZEND_ACC_PUBLIC)
+
+ PHP_ME(HTTPi_Request, getResponseData, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Request, getResponseHeaders, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Request, getResponseBody, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(HTTPi_Request, getResponseInfo, NULL, ZEND_ACC_PUBLIC)
+
+ {NULL, NULL, NULL}
+};
+
+/* {{{ proto void HTTPi_Request::__construct([string url[, long request_method = HTTP_GET]])
+ *
+ */
+PHP_METHOD(HTTPi_Request, __construct)
+{
+ char *URL = NULL;
+ int URL_len;
+ long meth = -1;
+ zval *info, *opts, *resp;
+ getObject(httpi_request_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sl", &URL, &URL_len, &meth)) {
+ return;
+ }
+
+ INIT_PARR(obj, options);
+ INIT_PARR(obj, responseInfo);
+ INIT_PARR(obj, responseData);
+
+ if (URL) {
+ UPD_PROP(obj, string, url, URL);
+ }
+ if (meth > -1) {
+ UPD_PROP(obj, long, method, meth);
+ }
+}
+/* }}} */
+
+/* {{{ 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)
+ *
+ */
+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;
+ zend_hash_move_forward(Z_ARRVAL_P(opts))) {
+ char *key;
+ long idx;
+ if (HASH_KEY_IS_STRING == zend_hash_get_current_key(Z_ARRVAL_P(opts), &key, &idx, 0)) {
+ if (!strcmp(key, "headers")) {
+ zval **headers;
+ if (SUCCESS == zend_hash_find(Z_ARRVAL_P(old_opts), "headers", sizeof("headers"), (void **) &headers)) {
+ array_merge(*opt, *headers);
+ continue;
+ }
+ } else if (!strcmp(key, "cookies")) {
+ zval **cookies;
+ if (SUCCESS == zend_hash_find(Z_ARRVAL_P(old_opts), "cookies", sizeof("cookies"), (void **) &cookies)) {
+ array_merge(*opt, *cookies);
+ continue;
+ }
+ }
+ zval_add_ref(opt);
+ add_assoc_zval(old_opts, key, *opt);
+ }
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto array HTTPi_Request::getOptions()
+ *
+ */
+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);
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Request::setURL(string url)
+ *
+ */
+PHP_METHOD(HTTPi_Request, setURL)
+{
+ char *URL = NULL;
+ int URL_len;
+ getObject(httpi_request_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &URL, &URL_len)) {
+ RETURN_FALSE;
+ }
+
+ UPD_PROP(obj, string, url, URL);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto string HTTPi_Request::getUrl()
+ *
+ */
+PHP_METHOD(HTTPi_Request, getURL)
+{
+ zval *URL;
+ getObject(httpi_request_object, obj);
+
+ NO_ARGS;
+
+ URL = GET_PROP(obj, url);
+ RETURN_STRINGL(Z_STRVAL_P(URL), Z_STRLEN_P(URL), 1);
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Request::setMethod(long request_method)
+ *
+ */
+PHP_METHOD(HTTPi_Request, setMethod)
+{
+ long meth;
+ getObject(httpi_request_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &meth)) {
+ RETURN_FALSE;
+ }
+
+ UPD_PROP(obj, long, method, meth);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto long HTTPi_Request::getMethod()
+ *
+ */
+PHP_METHOD(HTTPi_Request, getMethod)
+{
+ zval *meth;
+ getObject(httpi_request_object, obj);
+
+ NO_ARGS;
+
+ meth = GET_PROP(obj, method);
+ RETURN_LONG(Z_LVAL_P(meth));
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Request::setContentType(string content_type)
+ *
+ */
+PHP_METHOD(HTTPi_Request, setContentType)
+{
+ char *ctype;
+ int ct_len;
+ getObject(httpi_request_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &ctype, &ct_len)) {
+ RETURN_FALSE;
+ }
+
+ if (!strchr(ctype, '/')) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Content-Type '%s' doesn't seem to contain a primary and a secondary part",
+ ctype);
+ RETURN_FALSE;
+ }
+
+ UPD_PROP(obj, string, contentType, ctype);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto string HTTPi_Request::getContentType()
+ *
+ */
+PHP_METHOD(HTTPi_Request, getContentType)
+{
+ zval *ctype;
+ getObject(httpi_request_object, obj);
+
+ NO_ARGS;
+
+ ctype = GET_PROP(obj, contentType);
+ RETURN_STRINGL(Z_STRVAL_P(ctype), Z_STRLEN_P(ctype), 1);
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Request::setQueryData(mixed query_data)
+ *
+ */
+PHP_METHOD(HTTPi_Request, setQueryData)
+{
+ zval *qdata;
+ getObject(httpi_request_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &qdata)) {
+ RETURN_FALSE;
+ }
+
+ if ((Z_TYPE_P(qdata) == IS_ARRAY) || (Z_TYPE_P(qdata) == IS_OBJECT)) {
+ smart_str qstr = {0};
+ HTTP_URL_ARGSEP_OVERRIDE;
+ if (SUCCESS != php_url_encode_hash_ex(HASH_OF(qdata), &qstr, NULL, 0, NULL, 0, NULL, 0, NULL TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't encode query data");
+ if (qstr.c) {
+ efree(qstr.c);
+ }
+ HTTP_URL_ARGSEP_RESTORE;
+ RETURN_FALSE;
+ }
+ HTTP_URL_ARGSEP_RESTORE;
+ smart_str_0(&qstr);
+ UPD_PROP(obj, string, queryData, qstr.c);
+ efree(qstr.c);
+ RETURN_TRUE;
+ }
+
+ convert_to_string(qdata);
+ UPD_PROP(obj, string, queryData, Z_STRVAL_P(qdata));
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto string HTTPi_Request::getQueryData()
+ *
+ */
+PHP_METHOD(HTTPi_Request, getQueryData)
+{
+ zval *qdata;
+ getObject(httpi_request_object, obj);
+
+ NO_ARGS;
+
+ qdata = GET_PROP(obj, queryData);
+ RETURN_STRINGL(Z_STRVAL_P(qdata), Z_STRLEN_P(qdata), 1);
+}
+/* }}} */
+
+/* {{{ proto bool HTTPi_Request::addQueryData(array query_params)
+ *
+ */
+PHP_METHOD(HTTPi_Request, addQueryData)
+{
+ zval *qdata, *old_qdata;
+ smart_str qstr = {0};
+ char *separator;
+ getObject(httpi_request_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &qdata)) {
+ RETURN_FALSE;
+ }
+
+ old_qdata = GET_PROP(obj, queryData);
+ if (Z_STRLEN_P(old_qdata)) {
+ smart_str_appendl(&qstr, Z_STRVAL_P(old_qdata), Z_STRLEN_P(old_qdata));
+ }
+
+ HTTP_URL_ARGSEP_OVERRIDE;
+ if (SUCCESS != php_url_encode_hash_ex(HASH_OF(qdata), &qstr, NULL, 0, NULL, 0, NULL, 0, NULL TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't encode query data");
+ if (qstr.c) {
+ efree(qstr.c);
+ }
+ HTTP_URL_ARGSEP_RESTORE;
+ RETURN_FALSE;
+ }
+ HTTP_URL_ARGSEP_RESTORE;
+
+ smart_str_0(&qstr);
+
+ UPD_PROP(obj, string, queryData, qstr.c);
+ efree(qstr.c);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void HTTPi_Request::unsetQueryData()
+ *
+ */
+PHP_METHOD(HTTPi_Request, unsetQueryData)
+{
+ getObject(httpi_request_object, obj);
+
+ NO_ARGS;
+
+ UPD_PROP(obj, string, queryData, "");
+}
+/* }}} */
+
+/* {{{ proto array HTTPi_Request::getResponseData()
+ *
+ */
+PHP_METHOD(HTTPi_Request, getResponseData)
+{
+ zval *data;
+ getObject(httpi_request_object, obj);