X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_methods.c;h=1365fcf4c6a15c7630908ecc1e6f91094e3cc6b1;hp=3701e1a953f94bdc08bc53ac0bf8e60ec98711db;hb=d226b8581f49234f6769a123173b268aa9b2bb60;hpb=e0dea94e283b3429780057c2f052b1a6b43515ef diff --git a/http_methods.c b/http_methods.c index 3701e1a..1365fcf 100644 --- a/http_methods.c +++ b/http_methods.c @@ -15,9 +15,6 @@ /* $Id$ */ -#define _WINSOCKAPI_ -#define ZEND_INCLUDE_FULL_WINDOWS_HEADERS - #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -36,6 +33,11 @@ /* {{{ proto void HTTPi_Response::__construct(bool cache, bool gzip) * + * Instantiates a new HTTPi_Response object, which can be used to send + * any data/resource/file to an HTTP client with caching and multiple + * ranges/resuming support. + * + * NOTE: GZIPping is not implemented yet. */ PHP_METHOD(HTTPi_Response, __construct) { @@ -54,6 +56,13 @@ PHP_METHOD(HTTPi_Response, __construct) /* {{{ proto bool HTTPi_Response::setCache(bool cache) * + * Whether it sould be attempted to cache the entitity. + * This will result in necessary caching headers and checks of clients + * "If-Modified-Since" and "If-None-Match" headers. If one of those headers + * matches a "304 Not Modified" status code will be issued. + * + * NOTE: If you're using sessions, be shure that you set session.cache_limiter + * to something more appropriate than "no-cache"! */ PHP_METHOD(HTTPi_Response, setCache) { @@ -71,6 +80,7 @@ PHP_METHOD(HTTPi_Response, setCache) /* {{{ proto bool HTTPi_Response::getCache() * + * Get current caching setting. */ PHP_METHOD(HTTPi_Response, getCache) { @@ -86,6 +96,7 @@ PHP_METHOD(HTTPi_Response, getCache) /* {{{ proto bool HTTPi_Response::setGzip(bool gzip) * + * Enable on-thy-fly gzipping of the sent entity. NOT IMPLEMENTED YET. */ PHP_METHOD(HTTPi_Response, setGzip) { @@ -103,6 +114,7 @@ PHP_METHOD(HTTPi_Response, setGzip) /* {{{ proto bool HTTPi_Response::getGzip() * + * Get current gzipping setting. */ PHP_METHOD(HTTPi_Response, getGzip) { @@ -118,6 +130,8 @@ PHP_METHOD(HTTPi_Response, getGzip) /* {{{ proto bool HTTPi_Response::setCacheControl(string control[, bool raw = false]) * + * Set a custom cache-control header, usually being "private" or "public"; if + * $raw is set to true the header will be sent as-is. */ PHP_METHOD(HTTPi_Response, setCacheControl) { @@ -143,6 +157,7 @@ PHP_METHOD(HTTPi_Response, setCacheControl) /* {{{ proto string HTTPi_Response::getCacheControl() * + * Get current Cache-Control header setting. */ PHP_METHOD(HTTPi_Response, getCacheControl) { @@ -156,8 +171,9 @@ PHP_METHOD(HTTPi_Response, getCacheControl) } /* }}} */ -/* {{{ proto bool HTTPi::setContentType(string content_type) +/* {{{ proto bool HTTPi_Response::setContentType(string content_type) * + * Set the content-type of the sent entity. */ PHP_METHOD(HTTPi_Response, setContentType) { @@ -183,6 +199,7 @@ PHP_METHOD(HTTPi_Response, setContentType) /* {{{ proto string HTTPi_Response::getContentType() * + * Get current Content-Type header setting. */ PHP_METHOD(HTTPi_Response, getContentType) { @@ -198,6 +215,9 @@ PHP_METHOD(HTTPi_Response, getContentType) /* {{{ proto bool HTTPi_Response::setContentDisposition(string filename[, bool inline = false]) * + * Set the Content-Disposition of the sent entity. This setting aims to suggest + * the receiveing user agent how to handle the sent entity; usually the client + * will show the user a "Save As..." popup. */ PHP_METHOD(HTTPi_Response, setContentDisposition) { @@ -218,6 +238,14 @@ PHP_METHOD(HTTPi_Response, setContentDisposition) /* {{{ proto array HTTPi_Response::getContentDisposition() * + * Get current Content-Disposition setting. + * Will return an associative array like: + *
+ * array(
+ *     'filename' => 'foo.bar',
+ *     'inline'   => false
+ * )
+ * 
*/ PHP_METHOD(HTTPi_Response, getContentDisposition) { @@ -240,6 +268,7 @@ PHP_METHOD(HTTPi_Response, getContentDisposition) /* {{{ proto bool HTTPi_Response::setETag(string etag) * + * Set a custom ETag. Use this only if you know what you're doing. */ PHP_METHOD(HTTPi_Response, setETag) { @@ -258,6 +287,7 @@ PHP_METHOD(HTTPi_Response, setETag) /* {{{ proto string HTTPi_Response::getETag() * + * Get the previously set custom ETag. */ PHP_METHOD(HTTPi_Response, getETag) { @@ -273,6 +303,7 @@ PHP_METHOD(HTTPi_Response, getETag) /* {{{ proto bool HTTPi_Response::setData(string data) * + * Set the data to be sent. */ PHP_METHOD(HTTPi_Response, setData) { @@ -293,6 +324,7 @@ PHP_METHOD(HTTPi_Response, setData) /* {{{ proto string HTTPi_Response::getData() * + * Get the previously set data to be sent. */ PHP_METHOD(HTTPi_Response, getData) { @@ -308,6 +340,7 @@ PHP_METHOD(HTTPi_Response, getData) /* {{{ proto bool HTTPi_Response::setStream(resource stream) * + * Set the resource to be sent. */ PHP_METHOD(HTTPi_Response, setStream) { @@ -330,6 +363,7 @@ PHP_METHOD(HTTPi_Response, setStream) /* {{{ proto resource HTTPi_Response::getStream() * + * Get the previously set resource to be sent. */ PHP_METHOD(HTTPi_Response, getStream) { @@ -345,6 +379,7 @@ PHP_METHOD(HTTPi_Response, getStream) /* {{{ proto bool HTTPi_Response::setFile(string file) * + * Set the file to be sent. */ PHP_METHOD(HTTPi_Response, setFile) { @@ -366,6 +401,7 @@ PHP_METHOD(HTTPi_Response, setFile) /* {{{ proto string HTTPi_Response::getFile() * + * Get the previously set file to be sent. */ PHP_METHOD(HTTPi_Response, getFile) { @@ -379,11 +415,28 @@ PHP_METHOD(HTTPi_Response, getFile) } /* }}} */ +/* {{{ proto bool HTTPi_Response::send() + * + * Finally send the entity. + * + * Example: + *
+ * setFile('../hidden/contract.pdf');
+ * $r->setContentType('application/pdf');
+ * $r->send();
+ * ?>
+ * 
+ * + */ PHP_METHOD(HTTPi_Response, send) { zval *do_cache, *do_gzip; getObject(httpi_response_object, obj); + NO_ARGS; + do_cache = GET_PROP(obj, cache); do_gzip = GET_PROP(obj, gzip); @@ -438,7 +491,8 @@ PHP_METHOD(HTTPi_Response, send) { case SEND_DATA: { - RETURN_SUCCESS(http_send_data(GET_PROP(obj, data))); + zval *zdata = GET_PROP(obj, data); + RETURN_SUCCESS(http_send_data(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata))); } case SEND_RSRC: @@ -451,7 +505,8 @@ PHP_METHOD(HTTPi_Response, send) default: { - RETURN_SUCCESS(http_send_file(GET_PROP(obj, file))); + zval *zfile = GET_PROP(obj, file); + RETURN_SUCCESS(http_send_file(Z_STRVAL_P(zfile))); } } } @@ -464,6 +519,8 @@ PHP_METHOD(HTTPi_Response, send) /* {{{ proto void HTTPi_Request::__construct([string url[, long request_method = HTTP_GET]]) * + * Instantiate a new HTTPi_Request object which can be used to issue HEAD, GET + * and POST (including posting files) HTTP requests. */ PHP_METHOD(HTTPi_Request, __construct) { @@ -493,6 +550,7 @@ PHP_METHOD(HTTPi_Request, __construct) /* {{{ proto void HTTPi_Request::__destruct() * + * Destroys the HTTPi_Request object. */ PHP_METHOD(HTTPi_Request, __destruct) { @@ -510,6 +568,7 @@ PHP_METHOD(HTTPi_Request, __destruct) /* {{{ proto bool HTTPi_Request::setOptions(array options) * + * Set the request options to use. See http_get() for a full list of available options. */ PHP_METHOD(HTTPi_Request, setOptions) { @@ -554,6 +613,7 @@ PHP_METHOD(HTTPi_Request, setOptions) /* {{{ proto array HTTPi_Request::getOptions() * + * Get current set options. */ PHP_METHOD(HTTPi_Request, getOptions) { @@ -570,6 +630,7 @@ PHP_METHOD(HTTPi_Request, getOptions) /* {{{ proto bool HTTPi_Request::setURL(string url) * + * Set the request URL. */ PHP_METHOD(HTTPi_Request, setURL) { @@ -588,6 +649,7 @@ PHP_METHOD(HTTPi_Request, setURL) /* {{{ proto string HTTPi_Request::getUrl() * + * Get the previously set request URL. */ PHP_METHOD(HTTPi_Request, getURL) { @@ -603,6 +665,8 @@ PHP_METHOD(HTTPi_Request, getURL) /* {{{ proto bool HTTPi_Request::setMethod(long request_method) * + * Set the request methods; one of the HTTP_HEAD, HTTP_GET or + * HTTP_POST constants. */ PHP_METHOD(HTTPi_Request, setMethod) { @@ -620,6 +684,7 @@ PHP_METHOD(HTTPi_Request, setMethod) /* {{{ proto long HTTPi_Request::getMethod() * + * Get the previously set request method. */ PHP_METHOD(HTTPi_Request, getMethod) { @@ -635,6 +700,8 @@ PHP_METHOD(HTTPi_Request, getMethod) /* {{{ proto bool HTTPi_Request::setContentType(string content_type) * + * Set the content type the post request should have. + * Use this only if you know what you're doing. */ PHP_METHOD(HTTPi_Request, setContentType) { @@ -660,6 +727,7 @@ PHP_METHOD(HTTPi_Request, setContentType) /* {{{ proto string HTTPi_Request::getContentType() * + * Get the previously content type. */ PHP_METHOD(HTTPi_Request, getContentType) { @@ -675,6 +743,9 @@ PHP_METHOD(HTTPi_Request, getContentType) /* {{{ proto bool HTTPi_Request::setQueryData(mixed query_data) * + * Set the URL query parameters to use. + * Overwrites previously set query parameters. + * Affects any request types. */ PHP_METHOD(HTTPi_Request, setQueryData) { @@ -703,6 +774,7 @@ PHP_METHOD(HTTPi_Request, setQueryData) /* {{{ proto string HTTPi_Request::getQueryData() * + * Get the current query data in form of an urlencoded query string. */ PHP_METHOD(HTTPi_Request, getQueryData) { @@ -718,6 +790,8 @@ PHP_METHOD(HTTPi_Request, getQueryData) /* {{{ proto bool HTTPi_Request::addQueryData(array query_params) * + * Add parameters to the query parameter list. + * Affects any request type. */ PHP_METHOD(HTTPi_Request, addQueryData) { @@ -744,6 +818,8 @@ PHP_METHOD(HTTPi_Request, addQueryData) /* {{{ proto void HTTPi_Request::unsetQueryData() * + * Clean the query parameters. + * Affects any request type. */ PHP_METHOD(HTTPi_Request, unsetQueryData) { @@ -757,6 +833,8 @@ PHP_METHOD(HTTPi_Request, unsetQueryData) /* {{{ proto bool HTTPi_Request::addPostData(array post_data) * + * Adds POST data entries. + * Affects only POST requests. */ PHP_METHOD(HTTPi_Request, addPostData) { @@ -776,6 +854,9 @@ PHP_METHOD(HTTPi_Request, addPostData) /* {{{ proto bool HTTPi_Request::setPostData(array post_data) * + * Set the POST data entries. + * Overwrites previously set POST data. + * Affects only POST requests. */ PHP_METHOD(HTTPi_Request, setPostData) { @@ -796,6 +877,7 @@ PHP_METHOD(HTTPi_Request, setPostData) /* {{{ proto array HTTPi_Request::getPostData() * + * Get previously set POST data. */ PHP_METHOD(HTTPi_Request, getPostData) { @@ -812,6 +894,8 @@ PHP_METHOD(HTTPi_Request, getPostData) /* {{{ proto void HTTPi_Request::unsetPostData() * + * Clean POST data entires. + * Affects only POST requests. */ PHP_METHOD(HTTPi_Request, unsetPostData) { @@ -827,6 +911,8 @@ PHP_METHOD(HTTPi_Request, unsetPostData) /* {{{ proto bool HTTPi_Request::addPostFile(string name, string file[, string content_type = "application/x-octetstream"]) * + * Add a file to the POST request. + * Affects only POST requests. */ PHP_METHOD(HTTPi_Request, addPostFile) { @@ -865,6 +951,7 @@ PHP_METHOD(HTTPi_Request, addPostFile) /* {{{ proto array HTTPi_Request::getPostFiles() * + * Get all previously added POST files. */ PHP_METHOD(HTTPi_Request, getPostFiles) { @@ -882,6 +969,8 @@ PHP_METHOD(HTTPi_Request, getPostFiles) /* {{{ proto void HTTPi_Request::unsetPostFiles() * + * Unset the POST files list. + * Affects only POST requests. */ PHP_METHOD(HTTPi_Request, unsetPostFiles) { @@ -897,6 +986,7 @@ PHP_METHOD(HTTPi_Request, unsetPostFiles) /* {{{ proto array HTTPi_Request::getResponseData() * + * Get all response data after the request has been sent. */ PHP_METHOD(HTTPi_Request, getResponseData) { @@ -911,26 +1001,39 @@ PHP_METHOD(HTTPi_Request, getResponseData) } /* }}} */ -/* {{{ proto array HTTPi_Request::getResponseHeaders() +/* {{{ proto string HTTPi_Request::getResponseHeader([string name]) * + * Get response header(s) after the request has been sent. */ -PHP_METHOD(HTTPi_Request, getResponseHeaders) +PHP_METHOD(HTTPi_Request, getResponseHeader) { - zval *data, **headers; - getObject(httpi_request_object, obj); + zval *data, **headers, **header; + char *header_name = NULL; + int header_len = 0; + getObject(httpi_response_object, obj); - NO_ARGS; + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &header_name, &header_len)) { + RETURN_FALSE; + } - array_init(return_value); data = GET_PROP(obj, responseData); - if (SUCCESS == zend_hash_find(Z_ARRVAL_P(data), "headers", sizeof("headers"), (void **) &headers)) { + if (SUCCESS != zend_hash_find(Z_ARRVAL_P(data), "headers", sizeof("headers"), (void **) &headers)) { + RETURN_FALSE; + } + + 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); + } else { + RETURN_FALSE; } } -/* }}} */ /* {{{ proto string HTTPi_Request::getResponseBody() * + * Get the response body after the request has been sent. */ PHP_METHOD(HTTPi_Request, getResponseBody) { @@ -943,29 +1046,93 @@ PHP_METHOD(HTTPi_Request, getResponseBody) 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); } else { - Z_TYPE_P(return_value) = IS_NULL; + RETURN_FALSE; } } /* }}} */ -/* {{{ proto array HTTPi_Request::getResponseInfo() +/* {{{ proto int HTTPi_Request::getResponseCode() * + * Get the response code after the request has been sent. */ -PHP_METHOD(HTTPi_Request, getResponseInfo) +PHP_METHOD(HTTPi_Request, getResponseCode) { - zval *info; + zval **code, **hdrs, *data; getObject(httpi_request_object, obj); NO_ARGS; + data = GET_PROP(obj, responseData); + if ( (SUCCESS == zend_hash_find(Z_ARRVAL_P(data), "headers", sizeof("headers"), (void **) &hdrs)) && + (SUCCESS == zend_hash_find(Z_ARRVAL_PP(hdrs), "Status", sizeof("Status"), (void **) &code))) { + RETVAL_STRINGL(Z_STRVAL_PP(code), Z_STRLEN_PP(code), 1); + convert_to_long(return_value); + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto array HTTPi_Request::getResponseInfo([string name]) + * + * Get response info after the request has been sent. + * See http_get() for a full list of returned info. + */ +PHP_METHOD(HTTPi_Request, getResponseInfo) +{ + zval *info, **infop; + char *info_name = NULL; + int info_len = 0; + getObject(httpi_request_object, obj); + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &info_name, &info_len)) { + RETURN_FALSE; + } + info = GET_PROP(obj, responseInfo); - array_init(return_value); - array_copy(info, return_value); + + 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)) { + RETURN_ZVAL(*infop, 1, ZVAL_PTR_DTOR); + } else { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not find response info named %s", info_name); + RETURN_FALSE; + } + } else { + array_init(return_value); + array_copy(info, return_value); + } } /* }}}*/ /* {{{ proto bool HTTPi_Request::send() * + * Send the HTTP request. + * + * GET example: + *
+ * setOptions(array('lastmodified' => filemtime('local.rss')));
+ * $r->addQueryData(array('category' => 3));
+ * if ($r->send() && $r->getResponseCode() == 200) {
+ *     file_put_contents('local.rss', $r->getResponseBody());
+ * }
+ * ?>
+ * 
+ * + * POST example: + *
+ * setOptions(array('cookies' => array('lang' => 'de')));
+ * $r->addPostData(array('user' => 'mike', 'pass' => 's3c|r3t'));
+ * $r->addPostFile('image', 'profile.jpg', 'image/jpeg');
+ * if ($r->send()) {
+ *     echo $r->getResponseBody();
+ * }
+ * ?>
+ * 
*/ PHP_METHOD(HTTPi_Request, send) { @@ -989,8 +1156,8 @@ PHP_METHOD(HTTPi_Request, send) info = GET_PROP(obj, responseInfo); resp = GET_PROP(obj, responseData); - // HTTP_URI_MAXLEN+1 big char * - request_uri = http_absolute_uri(Z_STRVAL_P(URL), NULL); + // HTTP_URI_MAXLEN+1 long char * + request_uri = http_absolute_uri_ex(Z_STRVAL_P(URL), Z_STRLEN_P(URL), NULL, 0, NULL, 0, 0); if (Z_STRLEN_P(qdata) && (strlen(request_uri) < HTTP_URI_MAXLEN)) { if (!strchr(request_uri, '?')) { @@ -1082,22 +1249,22 @@ PHP_METHOD(HTTPi_Request, send) if (status != SUCCESS) { RETURN_FALSE; } else { - zval *zheaders, *zbody; + char *body = NULL; + size_t body_len = 0; + zval *zheaders; - MAKE_STD_ZVAL(zbody); MAKE_STD_ZVAL(zheaders) array_init(zheaders); - if (SUCCESS != http_split_response_ex(response_data, response_len, zheaders, zbody)) { + if (SUCCESS != http_split_response_ex(response_data, response_len, Z_ARRVAL_P(zheaders), &body, &body_len)) { zval_dtor(zheaders); efree(zheaders), - efree(zbody); efree(response_data); RETURN_FALSE; } add_assoc_zval(resp, "headers", zheaders); - add_assoc_zval(resp, "body", zbody); + add_assoc_stringl(resp, "body", body, body_len, 0); efree(response_data); @@ -1118,4 +1285,5 @@ PHP_METHOD(HTTPi_Request, send) * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 - */ \ No newline at end of file + */ +