From: Michael Wallner Date: Wed, 11 Jan 2006 16:35:22 +0000 (+0000) Subject: - fix http_get_request_body() X-Git-Tag: RELEASE_1_0_4~3 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=ab7ffb9d04418a394dec4604f88a3aa5d94b9a08;p=m6w6%2Fext-http - fix http_get_request_body() - add http_get_request_body_stream() # TODO: locate everything that accepts a stream context and fix it up --- diff --git a/http.c b/http.c index 05244d1..26ab4d3 100644 --- a/http.c +++ b/http.c @@ -92,6 +92,7 @@ zend_function_entry http_functions[] = { PHP_FE(http_parse_cookie, NULL) PHP_FE(http_get_request_headers, NULL) PHP_FE(http_get_request_body, NULL) + PHP_FE(http_get_request_body_stream, NULL) PHP_FE(http_match_request_header, NULL) #ifdef HTTP_HAVE_CURL PHP_FE(http_get, http_arg_pass_ref_3) diff --git a/http_api.c b/http_api.c index 7825ebd..3f4b7a6 100644 --- a/http_api.c +++ b/http_api.c @@ -312,18 +312,21 @@ PHP_HTTP_API STATUS _http_get_request_body_ex(char **body, size_t *length, zend_ { *length = 0; *body = NULL; - + if (SG(request_info).raw_post_data) { *length = SG(request_info).raw_post_data_length; - *body = (char *) (dup ? estrndup(SG(request_info).raw_post_data, *length) : SG(request_info).raw_post_data); + *body = SG(request_info).raw_post_data; + + if (dup) { + *body = estrndup(*body, *length); + } return SUCCESS; - } - - /* PHP only reads POST */ - if (sapi_module.read_post) { + } else if (sapi_module.read_post && !HTTP_G(read_post_data)) { char buf[4096]; int len; + HTTP_G(read_post_data) = 1; + while (0 < (len = sapi_module.read_post(buf, sizeof(buf) TSRMLS_CC))) { *body = erealloc(*body, *length + len + 1); memcpy(*body + *length, buf, len); @@ -332,23 +335,55 @@ PHP_HTTP_API STATUS _http_get_request_body_ex(char **body, size_t *length, zend_ } /* check for error */ - if (len >= 0) { - /* connect to sapi module so it'll be freed */ - if (!dup) { - SG(request_info).raw_post_data = *body; - SG(request_info).raw_post_data_length = *length; - } - return SUCCESS; - } else { + if (len < 0) { STR_FREE(*body); *length = 0; + return FAILURE; + } + + SG(request_info).raw_post_data = *body; + SG(request_info).raw_post_data_length = *length; + + if (dup) { + *body = estrndup(*body, *length); } + return SUCCESS; } return FAILURE; } /* }}} */ +/* {{{ php_stream *_http_get_request_body_stream(void) */ +PHP_HTTP_API php_stream *_http_get_request_body_stream(TSRMLS_D) +{ + php_stream *s = NULL; + + if (SG(request_info).raw_post_data) { + s = php_stream_open_wrapper("php://input", "rb", 0, NULL); + } else if (sapi_module.read_post && !HTTP_G(read_post_data)) { + HTTP_G(read_post_data) = 1; + + if ((s = php_stream_temp_new())) { + char buf[4096]; + int len; + + while (0 < (len = sapi_module.read_post(buf, sizeof(buf) TSRMLS_CC))) { + php_stream_write(s, buf, len); + } + + if (len < 0) { + php_stream_close(s); + s = NULL; + } else { + php_stream_rewind(s); + } + } + } + + return s; +} +/* }}} */ /* * Local variables: diff --git a/http_functions.c b/http_functions.c index 69f03e1..4ece696 100644 --- a/http_functions.c +++ b/http_functions.c @@ -1020,7 +1020,10 @@ PHP_FUNCTION(http_get_request_headers) * * Get the raw request body (e.g. POST or PUT data). * - * Returns NULL when using the CLI SAPI. + * This function can not be used after http_get_request_body_stream() + * if the request method was another than POST. + * + * Returns the raw request body as string on success or NULL on failure. */ PHP_FUNCTION(http_get_request_body) { @@ -1037,6 +1040,29 @@ PHP_FUNCTION(http_get_request_body) } /* }}} */ +/* {{{ proto resource http_get_request_body_stream(void) + * + * Create a stream to read the raw request body (e.g. POST or PUT data). + * + * This function can only be used once if the request method was another than POST. + * + * Returns the raw request body as stream on success or NULL on failure. + */ +PHP_FUNCTION(http_get_request_body_stream) +{ + php_stream *s; + + NO_ARGS; + + if ((s = http_get_request_body_stream())) { + php_stream_to_zval(s, return_value); + } else { + http_error(HE_WARNING, HTTP_E_RUNTIME, "Failed to create request body stream"); + RETURN_NULL(); + } +} +/* }}} */ + /* {{{ proto bool http_match_request_header(string header, string value[, bool match_case = false]) * * Match an incoming HTTP header. diff --git a/php_http.h b/php_http.h index a3cb94f..0fbbb55 100644 --- a/php_http.h +++ b/php_http.h @@ -107,6 +107,7 @@ ZEND_BEGIN_MODULE_GLOBALS(http) #endif zend_bool force_exit; + zend_bool read_post_data; ZEND_END_MODULE_GLOBALS(http) @@ -147,6 +148,7 @@ PHP_FUNCTION(http_parse_headers); PHP_FUNCTION(http_parse_cookie); PHP_FUNCTION(http_get_request_headers); PHP_FUNCTION(http_get_request_body); +PHP_FUNCTION(http_get_request_body_stream); PHP_FUNCTION(http_match_request_header); #ifdef HTTP_HAVE_CURL PHP_FUNCTION(http_get); diff --git a/php_http_api.h b/php_http_api.h index 3d708d7..2c54e2b 100644 --- a/php_http_api.h +++ b/php_http_api.h @@ -124,6 +124,8 @@ PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_size, zen #define http_get_request_body_ex(b, l, d) _http_get_request_body_ex((b), (l), (d) TSRMLS_CC) PHP_HTTP_API STATUS _http_get_request_body_ex(char **body, size_t *length, zend_bool dup TSRMLS_DC); +#define http_get_request_body_stream() _http_get_request_body_stream(TSRMLS_C) +PHP_HTTP_API php_stream *_http_get_request_body_stream(TSRMLS_D); #define http_locate_body _http_locate_body static inline const char *_http_locate_body(const char *message) diff --git a/tests/get_request_data_001.phpt b/tests/get_request_data_001.phpt index 4d15265..3dabaa1 100644 --- a/tests/get_request_data_001.phpt +++ b/tests/get_request_data_001.phpt @@ -4,25 +4,26 @@ get request data ---ENV-- -HTTP_ACCEPT_CHARSET=iso-8859-1, * -HTTP_ACCEPT_ENCODING=none -HTTP_USER_AGENT=Mozilla/5.0 -HTTP_HOST=localhost --POST-- a=b&c=d --FILE-- -===DONE=== --EXPECTF-- %sTEST Array @@ -32,5 +33,8 @@ Array [Host] => localhost [User-Agent] => Mozilla/5.0 ) -OK -===DONE=== +string(7) "a=b&c=d" +string(7) "a=b&c=d" +string(7) "a=b&c=d" +string(7) "a=b&c=d" +Done