X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_functions.c;h=4e67be7aee3fac005c0e2f083d096c94e0986b60;hp=9bf3399d72570ba6b6eb3a4abf1caf0eeb0ff9fd;hb=e47ee304be6758fbbfd238476f8a6bda9090fe12;hpb=c2b4f0332ead5425b183d2487ab5f25663f1009f diff --git a/http_functions.c b/http_functions.c index 9bf3399..4e67be7 100644 --- a/http_functions.c +++ b/http_functions.c @@ -33,9 +33,9 @@ #include "php_http_std_defs.h" #include "php_http_api.h" #include "php_http_auth_api.h" -#include "php_http_curl_api.h" +#include "php_http_request_api.h" #include "php_http_cache_api.h" -#include "php_http_curl_api.h" +#include "php_http_request_api.h" #include "php_http_date_api.h" #include "php_http_headers_api.h" #include "php_http_message_api.h" @@ -411,6 +411,35 @@ PHP_FUNCTION(ob_etaghandler) } /* }}} */ +/* {{{ proto void http_throttle(double sec[, long bytes = 2097152]) + * + * Use with http_send() API. + * + * Example: + *
+ * 
+ * 
+ */ +PHP_FUNCTION(http_throttle) +{ + long chunk_size; + double interval; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dl", &interval, &chunk_size)) { + return; + } + + HTTP_G(send).throttle_delay = interval; + HTTP_G(send).buffer_size = chunk_size; +} +/* }}} */ + /* {{{ proto void http_redirect([string url[, array params[, bool session,[ bool permanent]]]]) * * Redirect to a given url. @@ -431,7 +460,7 @@ PHP_FUNCTION(http_redirect) size_t query_len = 0; zend_bool session = 0, permanent = 0; zval *params = NULL; - char *query, *url, *URI, + char *query = NULL, *url = NULL, *URI, LOC[HTTP_URI_MAXLEN + sizeof("Location: ")], RED[HTTP_URI_MAXLEN * 2 + sizeof("Redirecting to %s?%s.\n")]; @@ -577,26 +606,26 @@ PHP_FUNCTION(http_chunked_decode) */ PHP_FUNCTION(http_split_response) { - zval *zresponse, *zbody, *zheaders; + char *response, *body; + int response_len; + size_t body_len; + zval *zheaders; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zresponse) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &response, &response_len) != SUCCESS) { RETURN_FALSE; } - convert_to_string(zresponse); - - MAKE_STD_ZVAL(zbody); MAKE_STD_ZVAL(zheaders); array_init(zheaders); - if (SUCCESS != http_split_response(zresponse, zheaders, zbody)) { + if (SUCCESS != http_split_response(response, response_len, Z_ARRVAL_P(zheaders), &body, &body_len)) { http_error(E_WARNING, HTTP_E_PARSE, "Could not parse HTTP response"); RETURN_FALSE; } array_init(return_value); add_index_zval(return_value, 0, zheaders); - add_index_zval(return_value, 1, zbody); + add_index_stringl(return_value, 1, body, body_len, 0); } /* }}} */ @@ -623,6 +652,7 @@ PHP_FUNCTION(http_parse_headers) /* {{{ proto array http_get_request_headers(void) * + * Get a list of incoming HTTP headers. */ PHP_FUNCTION(http_get_request_headers) { @@ -633,6 +663,43 @@ PHP_FUNCTION(http_get_request_headers) } /* }}} */ +/* {{{ proto string http_get_request_body(void) + * + * Get the raw request body (e.g. POST or PUT data). + */ +PHP_FUNCTION(http_get_request_body) +{ + char *body; + size_t length; + + NO_ARGS; + + if (SUCCESS == http_get_request_body(&body, &length)) { + RETURN_STRING(body, (int) length, 0); + } else { + RETURN_NULL(); + } +} +/* }}} */ + +/* {{{ proto bool http_match_request_header(string header, string value[, bool match_case = false]) + * + * Match an incoming HTTP header. + */ +PHP_FUNCTION(http_match_request_header) +{ + char *header, *value; + int header_len, value_len; + zend_bool match_case = 0, result = 0; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &header, &header_len, &value, &value_len, &match_case)) { + RETURN_FALSE; + } + + RETURN_BOOL(http_match_request_header_ex(header, value, match_case)); +} +/* }}} */ + /* {{{ HAVE_CURL */ #ifdef HTTP_HAVE_CURL @@ -670,6 +737,8 @@ PHP_FUNCTION(http_get_request_headers) * - lastmodified: int, timestamp for If-(Un)Modified-Since header * - timeout: int, seconds the request may take * - connecttimeout: int, seconds the connect may take + * - onprogress: mixed, progress callback + * - ondebug: mixed, debug callback * * * The optional third parameter will be filled with some additional information @@ -773,6 +842,7 @@ PHP_FUNCTION(http_post_data) char *URL, *postdata; int postdata_len, URL_len; phpstr response; + http_request_body body; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a/!z", &URL, &URL_len, &postdata, &postdata_len, &options, &info) != SUCCESS) { RETURN_FALSE; @@ -783,29 +853,125 @@ PHP_FUNCTION(http_post_data) array_init(info); } + body.type = HTTP_REQUEST_BODY_CSTRING; + body.data = postdata; + body.size = postdata_len; + phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); - if (SUCCESS == http_post_data(URL, postdata, (size_t) postdata_len, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { - RETURN_PHPSTR_VAL(response); + if (SUCCESS == http_post(URL, &body, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { + RETVAL_PHPSTR_VAL(response); } else { - RETURN_FALSE; + RETVAL_FALSE; } } /* }}} */ -/* {{{ proto string http_post_array(string url, array data[, array options[, array &info]]) +/* {{{ proto string http_post_fields(string url, array data[, array files[, array options[, array &info]]]) * * Performs an HTTP POST request, posting www-form-urlencoded array data. * Returns the HTTP response as string. * See http_get() for a full list of available options. */ -PHP_FUNCTION(http_post_array) +PHP_FUNCTION(http_post_fields) +{ + zval *options = NULL, *info = NULL, *fields, *files = NULL; + char *URL; + int URL_len; + phpstr response; + http_request_body body; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|aa/!z", &URL, &URL_len, &fields, &files, &options, &info) != SUCCESS) { + RETURN_FALSE; + } + + if (SUCCESS != http_request_body_fill(&body, Z_ARRVAL_P(fields), files ? Z_ARRVAL_P(files) : NULL)) { + RETURN_FALSE; + } + + if (info) { + zval_dtor(info); + array_init(info); + } + + phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); + if (SUCCESS == http_post(URL, &body, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { + RETVAL_PHPSTR_VAL(response); + } else { + RETVAL_FALSE; + } + http_request_body_dtor(&body); +} +/* }}} */ + +/* {{{ proto string http_put_file(string url, string file[, array options[, array &info]]) + * + * Performs an HTTP PUT request, uploading file. + * Returns the HTTP response as string. + * See http_get() for a full list of available options. + */ +PHP_FUNCTION(http_put_file) +{ + char *URL, *file; + int URL_len, f_len; + zval *options = NULL, *info = NULL; + phpstr response; + php_stream *stream; + php_stream_statbuf ssb; + http_request_body body; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a/!z", &URL, &URL_len, &file, &f_len, &options, &info)) { + RETURN_FALSE; + } + + if (!(stream = php_stream_open_wrapper(file, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL))) { + RETURN_FALSE; + } + if (php_stream_stat(stream, &ssb)) { + php_stream_close(stream); + RETURN_FALSE; + } + + if (info) { + zval_dtor(info); + array_init(info); + } + + body.type = HTTP_REQUEST_BODY_UPLOADFILE; + body.data = stream; + body.size = ssb.sb.st_size; + + phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); + if (SUCCESS == http_put(URL, &body, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { + RETVAL_PHPSTR_VAL(response); + } else { + RETVAL_FALSE; + } + http_request_body_dtor(&body); +} +/* }}} */ + +/* {{{ proto string http_put_stream(string url, resource stream[, array options[, array &info]]) + * + * Performs an HTTP PUT request, uploading stream. + * Returns the HTTP response as string. + * See http_get() for a full list of available options. + */ +PHP_FUNCTION(http_put_stream) { - zval *options = NULL, *info = NULL, *postdata; + zval *resource, *options = NULL, *info = NULL; char *URL; int URL_len; phpstr response; + php_stream *stream; + php_stream_statbuf ssb; + http_request_body body; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|a/!z", &URL, &URL_len, &postdata, &options, &info) != SUCCESS) { + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sr|a/!z", &URL, &URL_len, &resource, &options, &info)) { + RETURN_FALSE; + } + + php_stream_from_zval(stream, &resource); + if (php_stream_stat(stream, &ssb)) { RETURN_FALSE; } @@ -814,15 +980,125 @@ PHP_FUNCTION(http_post_array) array_init(info); } + body.type = HTTP_REQUEST_BODY_UPLOADFILE; + body.data = stream; + body.size = ssb.sb.st_size; + phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); - if (SUCCESS == http_post_array(URL, Z_ARRVAL_P(postdata), options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { + if (SUCCESS == http_put(URL, &body, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { RETURN_PHPSTR_VAL(response); } else { + RETURN_NULL(); + } +} +/* }}} */ + +/* {{{ proto long http_request_method_register(string method) + * + * Register a custom request method. + */ +PHP_FUNCTION(http_request_method_register) +{ + char *method; + int *method_len; + unsigned long existing; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &method, &method_len)) { RETURN_FALSE; } + if (existing = http_request_method_exists(1, 0, method)) { + RETURN_LONG((long) existing); + } + + RETVAL_LONG((long) http_request_method_register(method)); } /* }}} */ +/* {{{ proto bool http_request_method_unregister(mixed method) + * + * Unregister a previously registered custom request method. + */ +PHP_FUNCTION(http_request_method_unregister) +{ + zval *method; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &method)) { + RETURN_FALSE; + } + + switch (Z_TYPE_P(method)) + { + case IS_OBJECT: + convert_to_string(method); + case IS_STRING: +#include "zend_operators.h" + if (is_numeric_string(Z_STRVAL_P(method), Z_STRLEN_P(method), NULL, NULL, 1)) { + convert_to_long(method); + } else { + unsigned long mn; + if (!(mn = http_request_method_exists(1, 0, Z_STRVAL_P(method)))) { + RETURN_FALSE; + } + zval_dtor(method); + ZVAL_LONG(method, (long)mn); + } + case IS_LONG: + RETURN_SUCCESS(http_request_method_unregister(Z_LVAL_P(method))); + default: + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto long http_request_method_exists(mixed method) + * + * Check if a request method is registered (or available by default). + */ +PHP_FUNCTION(http_request_method_exists) +{ + IF_RETVAL_USED { + zval *method; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &method)) { + RETURN_FALSE; + } + + switch (Z_TYPE_P(method)) + { + case IS_OBJECT: + convert_to_string(method); + case IS_STRING: + if (is_numeric_string(Z_STRVAL_P(method), Z_STRLEN_P(method), NULL, NULL, 1)) { + convert_to_long(method); + } else { + RETURN_LONG((long) http_request_method_exists(1, 0, Z_STRVAL_P(method))); + } + case IS_LONG: + RETURN_LONG((long) http_request_method_exists(0, Z_LVAL_P(method), NULL)); + default: + RETURN_FALSE; + } + } +} +/* }}} */ + +/* {{{ proto string http_request_method_name(long method) + * + * Get the literal string representation of a standard or registered request method. + */ +PHP_FUNCTION(http_request_method_name) +{ + IF_RETVAL_USED { + long method; + + if ((SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &method)) || (method < 0)) { + RETURN_FALSE; + } + + RETURN_STRING(estrdup(http_request_method_name((unsigned long) method)), 0); + } +} +/* }}} */ #endif /* }}} HAVE_CURL */ @@ -851,18 +1127,18 @@ PHP_FUNCTION(http_auth_basic) realm = "Restricted"; } - if (SUCCESS != http_auth_credentials(&suser, &spass)) { - http_auth_header("Basic", realm); + if (SUCCESS != http_auth_basic_credentials(&suser, &spass)) { + http_auth_basic_header(realm); RETURN_FALSE; } if (strcasecmp(suser, user)) { - http_auth_header("Basic", realm); + http_auth_basic_header(realm); RETURN_FALSE; } if (strcmp(spass, pass)) { - http_auth_header("Basic", realm); + http_auth_basic_header(realm); RETURN_FALSE; } @@ -904,8 +1180,8 @@ PHP_FUNCTION(http_auth_basic_cb) realm = "Restricted"; } - if (SUCCESS != http_auth_credentials(&user, &pass)) { - http_auth_header("Basic", realm); + if (SUCCESS != http_auth_basic_credentials(&user, &pass)) { + http_auth_basic_header(realm); RETURN_FALSE; } { @@ -928,7 +1204,7 @@ PHP_FUNCTION(http_auth_basic_cb) efree(zparams[1]); if (!result) { - http_auth_header("Basic", realm); + http_auth_basic_header(realm); } RETURN_BOOL(result); @@ -991,4 +1267,3 @@ PHP_FUNCTION(http_test) * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ -