X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_request_object.c;h=cbb8b2be93b0810b521c174a54b9c597021b8898;hp=6527cce5cefaefac8ba6293bf3ebb80d378862a1;hb=7482519f97dbcb643318a44da8ba9167205c441a;hpb=b562e34cf4f8c8fae7b8fe773e0eed71592b09c2 diff --git a/http_request_object.c b/http_request_object.c index 6527cce..cbb8b2b 100644 --- a/http_request_object.c +++ b/http_request_object.c @@ -158,6 +158,7 @@ HTTP_END_ARGS; HTTP_EMPTY_ARGS(getResponseMessage, 1); HTTP_EMPTY_ARGS(getRequestMessage, 1); HTTP_EMPTY_ARGS(getHistory, 1); +HTTP_EMPTY_ARGS(clearHistory, 0); HTTP_EMPTY_ARGS(send, 1); HTTP_BEGIN_ARGS(get, 0, 1) @@ -276,6 +277,7 @@ zend_function_entry http_request_object_fe[] = { HTTP_REQUEST_ME(getResponseMessage, ZEND_ACC_PUBLIC) HTTP_REQUEST_ME(getRequestMessage, ZEND_ACC_PUBLIC) HTTP_REQUEST_ME(getHistory, ZEND_ACC_PUBLIC) + HTTP_REQUEST_ME(clearHistory, ZEND_ACC_PUBLIC) HTTP_REQUEST_ALIAS(get, http_get) HTTP_REQUEST_ALIAS(head, http_head) @@ -296,45 +298,6 @@ static zend_object_handlers http_request_object_handlers; void _http_request_object_init(INIT_FUNC_ARGS) { HTTP_REGISTER_CLASS_EX(HttpRequest, http_request_object, NULL, 0); - - /* HTTP/1.1 */ - HTTP_LONG_CONSTANT("HTTP_GET", HTTP_GET); - HTTP_LONG_CONSTANT("HTTP_HEAD", HTTP_HEAD); - HTTP_LONG_CONSTANT("HTTP_POST", HTTP_POST); - HTTP_LONG_CONSTANT("HTTP_PUT", HTTP_PUT); - HTTP_LONG_CONSTANT("HTTP_DELETE", HTTP_DELETE); - HTTP_LONG_CONSTANT("HTTP_OPTIONS", HTTP_OPTIONS); - HTTP_LONG_CONSTANT("HTTP_TRACE", HTTP_TRACE); - HTTP_LONG_CONSTANT("HTTP_CONNECT", HTTP_CONNECT); - /* WebDAV - RFC 2518 */ - HTTP_LONG_CONSTANT("HTTP_PROPFIND", HTTP_PROPFIND); - HTTP_LONG_CONSTANT("HTTP_PROPPATCH", HTTP_PROPPATCH); - HTTP_LONG_CONSTANT("HTTP_MKCOL", HTTP_MKCOL); - HTTP_LONG_CONSTANT("HTTP_COPY", HTTP_COPY); - HTTP_LONG_CONSTANT("HTTP_MOVE", HTTP_MOVE); - HTTP_LONG_CONSTANT("HTTP_LOCK", HTTP_LOCK); - HTTP_LONG_CONSTANT("HTTP_UNLOCK", HTTP_UNLOCK); - /* WebDAV Versioning - RFC 3253 */ - HTTP_LONG_CONSTANT("HTTP_VERSION_CONTROL", HTTP_VERSION_CONTROL); - HTTP_LONG_CONSTANT("HTTP_REPORT", HTTP_REPORT); - HTTP_LONG_CONSTANT("HTTP_CHECKOUT", HTTP_CHECKOUT); - HTTP_LONG_CONSTANT("HTTP_CHECKIN", HTTP_CHECKIN); - HTTP_LONG_CONSTANT("HTTP_UNCHECKOUT", HTTP_UNCHECKOUT); - HTTP_LONG_CONSTANT("HTTP_MKWORKSPACE", HTTP_MKWORKSPACE); - HTTP_LONG_CONSTANT("HTTP_UPDATE", HTTP_UPDATE); - HTTP_LONG_CONSTANT("HTTP_LABEL", HTTP_LABEL); - HTTP_LONG_CONSTANT("HTTP_MERGE", HTTP_MERGE); - HTTP_LONG_CONSTANT("HTTP_BASELINE_CONTROL", HTTP_BASELINE_CONTROL); - HTTP_LONG_CONSTANT("HTTP_MKACTIVITY", HTTP_MKACTIVITY); - /* WebDAV Access Control - RFC 3744 */ - HTTP_LONG_CONSTANT("HTTP_ACL", HTTP_ACL); - - -# if LIBCURL_VERSION_NUM >= 0x070a05 - HTTP_LONG_CONSTANT("HTTP_AUTH_BASIC", CURLAUTH_BASIC); - HTTP_LONG_CONSTANT("HTTP_AUTH_DIGEST", CURLAUTH_DIGEST); - HTTP_LONG_CONSTANT("HTTP_AUTH_NTLM", CURLAUTH_NTLM); -# endif /* LIBCURL_VERSION_NUM */ } zend_object_value _http_request_object_new(zend_class_entry *ce TSRMLS_DC) @@ -345,7 +308,6 @@ zend_object_value _http_request_object_new(zend_class_entry *ce TSRMLS_DC) o = ecalloc(1, sizeof(http_request_object)); o->zo.ce = ce; o->ch = curl_easy_init(); - o->pool = NULL; phpstr_init(&o->history); phpstr_init(&o->request); @@ -382,6 +344,53 @@ static inline void _http_request_object_declare_default_properties(TSRMLS_D) DCL_PROP(PROTECTED, string, putFile, ""); DCL_PROP(PUBLIC, bool, recordHistory, 1); + +#ifndef WONKY + /* + * Request Method Constants + */ + /* HTTP/1.1 */ + DCL_CONST(long, "METH_GET", HTTP_GET); + DCL_CONST(long, "METH_HEAD", HTTP_HEAD); + DCL_CONST(long, "METH_POST", HTTP_POST); + DCL_CONST(long, "METH_PUT", HTTP_PUT); + DCL_CONST(long, "METH_DELETE", HTTP_DELETE); + DCL_CONST(long, "METH_OPTIONS", HTTP_OPTIONS); + DCL_CONST(long, "METH_TRACE", HTTP_TRACE); + DCL_CONST(long, "METH_CONNECT", HTTP_CONNECT); + /* WebDAV - RFC 2518 */ + DCL_CONST(long, "METH_PROPFIND", HTTP_PROPFIND); + DCL_CONST(long, "METH_PROPPATCH", HTTP_PROPPATCH); + DCL_CONST(long, "METH_MKCOL", HTTP_MKCOL); + DCL_CONST(long, "METH_COPY", HTTP_COPY); + DCL_CONST(long, "METH_MOVE", HTTP_MOVE); + DCL_CONST(long, "METH_LOCK", HTTP_LOCK); + DCL_CONST(long, "METH_UNLOCK", HTTP_UNLOCK); + /* WebDAV Versioning - RFC 3253 */ + DCL_CONST(long, "METH_VERSION_CONTROL", HTTP_VERSION_CONTROL); + DCL_CONST(long, "METH_REPORT", HTTP_REPORT); + DCL_CONST(long, "METH_CHECKOUT", HTTP_CHECKOUT); + DCL_CONST(long, "METH_CHECKIN", HTTP_CHECKIN); + DCL_CONST(long, "METH_UNCHECKOUT", HTTP_UNCHECKOUT); + DCL_CONST(long, "METH_MKWORKSPACE", HTTP_MKWORKSPACE); + DCL_CONST(long, "METH_UPDATE", HTTP_UPDATE); + DCL_CONST(long, "METH_LABEL", HTTP_LABEL); + DCL_CONST(long, "METH_MERGE", HTTP_MERGE); + DCL_CONST(long, "METH_BASELINE_CONTROL", HTTP_BASELINE_CONTROL); + DCL_CONST(long, "METH_MKACTIVITY", HTTP_MKACTIVITY); + /* WebDAV Access Control - RFC 3744 */ + DCL_CONST(long, "METH_ACL", HTTP_ACL); + + /* + * Auth Constants + */ +# if LIBCURL_VERSION_NUM >= 0x070a05 + DCL_CONST(long, "AUTH_BASIC", CURLAUTH_BASIC); + DCL_CONST(long, "AUTH_DIGEST", CURLAUTH_DIGEST); + DCL_CONST(long, "AUTH_NTLM", CURLAUTH_NTLM); + DCL_CONST(long, "AUTH_ANY", CURLAUTH_ANY); +# endif /* LIBCURL_VERSION_NUM */ +#endif /* WONKY */ } void _http_request_object_free(zend_object *object TSRMLS_DC) @@ -420,13 +429,13 @@ STATUS _http_request_object_requesthandler(http_request_object *obj, zval *this_ return FAILURE; } - URL = GET_PROP(obj, url); + URL = convert_to_type_ex(IS_STRING, GET_PROP(obj, url)); // 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 FAILURE; } - meth = GET_PROP(obj, method); + meth = convert_to_type_ex(IS_LONG, GET_PROP(obj, method)); switch (Z_LVAL_P(meth)) { case HTTP_GET: @@ -454,17 +463,20 @@ STATUS _http_request_object_requesthandler(http_request_object *obj, zval *this_ default: { /* check for raw post data */ - zval *raw_data = GET_PROP(obj, rawPostData); + zval *raw_data = convert_to_type_ex(IS_STRING, GET_PROP(obj, rawPostData)); if (Z_STRLEN_P(raw_data)) { - zval *ctype = GET_PROP(obj, contentType); + zval *ctype = convert_to_type_ex(IS_STRING, GET_PROP(obj, contentType)); if (Z_STRLEN_P(ctype)) { zval **headers, *opts = GET_PROP(obj, options); + convert_to_array(opts); + if (SUCCESS == zend_hash_find(Z_ARRVAL_P(opts), "headers", sizeof("headers"), (void **) &headers)) { zval **ct_header; + convert_to_array(*headers); /* only override if not already set */ if (SUCCESS != zend_hash_find(Z_ARRVAL_PP(headers), "Content-Type", sizeof("Content-Type"), (void **) &ct_header)) { add_assoc_stringl(*headers, "Content-Type", Z_STRVAL_P(ctype), Z_STRLEN_P(ctype), 1); @@ -490,7 +502,7 @@ STATUS _http_request_object_requesthandler(http_request_object *obj, zval *this_ } if (status == SUCCESS) { - zval *qdata = GET_PROP(obj, queryData); + zval *qdata = convert_to_type_ex(IS_STRING, GET_PROP(obj, queryData)); if (Z_STRLEN_P(qdata) && (strlen(request_uri) < HTTP_URI_MAXLEN)) { if (!strchr(request_uri, '?')) { @@ -528,15 +540,10 @@ STATUS _http_request_object_responsehandler(http_request_object *obj, zval *this char *body; size_t body_len; zval *headers, *message, - *resp = GET_PROP(obj, responseData), - *info = GET_PROP(obj, responseInfo), - *hist = GET_PROP(obj, recordHistory); + *resp = convert_to_type(IS_ARRAY, GET_PROP(obj, responseData)), + *info = convert_to_type(IS_ARRAY, GET_PROP(obj, responseInfo)); - /* should we record history? */ - if (Z_TYPE_P(hist) != IS_BOOL) { - convert_to_boolean(hist); - } - if (Z_LVAL_P(hist)) { + 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 * for redirects @@ -596,9 +603,10 @@ static inline void _http_request_object_set_options_subr(INTERNAL_FUNCTION_PARAM RETURN_FALSE; } - opts = GET_PROP(obj, options); + opts = convert_to_type(IS_ARRAY, GET_PROP(obj, options)); if (SUCCESS == zend_hash_find(Z_ARRVAL_P(opts), key, len, (void **) &options)) { + convert_to_array(*options); if (overwrite) { zend_hash_clean(Z_ARRVAL_PP(options)); } @@ -627,11 +635,12 @@ static inline void _http_request_get_options_subr(INTERNAL_FUNCTION_PARAMETERS, zval *opts, **options; getObject(http_request_object, obj); - opts = GET_PROP(obj, options); + opts = convert_to_type_ex(IS_ARRAY, GET_PROP(obj, options)); array_init(return_value); if (SUCCESS == zend_hash_find(Z_ARRVAL_P(opts), key, len, (void **) &options)) { + convert_to_array(*options); array_copy(*options, return_value); } } @@ -640,10 +649,15 @@ static inline void _http_request_get_options_subr(INTERNAL_FUNCTION_PARAMETERS, /* ### USERLAND ### */ -/* {{{ proto void HttpRequest::__construct([string url[, long request_method = HTTP_GET]]) +/* {{{ proto void HttpRequest::__construct([string url[, int request_method = HTTP_METH_GET]]) * - * Instantiate a new HttpRequest object which can be used to issue HEAD, GET - * and POST (including posting files) HTTP requests. + * Instantiate a new HttpRequest object. + * + * Accepts a string as optional parameter containing the target request url. + * Additianally accepts an optional int parameter specifying the request method + * to use. + * + * Throws HttpException. */ PHP_METHOD(HttpRequest, __construct) { @@ -692,6 +706,12 @@ PHP_METHOD(HttpRequest, __destruct) /* {{{ proto bool HttpRequest::setOptions([array options]) * * Set the request options to use. See http_get() for a full list of available options. + * + * Accepts an array as optional parameters, wich values will overwrite the + * currently set request options. If the parameter is empty or mitted, + * the optoions of the HttpRequest object will be reset. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, setOptions) { @@ -704,7 +724,7 @@ PHP_METHOD(HttpRequest, setOptions) RETURN_FALSE; } - old_opts = GET_PROP(obj, options); + old_opts = convert_to_type(IS_ARRAY, GET_PROP(obj, options)); if (!opts || !zend_hash_num_elements(Z_ARRVAL_P(opts))) { zend_hash_clean(Z_ARRVAL_P(old_opts)); @@ -717,22 +737,28 @@ PHP_METHOD(HttpRequest, setOptions) if (!strcmp(key, "headers")) { zval **headers; if (SUCCESS == zend_hash_find(Z_ARRVAL_P(old_opts), "headers", sizeof("headers"), (void **) &headers)) { + convert_to_array(*opt); + convert_to_array(*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)) { + convert_to_array(*opt); + convert_to_array(*cookies); array_merge(*opt, *cookies); continue; } } else if (!strcmp(key, "ssl")) { zval **ssl; if (SUCCESS == zend_hash_find(Z_ARRVAL_P(old_opts), "ssl", sizeof("ssl"), (void **) &ssl)) { + convert_to_array(*opt); + convert_to_array(*ssl); array_merge(*opt, *ssl); continue; } - }else if ((!strcasecmp(key, "url")) || (!strcasecmp(key, "uri"))) { + } else if ((!strcasecmp(key, "url")) || (!strcasecmp(key, "uri"))) { if (Z_TYPE_PP(opt) != IS_STRING) { convert_to_string_ex(opt); } @@ -761,6 +787,8 @@ PHP_METHOD(HttpRequest, setOptions) /* {{{ proto array HttpRequest::getOptions() * * Get currently set options. + * + * Returns an associative array containing currently set options. */ PHP_METHOD(HttpRequest, getOptions) { @@ -770,7 +798,7 @@ PHP_METHOD(HttpRequest, getOptions) zval *opts; getObject(http_request_object, obj); - opts = GET_PROP(obj, options); + opts = convert_to_type_ex(IS_ARRAY, GET_PROP(obj, options)); array_init(return_value); array_copy(opts, return_value); } @@ -780,6 +808,11 @@ PHP_METHOD(HttpRequest, getOptions) /* {{{ proto bool HttpRequest::setSslOptions([array options]) * * Set SSL options. + * + * Accepts an associative array as parameter containing any SSL specific options. + * If the parameter is empty or omitted, the SSL options will be reset. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, setSslOptions) { @@ -790,6 +823,10 @@ PHP_METHOD(HttpRequest, setSslOptions) /* {{{ proto bool HttpRequest::addSslOptions(array options) * * Set additional SSL options. + * + * Expects an associative array as parameter containing additional SSL specific options. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, addSslOptions) { @@ -800,6 +837,8 @@ PHP_METHOD(HttpRequest, addSslOptions) /* {{{ proto array HttpRequest::getSslOtpions() * * Get previously set SSL options. + * + * Returns an associative array containing any previously set SSL options. */ PHP_METHOD(HttpRequest, getSslOptions) { @@ -810,6 +849,11 @@ PHP_METHOD(HttpRequest, getSslOptions) /* {{{ proto bool HttpRequest::addHeaders(array headers) * * Add request header name/value pairs. + * + * Expects an ssociative array as parameter containing additional header + * name/value pairs. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, addHeaders) { @@ -819,6 +863,11 @@ PHP_METHOD(HttpRequest, addHeaders) /* {{{ proto bool HttpRequest::setHeaders([array headers]) * * Set request header name/value pairs. + * + * Accepts an associative array as parameter containing header name/value pairs. + * If the parameter is empty or omitted, all previously set headers will be unset. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, setHeaders) { @@ -829,6 +878,8 @@ PHP_METHOD(HttpRequest, setHeaders) /* {{{ proto array HttpRequest::getHeaders() * * Get previously set request headers. + * + * Returns an associative array containing all currently set headers. */ PHP_METHOD(HttpRequest, getHeaders) { @@ -839,6 +890,11 @@ PHP_METHOD(HttpRequest, getHeaders) /* {{{ proto bool HttpRequest::setCookies([array cookies]) * * Set cookies. + * + * Accepts an associative array as parameter containing cookie name/value pairs. + * If the parameter is empty or omitted, all previously set cookies will be unset. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, setCookies) { @@ -849,6 +905,11 @@ PHP_METHOD(HttpRequest, setCookies) /* {{{ proto bool HttpRequest::addCookies(array cookies) * * Add cookies. + * + * Expects an associative array as parameter containing any cookie name/value + * pairs to add. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, addCookies) { @@ -859,6 +920,8 @@ PHP_METHOD(HttpRequest, addCookies) /* {{{ proto array HttpRequest::getCookies() * * Get previously set cookies. + * + * Returns an associative array containing any previously set cookies. */ PHP_METHOD(HttpRequest, getCookies) { @@ -869,6 +932,10 @@ PHP_METHOD(HttpRequest, getCookies) /* {{{ proto bool HttpRequest::setUrl(string url) * * Set the request URL. + * + * Expects a string as parameter specifying the request url. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, setUrl) { @@ -888,25 +955,30 @@ PHP_METHOD(HttpRequest, setUrl) /* {{{ proto string HttpRequest::getUrl() * * Get the previously set request URL. + * + * Returns the currently set request url as string. */ PHP_METHOD(HttpRequest, getUrl) { NO_ARGS; IF_RETVAL_USED { - zval *URL; getObject(http_request_object, obj); + zval *URL = GET_PROP(obj, url); - URL = GET_PROP(obj, url); - RETURN_STRINGL(Z_STRVAL_P(URL), Z_STRLEN_P(URL), 1); + RETURN_ZVAL(URL, 1, 0); } } /* }}} */ -/* {{{ proto bool HttpRequest::setMethod(long request_method) +/* {{{ proto bool HttpRequest::setMethod(int request_method) * - * Set the request methods; one of the HTTP_HEAD, HTTP_GET or - * HTTP_POST constants. + * Set the request method. + * + * Expects an int as parameter specifying the request method to use. + * In PHP 5.1+ HttpRequest::METH, otherwise the HTTP_METH constants can be used. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, setMethod) { @@ -922,20 +994,21 @@ PHP_METHOD(HttpRequest, setMethod) } /* }}} */ -/* {{{ proto long HttpRequest::getMethod() +/* {{{ proto int HttpRequest::getMethod() * * Get the previously set request method. + * + * Returns the currently set request method. */ PHP_METHOD(HttpRequest, getMethod) { NO_ARGS; IF_RETVAL_USED { - zval *meth; getObject(http_request_object, obj); - - meth = GET_PROP(obj, method); - RETURN_LONG(Z_LVAL_P(meth)); + zval *meth = GET_PROP(obj, method); + + RETURN_ZVAL(meth, 1, 0); } } /* }}} */ @@ -943,7 +1016,12 @@ PHP_METHOD(HttpRequest, getMethod) /* {{{ proto bool HttpRequest::setContentType(string content_type) * * Set the content type the post request should have. - * Use this only if you know what you're doing. + * + * Expects a string as parameters containing the content type of the request + * (primary/secondary). + * + * Returns TRUE on success, or FALSE if the content type does not seem to + * contain a primary and a secondary part. */ PHP_METHOD(HttpRequest, setContentType) { @@ -968,26 +1046,32 @@ PHP_METHOD(HttpRequest, setContentType) /* {{{ proto string HttpRequest::getContentType() * * Get the previously content type. + * + * Returns the previously set content type as string. */ PHP_METHOD(HttpRequest, getContentType) { NO_ARGS; IF_RETVAL_USED { - zval *ctype; getObject(http_request_object, obj); - - ctype = GET_PROP(obj, contentType); - RETURN_STRINGL(Z_STRVAL_P(ctype), Z_STRLEN_P(ctype), 1); + zval *ctype = GET_PROP(obj, contentType); + + RETURN_ZVAL(ctype, 1, 0); } } /* }}} */ /* {{{ proto bool HttpRequest::setQueryData([mixed query_data]) * - * Set the URL query parameters to use. - * Overwrites previously set query parameters. + * Set the URL query parameters to use, overwriting previously set query parameters. * Affects any request types. + * + * Accepts a string or associative array parameter containing the pre-encoded + * query string or to be encoded query fields. If the parameter is empty or + * omitted, the query data will be unset. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, setQueryData) { @@ -1010,7 +1094,7 @@ PHP_METHOD(HttpRequest, setQueryData) UPD_PROP(obj, string, queryData, query_data); efree(query_data); } else { - convert_to_string(qdata); + convert_to_string_ex(&qdata); UPD_STRL(obj, queryData, Z_STRVAL_P(qdata), Z_STRLEN_P(qdata)); } RETURN_TRUE; @@ -1020,25 +1104,30 @@ PHP_METHOD(HttpRequest, setQueryData) /* {{{ proto string HttpRequest::getQueryData() * * Get the current query data in form of an urlencoded query string. + * + * Returns a string containing the urlencoded query. */ PHP_METHOD(HttpRequest, getQueryData) { NO_ARGS; IF_RETVAL_USED { - zval *qdata; getObject(http_request_object, obj); - - qdata = GET_PROP(obj, queryData); - RETURN_STRINGL(Z_STRVAL_P(qdata), Z_STRLEN_P(qdata), 1); + zval *qdata = convert_to_type_ex(IS_STRING, GET_PROP(obj, queryData)); + + RETURN_ZVAL(qdata, 1, 0); } } /* }}} */ /* {{{ proto bool HttpRequest::addQueryData(array query_params) * - * Add parameters to the query parameter list. + * Add parameters to the query parameter list, leaving previously set unchanged. * Affects any request type. + * + * Expects an associative array as parameter containing the query fields to add. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, addQueryData) { @@ -1051,7 +1140,7 @@ PHP_METHOD(HttpRequest, addQueryData) RETURN_FALSE; } - old_qdata = GET_PROP(obj, queryData); + old_qdata = convert_to_type_ex(IS_STRING, GET_PROP(obj, queryData)); if (SUCCESS != http_urlencode_hash_ex(HASH_OF(qdata), 1, Z_STRVAL_P(old_qdata), Z_STRLEN_P(old_qdata), &query_data, &query_data_len)) { RETURN_FALSE; @@ -1066,8 +1155,13 @@ PHP_METHOD(HttpRequest, addQueryData) /* {{{ proto bool HttpRequest::addPostFields(array post_data) * - * Adds POST data entries. - * Affects only POST requests. + * Adds POST data entries, leaving previously set unchanged, unless a + * post entry with the same name already exists. + * Affects only POST and custom requests. + * + * Expects an associative array as parameter containing the post fields. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, addPostFields) { @@ -1078,7 +1172,7 @@ PHP_METHOD(HttpRequest, addPostFields) RETURN_FALSE; } - post = GET_PROP(obj, postFields); + post = convert_to_type(IS_ARRAY, GET_PROP(obj, postFields)); array_merge(post_data, post); RETURN_TRUE; @@ -1087,9 +1181,13 @@ PHP_METHOD(HttpRequest, addPostFields) /* {{{ proto bool HttpRequest::setPostFields([array post_data]) * - * Set the POST data entries. - * Overwrites previously set POST data. - * Affects only POST requests. + * Set the POST data entries, overwriting previously set POST data. + * Affects only POST and custom requests. + * + * Accepts an associative array as parameter containing the post fields. + * If the parameter is empty or omitted, the post data will be unset. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, setPostFields) { @@ -1100,7 +1198,7 @@ PHP_METHOD(HttpRequest, setPostFields) RETURN_FALSE; } - post = GET_PROP(obj, postFields); + post = convert_to_type(IS_ARRAY, GET_PROP(obj, postFields)); zend_hash_clean(Z_ARRVAL_P(post)); if (post_data && zend_hash_num_elements(Z_ARRVAL_P(post_data))) { @@ -1114,16 +1212,17 @@ PHP_METHOD(HttpRequest, setPostFields) /* {{{ proto array HttpRequest::getPostFields() * * Get previously set POST data. + * + * Returns the currently set post fields as associative array. */ PHP_METHOD(HttpRequest, getPostFields) { NO_ARGS; IF_RETVAL_USED { - zval *post_data; getObject(http_request_object, obj); - - post_data = GET_PROP(obj, postFields); + zval *post_data = convert_to_type_ex(IS_ARRAY, GET_PROP(obj, postFields)); + array_init(return_value); array_copy(post_data, return_value); } @@ -1132,8 +1231,15 @@ PHP_METHOD(HttpRequest, getPostFields) /* {{{ proto bool HttpRequest::setRawPostData([string raw_post_data]) * - * Set raw post data to send. Don't forget to specify a content type. - * Affects only POST requests. + * Set raw post data to send, overwriting previously set raw post data. Don't + * forget to specify a content type. Affects only POST and custom requests. + * Only either post fields or raw post data can be used for each request. + * Raw post data has higher precedence and will be used even if post fields + * are set. + * + * Accepts a string as parameter containing the *raw* post data. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, setRawPostData) { @@ -1156,8 +1262,12 @@ PHP_METHOD(HttpRequest, setRawPostData) /* {{{ proto bool HttpRequest::addRawPostData(string raw_post_data) * - * Add raw post data. - * Affects only POST requests. + * Add raw post data, leaving previously set raw post data unchanged. + * Affects only POST and custom requests. + * + * Expects a string as parameter containing the raw post data to concatenate. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, addRawPostData) { @@ -1170,7 +1280,7 @@ PHP_METHOD(HttpRequest, addRawPostData) } if (data_len) { - zval *zdata = GET_PROP(obj, rawPostData); + zval *zdata = convert_to_type_ex(IS_STRING, GET_PROP(obj, rawPostData)); new_data = emalloc(Z_STRLEN_P(zdata) + data_len + 1); new_data[Z_STRLEN_P(zdata) + data_len] = '\0'; @@ -1190,6 +1300,8 @@ PHP_METHOD(HttpRequest, addRawPostData) /* {{{ proto string HttpRequest::getRawPostData() * * Get previously set raw post data. + * + * Returns a string containing the currently set raw post data. */ PHP_METHOD(HttpRequest, getRawPostData) { @@ -1197,17 +1309,25 @@ PHP_METHOD(HttpRequest, getRawPostData) IF_RETVAL_USED { getObject(http_request_object, obj); - zval *raw_data = GET_PROP(obj, rawPostData); + zval *raw_data = convert_to_type_ex(IS_STRING, GET_PROP(obj, rawPostData)); - RETURN_STRINGL(Z_STRVAL_P(raw_data), Z_STRLEN_P(raw_data), 1); + RETURN_ZVAL(raw_data, 1, 0); } } /* }}} */ /* {{{ proto bool HttpRequest::addPostFile(string name, string file[, string content_type = "application/x-octetstream"]) * - * Add a file to the POST request. - * Affects only POST requests. + * Add a file to the POST request, leaving prefiously set files unchanged. + * Affects only POST and custom requests. Cannot be used with raw post data. + * + * Expects a string parameter containing the form element name, and a string + * paremeter containing the path to the file which should be uploaded. + * Additionally accepts an optional string parameter which chould contain + * the content type of the file. + * + * Returns TRUE on success, or FALSE if the content type seems not to contain a + * primary and a secondary content type part. */ PHP_METHOD(HttpRequest, addPostFile) { @@ -1237,7 +1357,7 @@ PHP_METHOD(HttpRequest, addPostFile) add_assoc_stringl(entry, "type", type, type_len, 1); add_assoc_stringl(entry, "file", file, file_len, 1); - files = GET_PROP(obj, postFiles); + files = convert_to_type(IS_ARRAY, GET_PROP(obj, postFiles)); add_next_index_zval(files, entry); RETURN_TRUE; @@ -1246,9 +1366,14 @@ PHP_METHOD(HttpRequest, addPostFile) /* {{{ proto bool HttpRequest::setPostFiles([array post_files]) * - * Set files to post. - * Overwrites previously set post files. - * Affects only POST requests. + * Set files to post, overwriting previously set post files. + * Affects only POST and requests. Cannot be used with raw post data. + * + * Accepts an array containing the files to post. Each entry should be an + * associative array with "name", "file" and "type" keys. If the parameter + * is empty or omitted the post files will be unset. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, setPostFiles) { @@ -1259,7 +1384,7 @@ PHP_METHOD(HttpRequest, setPostFiles) RETURN_FALSE; } - pFiles = GET_PROP(obj, postFiles); + pFiles = convert_to_type(IS_ARRAY, GET_PROP(obj, postFiles)); zend_hash_clean(Z_ARRVAL_P(pFiles)); if (files && zend_hash_num_elements(Z_ARRVAL_P(files))) { @@ -1273,16 +1398,16 @@ PHP_METHOD(HttpRequest, setPostFiles) /* {{{ proto array HttpRequest::getPostFiles() * * Get all previously added POST files. + * + * Returns an array containing currently set post files. */ PHP_METHOD(HttpRequest, getPostFiles) { NO_ARGS; IF_RETVAL_USED { - zval *files; getObject(http_request_object, obj); - - files = GET_PROP(obj, postFiles); + zval *files = convert_to_type_ex(IS_ARRAY, GET_PROP(obj, postFiles)); array_init(return_value); array_copy(files, return_value); @@ -1292,8 +1417,12 @@ PHP_METHOD(HttpRequest, getPostFiles) /* {{{ proto bool HttpRequest::setPutFile([string file]) * - * Set file to put. - * Affects only PUT requests. + * Set file to put. Affects only PUT requests. + * + * Accepts a string as parameter referencing the path to file. + * If the parameter is empty or omitted the put file will be unset. + * + * Returns TRUE on success, or FALSE on failure. */ PHP_METHOD(HttpRequest, setPutFile) { @@ -1313,17 +1442,18 @@ PHP_METHOD(HttpRequest, setPutFile) /* {{{ proto string HttpRequest::getPutFile() * * Get previously set put file. + * + * Returns a string containing the path to the currently 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); + zval *putfile = convert_to_type_ex(IS_STRING, GET_PROP(obj, putFile)); + + RETURN_ZVAL(putfile, 1, 0); } } /* }}} */ @@ -1331,16 +1461,22 @@ PHP_METHOD(HttpRequest, getPutFile) /* {{{ proto array HttpRequest::getResponseData() * * Get all response data after the request has been sent. + * + * Returns an associative array with the key "headers" containing an associative + * array holding all response headers, as well as the ley "body" containing a + * string with the response body. + * + * If redirects were allowed and several responses were received, the data + * references the last received response. */ PHP_METHOD(HttpRequest, getResponseData) { NO_ARGS; IF_RETVAL_USED { - zval *data; getObject(http_request_object, obj); - - data = GET_PROP(obj, responseData); + zval *data = convert_to_type_ex(IS_ARRAY, GET_PROP(obj, responseData)); + array_init(return_value); array_copy(data, return_value); } @@ -1350,6 +1486,15 @@ PHP_METHOD(HttpRequest, getResponseData) /* {{{ proto mixed HttpRequest::getResponseHeader([string name]) * * Get response header(s) after the request has been sent. + * + * Accepts an string as optional parameter specifying a certain header to read. + * If the parameter is empty or omitted all response headers will be returned. + * + * Returns either a string with the value of the header matching name if requested, + * FALSE on failure, or an associative array containing all reponse headers. + * + * If redirects were allowed and several responses were received, the data + * references the last received response. */ PHP_METHOD(HttpRequest, getResponseHeader) { @@ -1363,16 +1508,16 @@ PHP_METHOD(HttpRequest, getResponseHeader) RETURN_FALSE; } - data = GET_PROP(obj, responseData); + data = convert_to_type_ex(IS_ARRAY, GET_PROP(obj, responseData)); if (SUCCESS != zend_hash_find(Z_ARRVAL_P(data), "headers", sizeof("headers"), (void **) &headers)) { RETURN_FALSE; } - + convert_to_array_ex(headers); if (!header_len || !header_name) { array_init(return_value); array_copy(*headers, return_value); } else if (SUCCESS == zend_hash_find(Z_ARRVAL_PP(headers), pretty_key(header_name, header_len, 1, 1), header_len + 1, (void **) &header)) { - RETURN_STRINGL(Z_STRVAL_PP(header), Z_STRLEN_PP(header), 1); + RETURN_ZVAL(*header, 1, 0); } else { RETURN_FALSE; } @@ -1383,6 +1528,17 @@ PHP_METHOD(HttpRequest, getResponseHeader) /* {{{ proto array HttpRequest::getResponseCookie([string name]) * * Get response cookie(s) after the request has been sent. + * + * Accepts a string as optional parameter specifying the name of the cookie to read. + * If the parameter is empty or omitted, an associative array with all received + * cookies will be returned. + * + * Returns either an associative array with the cookie's name, value and any + * additional params of the cookie matching name if requested, FALSE on failure, + * or an array containing all received cookies as arrays. + * + * If redirects were allowed and several responses were received, the data + * references the last received response. */ PHP_METHOD(HttpRequest, getResponseCookie) { @@ -1398,12 +1554,13 @@ PHP_METHOD(HttpRequest, getResponseCookie) array_init(return_value); - data = GET_PROP(obj, responseData); + data = convert_to_type_ex(IS_ARRAY, GET_PROP(obj, responseData)); if (SUCCESS == zend_hash_find(Z_ARRVAL_P(data), "headers", sizeof("headers"), (void **) &headers)) { ulong idx = 0; char *key = NULL; zval **header = NULL; + convert_to_array_ex(headers); FOREACH_HASH_KEYVAL(Z_ARRVAL_PP(headers), key, idx, header) { if (key && !strcasecmp(key, "Set-Cookie")) { /* several cookies? */ @@ -1437,9 +1594,11 @@ PHP_METHOD(HttpRequest, getResponseCookie) } } else { zval *cookie_hash; + MAKE_STD_ZVAL(cookie_hash); array_init(cookie_hash); - + convert_to_string_ex(header); + if (SUCCESS == http_parse_cookie(Z_STRVAL_PP(header), Z_ARRVAL_P(cookie_hash))) { if (!cookie_len) { add_next_index_zval(return_value, cookie_hash); @@ -1472,18 +1631,24 @@ PHP_METHOD(HttpRequest, getResponseCookie) /* {{{ proto string HttpRequest::getResponseBody() * * Get the response body after the request has been sent. + * + * Returns a string containing the response body. + * + * If redirects were allowed and several responses were received, the data + * references the last received response. */ PHP_METHOD(HttpRequest, getResponseBody) { NO_ARGS; IF_RETVAL_USED { - zval *data, **body; + zval **body; getObject(http_request_object, obj); - - data = GET_PROP(obj, responseData); + zval *data = convert_to_type_ex(IS_ARRAY, GET_PROP(obj, responseData)); + if (SUCCESS == zend_hash_find(Z_ARRVAL_P(data), "body", sizeof("body"), (void **) &body)) { - RETURN_STRINGL(Z_STRVAL_PP(body), Z_STRLEN_PP(body), 1); + convert_to_string_ex(body); + RETURN_ZVAL(*body, 1, 0); } else { RETURN_FALSE; } @@ -1494,25 +1659,40 @@ PHP_METHOD(HttpRequest, getResponseBody) /* {{{ proto int HttpRequest::getResponseCode() * * Get the response code after the request has been sent. + * + * Returns an int representing the response code. + * + * If redirects were allowed and several responses were received, the data + * references the last received response. */ PHP_METHOD(HttpRequest, getResponseCode) { NO_ARGS; IF_RETVAL_USED { - zval *code; getObject(http_request_object, obj); - - code = GET_PROP(obj, responseCode); - RETURN_LONG(Z_LVAL_P(code)); + zval *code = convert_to_type_ex(IS_LONG, GET_PROP(obj, responseCode)); + + RETURN_ZVAL(code, 1, 0); } } /* }}} */ -/* {{{ proto array HttpRequest::getResponseInfo([string name]) +/* {{{ proto mixed HttpRequest::getResponseInfo([string name]) * * Get response info after the request has been sent. * See http_get() for a full list of returned info. + * + * Accepts a string as optional parameter specifying the info to read. + * If the parameter is empty or omitted, an associative array containing + * all available info will be returned. + * + * Returns either a scalar containing the value of the info matching name if + * requested, FALSE on failure, or an associative array containing all + * available info. + * + * If redirects were allowed and several responses were received, the data + * references the last received response. */ PHP_METHOD(HttpRequest, getResponseInfo) { @@ -1526,7 +1706,7 @@ PHP_METHOD(HttpRequest, getResponseInfo) RETURN_FALSE; } - info = GET_PROP(obj, responseInfo); + info = convert_to_type_ex(IS_ARRAY, GET_PROP(obj, responseInfo)); if (info_len && info_name) { if (SUCCESS == zend_hash_find(Z_ARRVAL_P(info), pretty_key(info_name, info_len, 0, 0), info_len + 1, (void **) &infop)) { @@ -1545,7 +1725,16 @@ PHP_METHOD(HttpRequest, getResponseInfo) /* {{{ proto HttpMessage HttpRequest::getResponseMessage() * - * Get the full response as HttpMessage object. + * Get the full response as HttpMessage object after the request has been sent. + * + * Returns an HttpMessage object of the response. + * + * If redirects were allowed and several responses were received, the data + * references the last received response. Use HttpMessage::getParentMessage() + * to access the data of previously received responses whithin this request + * cycle. + * + * Throws HttpException. */ PHP_METHOD(HttpRequest, getResponseMessage) { @@ -1570,6 +1759,13 @@ PHP_METHOD(HttpRequest, getResponseMessage) /* {{{ proto HttpMessage HttpRequest::getRequestMessage() * * Get sent HTTP message. + * + * Returns an HttpMessage object representing the sent request. + * + * If redirects were allowed and several responses were received, the data + * references the last received response. Use HttpMessage::getParentMessage() + * to access the data of previously sent requests whithin this request + * cycle. */ PHP_METHOD(HttpRequest, getRequestMessage) { @@ -1588,6 +1784,21 @@ PHP_METHOD(HttpRequest, getRequestMessage) } /* }}} */ +/* {{{ proto HttpMessage HttpRequest::getHistory() + * + * Get all sent requests and received responses as an HttpMessage object. + * + * If you don't want to record history at all, set the instance variable + * HttpRequest::$recoedHistory to FALSE. + * + * Returns an HttpMessage object representing the complete request/response + * history. + * + * The object references the last received response, use HttpMessage::getParentMessage() + * to access the data of previously sent requests and received responses. + * + * Throws HttpMalformedHeaderException. + */ PHP_METHOD(HttpRequest, getHistory) { NO_ARGS; @@ -1603,10 +1814,29 @@ PHP_METHOD(HttpRequest, getHistory) SET_EH_NORMAL(); } } +/* }}} */ + +/* {{{ proto void HttpRequest::clearHistory() + * + * Clear the history. + */ +PHP_METHOD(HttpRequest, clearHistory) +{ + NO_ARGS { + getObject(http_request_object, obj); + phpstr_dtor(&obj->history); + } +} +/* }}} */ /* {{{ proto HttpMessage HttpRequest::send() * * Send the HTTP request. + * + * Returns the received response as HttpMessage object. + * + * Throws HttpRuntimeException, HttpRequestException, + * HttpMalformedHeaderException, HttpEncodingException. * * GET example: *