X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_functions.c;h=41afd28e3733664ab0d7ad22e3f47fd2420002a1;hp=ade26547982859fa4fa60acc2032edbdccca5fd6;hb=7b88d9022c90eb12e5fe195af8644935141c9d68;hpb=7fef44c902c86eebce30f36003a27905fbaeba65 diff --git a/http_functions.c b/http_functions.c index ade2654..41afd28 100644 --- a/http_functions.c +++ b/http_functions.c @@ -17,6 +17,7 @@ #endif #define HTTP_WANT_CURL +#define HTTP_WANT_ZLIB #include "php_http.h" #include "SAPI.h" @@ -40,8 +41,6 @@ #include "php_http_send_api.h" #include "php_http_url_api.h" -ZEND_EXTERN_MODULE_GLOBALS(http) - /* {{{ proto string http_date([int timestamp]) * * Compose a valid HTTP date regarding RFC 822/1123 @@ -67,41 +66,84 @@ PHP_FUNCTION(http_date) } /* }}} */ -/* {{{ proto string http_build_uri(string url[, string proto[, string host[, int port]]]) +/* {{{ proto string http_build_url(mixed url[, mixed parts[, array new_url]]) * - * Build a complete URI according to the supplied parameters. - * - * If the url is already abolute but a different proto was supplied, - * only the proto part of the URI will be updated. If url has no - * path specified, the path of the current REQUEST_URI will be taken. - * The host will be taken either from the Host HTTP header of the client - * the SERVER_NAME or just localhost if prior are not available. - * If a port is pecified in either the url or as sperate parameter, - * it will be added if it differs from te default port for HTTP(S). - * - * Returns the absolute URI as string on success or false on failure. - * - * Examples: - *
- * 
- * 
+ * Returns the new URL as string on success or FALSE on failure. */ -PHP_FUNCTION(http_build_uri) +PHP_FUNCTION(http_build_url) { - char *url = NULL, *proto = NULL, *host = NULL, *built = NULL; - int url_len = 0, proto_len = 0, host_len = 0; - long port = 0; + char *url_str = NULL; + size_t url_len = 0; + zval *z_old_url = NULL, *z_new_url = NULL, *z_composed_url = NULL; + php_url *old_url = NULL, *new_url = NULL, *composed_url = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ssl", &url, &url_len, &proto, &proto_len, &host, &host_len, &port) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/|z/z", &z_old_url, &z_new_url, &z_composed_url) != SUCCESS) { RETURN_FALSE; } - - if ((built = http_absolute_uri_ex(url, url_len, proto, proto_len, host, host_len, port))) { - RETURN_STRING(built, 0); + + if (z_new_url) { + if (Z_TYPE_P(z_new_url) == IS_ARRAY || Z_TYPE_P(z_new_url) == IS_OBJECT) { + new_url = array2url(HASH_OF(z_new_url)); + } else { + convert_to_string(z_new_url); + if (!(new_url = php_url_parse_ex(Z_STRVAL_P(z_new_url), Z_STRLEN_P(z_new_url)))) { + RETURN_FALSE; + } + } } - RETURN_FALSE; + + if (Z_TYPE_P(z_old_url) == IS_ARRAY || Z_TYPE_P(z_old_url) == IS_OBJECT) { + old_url = array2url(HASH_OF(z_old_url)); + } else { + convert_to_string(z_old_url); + if (!(old_url = php_url_parse_ex(Z_STRVAL_P(z_old_url), Z_STRLEN_P(z_old_url)))) { + if (new_url) { + php_url_free(new_url); + } + RETURN_FALSE; + } + } + + if (z_composed_url) { + http_build_url(old_url, new_url, &composed_url, &url_str, &url_len); + + zval_dtor(z_composed_url); + array_init(z_composed_url); + if (composed_url->scheme) { + add_assoc_string(z_composed_url, "scheme", composed_url->scheme, 1); + } + if (composed_url->user) { + add_assoc_string(z_composed_url, "user", composed_url->user, 1); + } + if (composed_url->pass) { + add_assoc_string(z_composed_url, "pass", composed_url->pass, 1); + } + if (composed_url->host) { + add_assoc_string(z_composed_url, "host", composed_url->host, 1); + } + if (composed_url->port) { + add_assoc_long(z_composed_url, "port", composed_url->port); + } + if (composed_url->path) { + add_assoc_string(z_composed_url, "path", composed_url->path, 1); + } + if (composed_url->query) { + add_assoc_string(z_composed_url, "query", composed_url->query, 1); + } + if (composed_url->fragment) { + add_assoc_string(z_composed_url, "fragment", composed_url->fragment, 1); + } + php_url_free(composed_url); + } else { + http_build_url(old_url, new_url, NULL, &url_str, &url_len); + } + + if (new_url) { + php_url_free(new_url); + } + php_url_free(old_url); + + RETURN_STRINGL(url_str, url_len, 0); } /* }}} */ @@ -685,7 +727,7 @@ PHP_FUNCTION(http_redirect) } } - URI = http_absolute_uri(url); + URI = http_absolute_url(url); if (query_len) { spprintf(&LOC, 0, "Location: %s?%s", URI, query); @@ -894,6 +936,7 @@ PHP_FUNCTION(http_parse_message) * ) * [Folded] => works * too + * ) * ?> * */ @@ -914,6 +957,44 @@ PHP_FUNCTION(http_parse_headers) } /* }}}*/ +/* {{{ proto object http_parse_cookie(string cookie) + * + * Parses HTTP cookies like sent in a response into a struct. + * + * Expects a string as parameter containing the value of a Set-Cookie response header. + * + * Returns an stdClass object with the cookie params as properties on success or FALSE on failure. + * + * Example: + *
+ *  foo
+ *     [value] => bar
+ *     [path] => /
+ * )
+ * ?>
+ * 
+ */ +PHP_FUNCTION(http_parse_cookie) +{ + char *cookie; + int cookie_len; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &cookie, &cookie_len)) { + RETURN_FALSE; + } + + object_init(return_value); + if (SUCCESS != http_parse_cookie(cookie, HASH_OF(return_value))) { + zval_dtor(return_value); + RETURN_FALSE; + } +} + /* {{{ proto array http_get_request_headers(void) * * Get a list of incoming HTTP headers. @@ -1161,14 +1242,9 @@ PHP_FUNCTION(http_post_data) RETVAL_FALSE; - body.type = HTTP_REQUEST_BODY_CSTRING; - body.data = postdata; - body.size = postdata_len; - http_request_init_ex(&request, NULL, HTTP_POST, URL); - request.body = &body; + request.body = http_request_body_init_ex(&body, HTTP_REQUEST_BODY_CSTRING, postdata, postdata_len, 0); if (SUCCESS == http_request_prepare(&request, options?Z_ARRVAL_P(options):NULL)) { - request.body = NULL; http_request_exec(&request); if (info) { http_request_info(&request, Z_ARRVAL_P(info)); @@ -1200,7 +1276,7 @@ PHP_FUNCTION(http_post_fields) RETURN_FALSE; } - if (SUCCESS != http_request_body_fill(&body, Z_ARRVAL_P(fields), files ? Z_ARRVAL_P(files) : NULL)) { + if (!http_request_body_fill(&body, Z_ARRVAL_P(fields), files ? Z_ARRVAL_P(files) : NULL)) { RETURN_FALSE; } @@ -1214,15 +1290,12 @@ PHP_FUNCTION(http_post_fields) http_request_init_ex(&request, NULL, HTTP_POST, URL); request.body = &body; if (SUCCESS == http_request_prepare(&request, options?Z_ARRVAL_P(options):NULL)) { - request.body = NULL; http_request_exec(&request); - http_request_body_dtor(&body); if (info) { http_request_info(&request, Z_ARRVAL_P(info)); } RETVAL_RESPONSE_OR_BODY(request); } - http_request_body_dtor(&body); http_request_dtor(&request); } /* }}} */ @@ -1272,15 +1345,14 @@ PHP_FUNCTION(http_put_file) http_request_init_ex(&request, NULL, HTTP_PUT, URL); request.body = &body; if (SUCCESS == http_request_prepare(&request, options?Z_ARRVAL_P(options):NULL)) { - request.body = NULL; http_request_exec(&request); - http_request_body_dtor(&body); if (info) { http_request_info(&request, Z_ARRVAL_P(info)); } RETVAL_RESPONSE_OR_BODY(request); } http_request_body_dtor(&body); + request.body = NULL; http_request_dtor(&request); } /* }}} */ @@ -1328,13 +1400,13 @@ PHP_FUNCTION(http_put_stream) http_request_init_ex(&request, NULL, HTTP_POST, URL); request.body = &body; if (SUCCESS == http_request_prepare(&request, options?Z_ARRVAL_P(options):NULL)) { - request.body = NULL; http_request_exec(&request); if (info) { http_request_info(&request, Z_ARRVAL_P(info)); } RETVAL_RESPONSE_OR_BODY(request); } + request.body = NULL; http_request_dtor(&request); } /* }}} */ @@ -1504,73 +1576,12 @@ PHP_FUNCTION(http_build_query) /* {{{ */ #ifdef HTTP_HAVE_ZLIB -/* {{{ proto string http_gzencode(string data[, int level = -1]) +/* {{{ proto string http_deflate(string data[, int flags = 0]) * - * Compress data with the HTTP compatible GZIP encoding. - * - * Expects the first parameter to be a string which contains the data that - * should be encoded. Additionally accepts an optional in paramter specifying - * the compression level, where -1 is default, 0 is no compression and 9 is - * best compression ratio. - * - * Returns the encoded string on success, or NULL on failure. - */ -PHP_FUNCTION(http_gzencode) -{ - char *data; - int data_len; - long level = -1; - - RETVAL_NULL(); - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &level)) { - HTTP_CHECK_GZIP_LEVEL(level, return); - { - char *encoded; - size_t encoded_len; - - if (SUCCESS == http_encoding_gzencode(level, data, data_len, &encoded, &encoded_len)) { - RETURN_STRINGL(encoded, (int) encoded_len, 0); - } - } - } -} -/* }}} */ - -/* {{{ proto string http_gzdecode(string data) - * - * Uncompress data compressed with the HTTP compatible GZIP encoding. - * - * Expects a string as parameter containing the compressed data. - * - * Returns the decoded string on success, or NULL on failure. - */ -PHP_FUNCTION(http_gzdecode) -{ - char *data; - int data_len; - - RETVAL_NULL(); - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len)) { - char *decoded; - size_t decoded_len; - - if (SUCCESS == http_encoding_gzdecode(data, data_len, &decoded, &decoded_len)) { - RETURN_STRINGL(decoded, (int) decoded_len, 0); - } - } -} -/* }}} */ - -/* {{{ proto string http_deflate(string data[, int level = -1]) - * - * Compress data with the HTTP compatible DEFLATE encoding. + * Compress data with gzip, zlib AKA deflate or raw deflate encoding. * * Expects the first parameter to be a string containing the data that should - * be encoded. Additionally accepts an optional int parameter specifying the - * compression level, where -1 is default, 0 is no compression and 9 is best - * compression ratio. + * be encoded. * * Returns the encoded string on success, or NULL on failure. */ @@ -1578,19 +1589,16 @@ PHP_FUNCTION(http_deflate) { char *data; int data_len; - long level = -1; + long flags = 0; RETVAL_NULL(); - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &level)) { - HTTP_CHECK_GZIP_LEVEL(level, return); - { - char *encoded; - size_t encoded_len; - - if (SUCCESS == http_encoding_deflate(level, data, data_len, &encoded, &encoded_len)) { - RETURN_STRINGL(encoded, (int) encoded_len, 0); - } + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &flags)) { + char *encoded; + size_t encoded_len; + + if (SUCCESS == http_encoding_deflate(flags, data, data_len, &encoded, &encoded_len)) { + RETURN_STRINGL(encoded, (int) encoded_len, 0); } } } @@ -1598,7 +1606,8 @@ PHP_FUNCTION(http_deflate) /* {{{ proto string http_inflate(string data) * - * Uncompress data compressed with the HTTP compatible DEFLATE encoding. + * Uncompress data compressed with either gzip, deflate AKA zlib or raw + * deflate encoding. * * Expects a string as parameter containing the compressed data. * @@ -1622,64 +1631,47 @@ PHP_FUNCTION(http_inflate) } /* }}} */ -/* {{{ proto string http_compress(string data[, int level = -1]) +/* {{{ proto string ob_deflatehandler(string data, int mode) * - * Compress data with the HTTP compatible COMPRESS encoding. - * - * Expects the first parameter to be a string containing the data which should - * be encoded. Additionally accepts an optional int parameter specifying the - * compression level, where -1 is default, 0 is no compression and 9 is best - * compression ratio. - * - * Returns the encoded string on success, or NULL on failure. + * For use with ob_start(). The deflate output buffer handler can only be used once. + * It conflicts with ob_gzhanlder and zlib.output_compression as well and should + * not be used after ext/mbstrings mb_output_handler and ext/sessions URL-Rewriter (AKA + * session.use_trans_sid). */ -PHP_FUNCTION(http_compress) +PHP_FUNCTION(ob_deflatehandler) { char *data; int data_len; - long level = -1; - - RETVAL_NULL(); - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &level)) { - HTTP_CHECK_GZIP_LEVEL(level, return); - { - char *encoded; - size_t encoded_len; - - if (SUCCESS == http_encoding_compress(level, data, data_len, &encoded, &encoded_len)) { - RETURN_STRINGL(encoded, (int) encoded_len, 0); - } - } + long mode; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &data, &data_len, &mode)) { + RETURN_FALSE; } + + http_ob_deflatehandler(data, data_len, &Z_STRVAL_P(return_value), (uint *) &Z_STRLEN_P(return_value), mode); + Z_TYPE_P(return_value) = Z_STRVAL_P(return_value) ? IS_STRING : IS_NULL; } /* }}} */ -/* {{{ proto string http_uncompress(string data) +/* {{{ proto string ob_inflatehandler(string data, int mode) * - * Uncompress data compressed with the HTTP compatible COMPRESS encoding. - * - * Expects a string as parameter containing the compressed data. - * - * Returns the decoded string on success, or NULL on failure. + * For use with ob_start(). Same restrictions as with ob_deflatehandler apply. */ -PHP_FUNCTION(http_uncompress) +PHP_FUNCTION(ob_inflatehandler) { char *data; int data_len; + long mode; - RETVAL_NULL(); - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len)) { - char *decoded; - size_t decoded_len; - - if (SUCCESS == http_encoding_uncompress(data, data_len, &decoded, &decoded_len)) { - RETURN_STRINGL(decoded, (int) decoded_len, 0); - } + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &data, &data_len, &mode)) { + RETURN_FALSE; } + + http_ob_inflatehandler(data, data_len, &Z_STRVAL_P(return_value), (uint *) &Z_STRLEN_P(return_value), mode); + Z_TYPE_P(return_value) = Z_STRVAL_P(return_value) ? IS_STRING : IS_NULL; } /* }}} */ + #endif /* HTTP_HAVE_ZLIB */ /* }}} */