X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_functions.c;h=f42fccba9b28c02eadb76488aed0f8607194ab7e;hp=8b79f42497beffd47140e6b272bbb9fb291c0169;hb=7038c951485d1b2afa79c9a84b8dcdcb57c9bc54;hpb=a19a05825d04d634834f7898ec1a5247fdd6095c diff --git a/http_functions.c b/http_functions.c index 8b79f42..f42fccb 100644 --- a/http_functions.c +++ b/http_functions.c @@ -32,6 +32,7 @@ #include "php_http.h" #include "php_http_api.h" #include "php_http_curl_api.h" +#include "php_http_std_defs.h" ZEND_DECLARE_MODULE_GLOBALS(http) @@ -57,7 +58,7 @@ PHP_FUNCTION(http_date) } /* }}} */ -/* {{{ proto string http_absolute_uri(string url[, string proto]) +/* {{{ proto string http_absolute_uri(string url[, string proto[, string host[, int port]]]) * * This function returns an absolute URI constructed from url. * If the url is already abolute but a different proto was supplied, @@ -76,14 +77,15 @@ PHP_FUNCTION(http_date) */ PHP_FUNCTION(http_absolute_uri) { - char *url = NULL, *proto = NULL; - int url_len = 0, proto_len = 0; + char *url = NULL, *proto = NULL, *host = NULL; + int url_len = 0, proto_len = 0, host_len = 0; + long port = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &url, &url_len, &proto, &proto_len) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ssl", &url, &url_len, &proto, &proto_len, &host, &host_len, &port) != SUCCESS) { RETURN_FALSE; } - RETURN_STRING(http_absolute_uri(url, proto), 0); + RETURN_STRING(http_absolute_uri_ex(url, url_len, proto, proto_len, host, host_len, port), 0); } /* }}} */ @@ -265,7 +267,7 @@ PHP_FUNCTION(http_send_content_disposition) } /* }}} */ -/* {{{ proto bool http_match_modified([int timestamp]) +/* {{{ proto bool http_match_modified([int timestamp[, for_range = false]]) * * Matches the given timestamp against the clients "If-Modified-Since" resp. * "If-Unmodified-Since" HTTP headers. @@ -274,8 +276,9 @@ PHP_FUNCTION(http_send_content_disposition) PHP_FUNCTION(http_match_modified) { long t = -1; + zend_bool for_range = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &t) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &t, &for_range) != SUCCESS) { RETURN_FALSE; } @@ -284,11 +287,14 @@ PHP_FUNCTION(http_match_modified) t = (long) time(NULL); } - RETURN_BOOL(http_modified_match("HTTP_IF_MODIFIED_SINCE", t) || http_modified_match("HTTP_IF_UNMODIFIED_SINCE", t)); + if (for_range) { + RETURN_BOOL(http_modified_match("HTTP_IF_UNMODIFIED_SINCE", t)); + } + RETURN_BOOL(http_modified_match("HTTP_IF_MODIFIED_SINCE", t)); } /* }}} */ -/* {{{ proto bool http_match_etag(string etag) +/* {{{ proto bool http_match_etag(string etag[, for_range = false]) * * This matches the given ETag against the clients * "If-Match" resp. "If-None-Match" HTTP headers. @@ -298,12 +304,16 @@ PHP_FUNCTION(http_match_etag) { int etag_len; char *etag; + zend_bool for_range = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &etag, &etag_len) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &etag, &etag_len, &for_range) != SUCCESS) { RETURN_FALSE; } - RETURN_BOOL(http_etag_match("HTTP_IF_NONE_MATCH", etag) || http_etag_match("HTTP_IF_MATCH", etag)); + if (for_range) { + RETURN_BOOL(http_etag_match("HTTP_IF_MATCH", etag)); + } + RETURN_BOOL(http_etag_match("HTTP_IF_NONE_MATCH", etag)); } /* }}} */ @@ -363,7 +373,7 @@ PHP_FUNCTION(http_cache_last_modified) */ PHP_FUNCTION(http_cache_etag) { - char *etag; + char *etag = NULL; int etag_len = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &etag, &etag_len) != SUCCESS) { @@ -426,10 +436,12 @@ PHP_FUNCTION(ob_httpetaghandler) PHP_FUNCTION(http_redirect) { int url_len; + size_t query_len = 0; zend_bool session = 0, permanent = 0; zval *params = NULL; - smart_str qstr = {0}; - char *url, *URI, LOC[HTTP_URI_MAXLEN + 9], RED[HTTP_URI_MAXLEN * 2 + 34]; + char *query, *url, *URI, + LOC[HTTP_URI_MAXLEN + sizeof("Location: ")], + RED[HTTP_URI_MAXLEN * 2 + sizeof("Redirecting to %s?%s.\n")]; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sa!/bb", &url, &url_len, ¶ms, &session, &permanent) != SUCCESS) { RETURN_FALSE; @@ -448,23 +460,19 @@ PHP_FUNCTION(http_redirect) /* treat params array with http_build_query() */ if (params) { - if (php_url_encode_hash_ex(Z_ARRVAL_P(params), &qstr, NULL,0,NULL,0,NULL,0,NULL TSRMLS_CC) != SUCCESS) { - if (qstr.c) { - efree(qstr.c); - } - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not encode query parameters"); + if (SUCCESS != http_urlencode_hash_ex(Z_ARRVAL_P(params), 0, NULL, 0, &query, &query_len)) { RETURN_FALSE; } - smart_str_0(&qstr); } - URI = http_absolute_uri(url, NULL); - if (qstr.c) { - snprintf(LOC, HTTP_URI_MAXLEN + strlen("Location: "), "Location: %s?%s", URI, qstr.c); - sprintf(RED, "Redirecting to %s?%s.\n", URI, qstr.c, URI, qstr.c); - efree(qstr.c); + URI = http_absolute_uri(url); + + if (query_len) { + snprintf(LOC, HTTP_URI_MAXLEN + sizeof("Location: "), "Location: %s?%s", URI, query); + sprintf(RED, "Redirecting to %s?%s.\n", URI, query, URI, query); + efree(query); } else { - snprintf(LOC, HTTP_URI_MAXLEN + strlen("Location: "), "Location: %s", URI); + snprintf(LOC, HTTP_URI_MAXLEN + sizeof("Location: "), "Location: %s", URI); sprintf(RED, "Redirecting to %s.\n", URI, URI); } efree(URI); @@ -492,7 +500,7 @@ PHP_FUNCTION(http_send_data) convert_to_string_ex(&zdata); http_send_header("Accept-Ranges: bytes"); - RETURN_SUCCESS(http_send_data(zdata)); + RETURN_SUCCESS(http_send_data(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata))); } /* }}} */ @@ -503,15 +511,18 @@ PHP_FUNCTION(http_send_data) */ PHP_FUNCTION(http_send_file) { - zval *zfile; + char *file; + int flen = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zfile) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &flen) != SUCCESS) { + RETURN_FALSE; + } + if (!flen) { RETURN_FALSE; } - convert_to_string_ex(&zfile); http_send_header("Accept-Ranges: bytes"); - RETURN_SUCCESS(http_send_file(zfile)); + RETURN_SUCCESS(http_send_file(file)); } /* }}} */ @@ -568,6 +579,7 @@ PHP_FUNCTION(http_chunked_decode) * 0 => array( * 'Status' => '200 Ok', * 'Content-Type' => 'text/plain', + * 'Content-Language' => 'en-US' * ), * 1 => "Hello World!" @@ -583,7 +595,7 @@ PHP_FUNCTION(http_split_response) RETURN_FALSE; } - convert_to_string_ex(&zresponse); + convert_to_string(zresponse); MAKE_STD_ZVAL(zbody); MAKE_STD_ZVAL(zheaders); @@ -618,7 +630,7 @@ PHP_FUNCTION(http_parse_headers) header_len = rnrn - header + 2; } if (SUCCESS != http_parse_headers(header, header_len, return_value)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP header"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP headers"); zval_dtor(return_value); RETURN_FALSE; } @@ -630,9 +642,7 @@ PHP_FUNCTION(http_parse_headers) */ PHP_FUNCTION(http_get_request_headers) { - if (ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; - } + NO_ARGS; array_init(return_value); http_get_request_headers(return_value); @@ -669,6 +679,13 @@ PHP_FUNCTION(http_get_request_headers) * - cookies: array, list of cookies as associative array * like array("cookie" => "value") * - cookiestore: string, path to a file where cookies are/will be stored + * - resume: int, byte offset to start the download from; + * if the server supports ranges + * - maxfilesize: int, maximum file size that should be downloaded; + * has no effect, if the size of the requested entity is not known + * - lastmodified: int, timestamp for If-(Un)Modified-Since header + * - timeout: int, seconds the request may take + * - connecttimeout: int, seconds the connect may take * * * The optional third parameter will be filled with some additional information @@ -879,7 +896,6 @@ PHP_FUNCTION(http_auth_basic) * } * return false; * } - * * if (!http_auth_basic_cb('auth_cb')) { * die('

