X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_methods.c;h=053fce7b232ee97845beb5a62b98d7bcbbbd38ff;hp=4b2493586fba76569483524f74a6ed48956508c6;hb=b272c1e03de58ff0c01f78421b824c7f45d43959;hpb=5030a6b1909ce10f584fb8223f6af8110de45cff diff --git a/http_methods.c b/http_methods.c index 4b24935..053fce7 100644 --- a/http_methods.c +++ b/http_methods.c @@ -36,10 +36,13 @@ #include "php_http_message_object.h" #include "php_http_response_object.h" #include "php_http_request_object.h" +#include "php_http_requestpool_object.h" #include "php_http_exception_object.h" #ifdef ZEND_ENGINE_2 +#include "missing.h" + ZEND_EXTERN_MODULE_GLOBALS(http) /* {{{ HttpResponse */ @@ -505,7 +508,7 @@ PHP_METHOD(HttpResponse, getFile) } /* }}} */ -/* {{{ proto bool HttpResponse::send() +/* {{{ proto bool HttpResponse::send([bool clean_ob = true]) * * Finally send the entity. * @@ -522,14 +525,24 @@ PHP_METHOD(HttpResponse, getFile) */ PHP_METHOD(HttpResponse, send) { + zend_bool clean_ob = 1; zval *do_cache, *do_gzip; getObject(http_response_object, obj); - NO_ARGS; + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean_ob)) { + RETURN_FALSE; + } do_cache = GET_PROP(obj, cache); do_gzip = GET_PROP(obj, gzip); + if (clean_ob) { + /* interrupt on-the-fly etag generation */ + HTTP_G(etag).started = 0; + /* discard previous output buffers */ + php_end_ob_buffers(0 TSRMLS_CC); + } + /* gzip */ if (Z_LVAL_P(do_gzip)) { php_start_ob_buffer_named("ob_gzhandler", 0, 1 TSRMLS_CC); @@ -620,30 +633,6 @@ PHP_METHOD(HttpResponse, send) /* {{{ HttpMessage */ -/* {{{ proto static HttpMessage HttpMessage::fromString(string raw_message) - * - * Create an HttpMessage object from a string. - */ -PHP_METHOD(HttpMessage, fromString) -{ - char *string = NULL; - int length = 0; - http_message *msg = NULL; - http_message_object obj; - - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &string, &length)) { - RETURN_NULL(); - } - - if (!(msg = http_message_parse(string, length))) { - RETURN_NULL(); - } - - Z_TYPE_P(return_value) = IS_OBJECT; - return_value->value.obj = http_message_object_from_msg(msg); -} -/* }}} */ - /* {{{ proto void HttpMessage::__construct([string message]) * * Instantiate a new HttpMessage object. @@ -668,6 +657,29 @@ PHP_METHOD(HttpMessage, __construct) } /* }}} */ +/* {{{ proto static HttpMessage HttpMessage::fromString(string raw_message) + * + * Create an HttpMessage object from a string. + */ +PHP_METHOD(HttpMessage, fromString) +{ + char *string = NULL; + int length = 0; + http_message *msg = NULL; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &string, &length)) { + RETURN_NULL(); + } + + if (!(msg = http_message_parse(string, length))) { + RETURN_NULL(); + } + + Z_TYPE_P(return_value) = IS_OBJECT; + return_value->value.obj = http_message_object_from_msg(msg); +} +/* }}} */ + /* {{{ proto string HttpMessage::getBody() * * Get the body of the parsed Message. @@ -889,7 +901,6 @@ PHP_METHOD(HttpMessage, getRequestUri) NO_ARGS; IF_RETVAL_USED { - zval *uri; getObject(http_message_object, obj); if (!HTTP_MSG_TYPE(REQUEST, obj->message)) { @@ -972,7 +983,7 @@ PHP_METHOD(HttpMessage, getHttpVersion) PHP_METHOD(HttpMessage, setHttpVersion) { char v[4]; - zval *zv, *version; + zval *zv; getObject(http_message_object, obj); if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &zv)) { @@ -1716,6 +1727,29 @@ PHP_METHOD(HttpRequest, addPostFile) } /* }}} */ +/* {{{ proto bool HttpRequest::setPostFiles() + * + * Set files to post. + * Overwrites previously set post files. + * Affects only POST requests. + */ +PHP_METHOD(HttpRequest, setPostFiles) +{ + zval *files, *pFiles; + getObject(http_request_object, obj); + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &files)) { + RETURN_FALSE; + } + + pFiles = GET_PROP(obj, postFiles); + zend_hash_clean(Z_ARRVAL_P(pFiles)); + array_copy(files, pFiles); + + RETURN_TRUE; +} +/* }}} */ + /* {{{ proto array HttpRequest::getPostFiles() * * Get all previously added POST files. @@ -1753,6 +1787,59 @@ PHP_METHOD(HttpRequest, unsetPostFiles) } /* }}} */ +/* {{{ proto bool HttpRequest::SetPutFile(string file) + * + * Set file to put. + * Affects only PUT requests. + */ +PHP_METHOD(HttpRequest, setPutFile) +{ + char *file; + int file_len; + getObject(http_request_object, obj); + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len)) { + RETURN_FALSE; + } + + UPD_PROP(obj, string, putFile, file); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto string HttpRequest::getPutFile() + * + * Get previously set put file. + */ +PHP_METHOD(HttpRequest, getPutFile) +{ + NO_ARGS; + + IF_RETVAL_USED { + zval *putfile; + getObject(http_request_object, obj); + + putfile = GET_PROP(obj, putFile); + RETVAL_STRINGL(Z_STRVAL_P(putfile), Z_STRLEN_P(putfile), 1); + } +} +/* }}} */ + +/* {{{ proto void HttpRequest::unsetPutFile() + * + * Unset file to put. + * Affects only PUT requests. + */ +PHP_METHOD(HttpRequest, unsetPutFile) +{ + getObject(http_request_object, obj); + + NO_ARGS; + + UPD_PROP(obj, string, putFile, ""); +} +/* }}} */ + /* {{{ proto array HttpRequest::getResponseData() * * Get all response data after the request has been sent. @@ -2025,130 +2112,111 @@ PHP_METHOD(HttpRequest, getResponseMessage) PHP_METHOD(HttpRequest, send) { STATUS status = FAILURE; - zval *meth, *URL, *qdata, *opts, *info, *resp; - char *request_uri; + http_request_body body = {0}; getObject(http_request_object, obj); NO_ARGS; SET_EH_THROW_HTTP(); - if ((!obj->ch) && (!(obj->ch = curl_easy_init()))) { - http_error(E_WARNING, HTTP_E_CURL, "Could not initilaize curl"); + if (obj->pool) { + http_error(E_WARNING, HTTP_E_CURL, "You cannot call HttpRequest::send() while attached to an HttpRequestPool"); RETURN_FALSE; } - meth = GET_PROP(obj, method); - URL = GET_PROP(obj, url); - qdata = GET_PROP(obj, queryData); - opts = GET_PROP(obj, options); - info = GET_PROP(obj, responseInfo); - resp = GET_PROP(obj, responseData); - - // HTTP_URI_MAXLEN+1 long char * - if (!(request_uri = http_absolute_uri_ex(Z_STRVAL_P(URL), Z_STRLEN_P(URL), NULL, 0, NULL, 0, 0))) { - RETURN_FALSE; + if (SUCCESS == (status = http_request_object_requesthandler(obj, getThis(), &body))) { + zval *info = GET_PROP(obj, responseInfo); + status = http_request_exec(obj->ch, Z_ARRVAL_P(info)); + SET_PROP(obj, responseInfo, info); } + http_request_body_dtor(&body); - if (Z_STRLEN_P(qdata) && (strlen(request_uri) < HTTP_URI_MAXLEN)) { - if (!strchr(request_uri, '?')) { - strcat(request_uri, "?"); - } else { - strcat(request_uri, "&"); - } - strncat(request_uri, Z_STRVAL_P(qdata), HTTP_URI_MAXLEN - strlen(request_uri)); + /* final data handling */ + if (SUCCESS == status) { + status = http_request_object_responsehandler(obj, getThis(), NULL); } - switch (Z_LVAL_P(meth)) - { - case HTTP_GET: - case HTTP_HEAD: - status = http_request_ex(obj->ch, Z_LVAL_P(meth), request_uri, NULL, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); - break; - - case HTTP_PUT: - { - http_request_body body; - php_stream *stream; - php_stream_statbuf ssb; - zval *file = GET_PROP(obj, putFile); - - if ( (stream = php_stream_open_wrapper(Z_STRVAL_P(file), "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL)) && - !php_stream_stat(stream, &ssb)) { - body.type = HTTP_REQUEST_BODY_UPLOADFILE; - body.data = stream; - body.size = ssb.sb.st_size; - - status = http_put_ex(obj->ch, request_uri, &body, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); - http_request_body_dtor(&body); - } else { - status = FAILURE; - } - } - break; + SET_EH_NORMAL(); + RETURN_SUCCESS(status); +} +/* }}} */ - case HTTP_POST: - { - http_request_body body; - zval *fields = GET_PROP(obj, postFields), *files = GET_PROP(obj, postFiles); +/* {{{ HttpRequestPool */ - if (SUCCESS == (status = http_request_body_fill(&body, Z_ARRVAL_P(fields), Z_ARRVAL_P(files)))) { - status = http_post_ex(obj->ch, request_uri, &body, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); - http_request_body_dtor(&body); - } - } - break; +/* {{{ proto void HttpRequestPool::__construct(void) + * + * Instantiate a new HttpRequestPool object. + */ +PHP_METHOD(HttpRequestPool, __construct) +{ + NO_ARGS; +} +/* }}} */ - default: - { - http_request_body body; - zval *post = GET_PROP(obj, postData); +PHP_METHOD(HttpRequestPool, __destruct) +{ + getObject(http_requestpool_object, obj); + + NO_ARGS; + + http_requestpool_object_ondestruct(&obj->pool); +} - body.type = HTTP_REQUEST_BODY_CSTRING; - body.data = Z_STRVAL_P(post); - body.size = Z_STRLEN_P(post); +/* {{{ proto bool HttpRequestPool::attach(HttpRequest request) + * + * Attach an HttpRequest object to this HttpRequestPool. + * NOTE: set all options prior attaching! + */ +PHP_METHOD(HttpRequestPool, attach) +{ + zval *request; + STATUS status = FAILURE; + getObject(http_requestpool_object, obj); - status = http_request_ex(obj->ch, Z_LVAL_P(meth), request_uri, &body, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); - } - break; + SET_EH_THROW_HTTP(); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, http_request_object_ce)) { + status = http_request_pool_attach(&obj->pool, request); } + SET_EH_NORMAL(); + RETURN_SUCCESS(status); +} +/* }}} */ - efree(request_uri); - - /* final data handling */ - if (status == SUCCESS) { - http_message *msg; - - if (msg = http_message_parse(PHPSTR_VAL(&obj->response), PHPSTR_LEN(&obj->response))) { - zval *headers, *message; - char *body; - size_t body_len; - - UPD_PROP(obj, long, responseCode, msg->info.response.code); - - MAKE_STD_ZVAL(headers) - array_init(headers); - - zend_hash_copy(Z_ARRVAL_P(headers), &msg->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); - phpstr_data(PHPSTR(msg), &body, &body_len); - - add_assoc_zval(resp, "headers", headers); - add_assoc_stringl(resp, "body", body, body_len, 0); +/* {{{ proto bool HttpRequestPool::detach(HttpRequest request) + * + * Detach an HttpRequest object from this HttpRequestPool. + */ +PHP_METHOD(HttpRequestPool, detach) +{ + zval *request; + STATUS status = FAILURE; + getObject(http_requestpool_object, obj); - message = GET_PROP(obj, responseMessage); - zval_dtor(message); - Z_TYPE_P(message) = IS_OBJECT; - message->value.obj = http_message_object_from_msg(msg); - SET_PROP(obj, responseMessage, message); - } else { - status = FAILURE; - } + SET_EH_THROW_HTTP(); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, http_request_object_ce)) { + status = http_request_pool_detach(&obj->pool, request); } - SET_EH_NORMAL(); RETURN_SUCCESS(status); } /* }}} */ + +/* {{{ proto bool HttpRequestPool::send() + * + * Send all attached HttpRequest objects in parallel. + */ +PHP_METHOD(HttpRequestPool, send) +{ + getObject(http_requestpool_object, obj); + + NO_ARGS; + + RETURN_SUCCESS(http_request_pool_send(&obj->pool)); +} +/* }}} */ + +/* }}} */ + /* }}} */ #endif /* HTTP_HAVE_CURL */