diff --git a/main/SAPI.c b/main/SAPI.c index 9781f18c12420..70ea601b1cec8 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -469,7 +469,12 @@ SAPI_API void sapi_activate(void) if (PG(enable_post_data_reading) && SG(request_info).content_type && SG(request_info).request_method - && !strcmp(SG(request_info).request_method, "POST")) { + && + (!strcmp(SG(request_info).request_method, "POST") || + !strcmp(SG(request_info).request_method, "PUT") || + !strcmp(SG(request_info).request_method, "PATCH") || + !strcmp(SG(request_info).request_method, "DELETE")) + ) { /* HTTP POST may contain form data to be processed into variables * depending on given content type */ sapi_read_post_data(); diff --git a/main/php_content_types.c b/main/php_content_types.c index 51b18c424d38a..662c2383596cb 100644 --- a/main/php_content_types.c +++ b/main/php_content_types.c @@ -37,7 +37,13 @@ static sapi_post_entry php_post_entries[] = { */ SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader) { - if (!strcmp(SG(request_info).request_method, "POST")) { + if ( + !strcmp(SG(request_info).request_method, "POST") || + !strcmp(SG(request_info).request_method, "PUT") || + !strcmp(SG(request_info).request_method, "PATCH") || + !strcmp(SG(request_info).request_method, "DELETE") + ) { + if (NULL == SG(request_info).post_entry) { /* no post handler registered, so we just swallow the data */ sapi_read_standard_form_data(); diff --git a/main/php_variables.c b/main/php_variables.c index 73274d7695015..3dae16bf2d87c 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -690,7 +690,11 @@ static zend_bool php_auto_globals_create_post(zend_string *name) (strchr(PG(variables_order),'P') || strchr(PG(variables_order),'p')) && !SG(headers_sent) && SG(request_info).request_method && - !strcasecmp(SG(request_info).request_method, "POST")) { + (!strcasecmp(SG(request_info).request_method, "POST") || + !strcasecmp(SG(request_info).request_method, "PUT") || + !strcasecmp(SG(request_info).request_method, "PATCH") || + !strcasecmp(SG(request_info).request_method, "DELETE")) + ) { sapi_module.treat_data(PARSE_POST, NULL, NULL); } else { zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_POST]); diff --git a/run-tests.php b/run-tests.php index 25123c319f06e..82f04e9129ec7 100755 --- a/run-tests.php +++ b/run-tests.php @@ -1296,7 +1296,7 @@ function run_test($php, $file, $env) unset($section_text['FILEEOF']); } - foreach (array( 'FILE', 'EXPECT', 'EXPECTF', 'EXPECTREGEX' ) as $prefix) { + foreach (array( 'FILE', 'EXPECT', 'EXPECTF', 'EXPECTREGEX' ) as $prefix) { $key = $prefix . '_EXTERNAL'; if (@count($section_text[$key]) == 1) { @@ -1340,8 +1340,8 @@ function run_test($php, $file, $env) $tested = trim($section_text['TEST']); - /* For GET/POST/PUT tests, check if cgi sapi is available and if it is, use it. */ - if (!empty($section_text['GET']) || !empty($section_text['POST']) || !empty($section_text['GZIP_POST']) || !empty($section_text['DEFLATE_POST']) || !empty($section_text['POST_RAW']) || !empty($section_text['PUT']) || !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) { + /* For GET/POST/PUT/PATCH/DELETE tests, check if cgi sapi is available and if it is, use it. */ + if (!empty($section_text['GET']) || !empty($section_text['POST']) || !empty($section_text['GZIP_POST']) || !empty($section_text['DEFLATE_POST']) || !empty($section_text['POST_RAW']) || !empty($section_text['PUT']) || !empty($section_text['PATCH']) || !empty($section_text['DELETE']) || !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) { if (isset($php_cgi)) { $old_php = $php; $php = $php_cgi . ' -C '; @@ -1594,9 +1594,9 @@ function run_test($php, $file, $env) } } } - + if (!extension_loaded("zlib") - && ( array_key_exists("GZIP_POST", $section_text) + && ( array_key_exists("GZIP_POST", $section_text) || array_key_exists("DEFLATE_POST", $section_text)) ) { $message = "ext/zlib required"; @@ -1770,6 +1770,10 @@ function run_test($php, $file, $env) $request .= $line; } + if (empty($env['CONTENT_TYPE'])) { + $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; + } + $env['CONTENT_LENGTH'] = strlen($request); $env['REQUEST_METHOD'] = 'PUT'; @@ -1781,6 +1785,82 @@ function run_test($php, $file, $env) save_text($tmp_post, $request); $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\""; + } elseif (array_key_exists('PATCH', $section_text) && !empty($section_text['PATCH'])) { + + $post = trim($section_text['PATCH']); + $raw_lines = explode("\n", $post); + + $request = ''; + $started = false; + + foreach ($raw_lines as $line) { + + if (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) { + $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1])); + continue; + } + + if ($started) { + $request .= "\n"; + } + + $started = true; + $request .= $line; + } + + if (empty($env['CONTENT_TYPE'])) { + $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; + } + + $env['CONTENT_LENGTH'] = strlen($request); + $env['REQUEST_METHOD'] = 'PATCH'; + + if (empty($request)) { + junit_mark_test_as('BORK', $shortname, $tested, null, 'empty $request'); + return 'BORKED'; + } + + save_text($tmp_post, $request); + $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\""; + + } elseif (array_key_exists('DELETE', $section_text) && !empty($section_text['DELETE'])) { + + $post = trim($section_text['DELETE']); + $raw_lines = explode("\n", $post); + + $request = ''; + $started = false; + + foreach ($raw_lines as $line) { + + if (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) { + $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1])); + continue; + } + + if ($started) { + $request .= "\n"; + } + + $started = true; + $request .= $line; + } + + if (empty($env['CONTENT_TYPE'])) { + $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; + } + + $env['CONTENT_LENGTH'] = strlen($request); + $env['REQUEST_METHOD'] = 'DELETE'; + + if (empty($request)) { + junit_mark_test_as('BORK', $shortname, $tested, null, 'empty $request'); + return 'BORKED'; + } + + save_text($tmp_post, $request); + $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\""; + } else if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) { $post = trim($section_text['POST']); @@ -2185,7 +2265,7 @@ function run_test($php, $file, $env) if (isset($old_php)) { $php = $old_php; } - + $diff = empty($diff) ? '' : preg_replace('/\e/', '', $diff); junit_mark_test_as($restype, str_replace($cwd . '/', '', $tested_file), $tested, null, $info, $diff); diff --git a/tests/basic/033.phpt b/tests/basic/033.phpt new file mode 100644 index 0000000000000..c15154148614e --- /dev/null +++ b/tests/basic/033.phpt @@ -0,0 +1,9 @@ +--TEST-- +Simple PUT Method test +--PUT-- +a=Hello+World +--FILE-- + +--EXPECT-- +Hello World \ No newline at end of file diff --git a/tests/basic/034.phpt b/tests/basic/034.phpt new file mode 100644 index 0000000000000..f105342116fd6 --- /dev/null +++ b/tests/basic/034.phpt @@ -0,0 +1,9 @@ +--TEST-- +Simple PATCH Method test +--PATCH-- +a=Hello+World +--FILE-- + +--EXPECT-- +Hello World \ No newline at end of file diff --git a/tests/basic/035.phpt b/tests/basic/035.phpt new file mode 100644 index 0000000000000..81553d0b9485c --- /dev/null +++ b/tests/basic/035.phpt @@ -0,0 +1,9 @@ +--TEST-- +Simple DELETE Method test +--DELETE-- +a=Hello+World +--FILE-- + +--EXPECT-- +Hello World \ No newline at end of file