Authorization failed

'); * } @@ -932,6 +948,45 @@ PHP_FUNCTION(http_auth_basic_cb) } /* }}}*/ +/* {{{ Sara Golemons http_build_query() */ +#ifndef ZEND_ENGINE_2 + +/* {{{ proto string http_build_query(mixed formdata [, string prefix]) + Generates a form-encoded query string from an associative array or object. */ +PHP_FUNCTION(http_build_query) +{ + zval *formdata; + char *prefix = NULL; + int prefix_len = 0; + smart_str formstr = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|s", &formdata, &prefix, &prefix_len) != SUCCESS) { + RETURN_FALSE; + } + + if (Z_TYPE_P(formdata) != IS_ARRAY && Z_TYPE_P(formdata) != IS_OBJECT) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter 1 expected to be Array or Object. Incorrect value given."); + RETURN_FALSE; + } + + if (php_url_encode_hash_ex(HASH_OF(formdata), &formstr, prefix, prefix_len, NULL, 0, NULL, 0, (Z_TYPE_P(formdata) == IS_OBJECT ? formdata : NULL) TSRMLS_CC) == FAILURE) { + if (formstr.c) { + efree(formstr.c); + } + RETURN_FALSE; + } + + if (!formstr.c) { + RETURN_NULL(); + } + + smart_str_0(&formstr); + + RETURN_STRINGL(formstr.c, formstr.len, 0); +} +/* }}} */ +#endif /* !ZEND_ENGINE_2 */ +/* }}} */ /* * Local variables: @@ -941,3 +996,4 @@ PHP_FUNCTION(http_auth_basic_cb) * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ +