mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Add http_(get|clear)_last_reponse_headers() functions (#12500)
This is to provide an alternative to the $http_response_header magic variable RFC: https://wiki.php.net/rfc/http-last-response-headers
This commit is contained in:
committed by
GitHub
parent
99e7cf074b
commit
47a199c8b4
3
NEWS
3
NEWS
@@ -198,6 +198,9 @@ PHP NEWS
|
||||
. Changed return type of long2ip to string from string|false. (Jorg Sowa)
|
||||
. Fix GH-12143 (Extend the maximum precision round can handle by one digit).
|
||||
(SakiTakamachi)
|
||||
. Added the http_get_last_response_headers() and
|
||||
http_clear_last_response_headers() that allows retrieving the same content
|
||||
as the magic $http_response_header variable.
|
||||
|
||||
- XML:
|
||||
. Added XML_OPTION_PARSE_HUGE parser option. (nielsdos)
|
||||
|
||||
@@ -428,6 +428,11 @@ PHP 8.4 UPGRADE NOTES
|
||||
. sodium_crypto_aead_aes256gcm_*() functions are now enabled on aarch64 CPUs
|
||||
with the ARM cryptographic extensions.
|
||||
|
||||
- Standard:
|
||||
. Added the http_get_last_response_headers() and
|
||||
http_clear_last_response_headers() that allows retrieving the same content
|
||||
as the magic $http_response_header variable.
|
||||
|
||||
- XSL:
|
||||
. Added XSLTProcessor::registerPhpFunctionNS().
|
||||
RFC: https://wiki.php.net/rfc/improve_callbacks_dom_and_xsl
|
||||
|
||||
@@ -418,6 +418,9 @@ PHP_RINIT_FUNCTION(basic) /* {{{ */
|
||||
BASIC_RINIT_SUBMODULE(dir)
|
||||
BASIC_RINIT_SUBMODULE(url_scanner_ex)
|
||||
|
||||
/* Initialize memory for last http headers */
|
||||
ZVAL_UNDEF(&BG(last_http_headers));
|
||||
|
||||
/* Setup default context */
|
||||
FG(default_context) = NULL;
|
||||
|
||||
@@ -482,6 +485,9 @@ PHP_RSHUTDOWN_FUNCTION(basic) /* {{{ */
|
||||
BASIC_RSHUTDOWN_SUBMODULE(user_filters)
|
||||
BASIC_RSHUTDOWN_SUBMODULE(browscap)
|
||||
|
||||
/* Free last http headers */
|
||||
zval_ptr_dtor(&BG(last_http_headers));
|
||||
|
||||
BG(page_uid) = -1;
|
||||
BG(page_gid) = -1;
|
||||
return SUCCESS;
|
||||
|
||||
@@ -70,6 +70,9 @@ typedef struct _php_basic_globals {
|
||||
|
||||
zval active_ini_file_section;
|
||||
|
||||
/* http_fopen_wrapper.c */
|
||||
zval last_http_headers;
|
||||
|
||||
/* pageinfo.c */
|
||||
zend_long page_uid;
|
||||
zend_long page_gid;
|
||||
|
||||
@@ -3025,6 +3025,10 @@ function pfsockopen(string $hostname, int $port = -1, &$error_code = null, &$err
|
||||
/** @refcount 1 */
|
||||
function http_build_query(array|object $data, string $numeric_prefix = "", ?string $arg_separator = null, int $encoding_type = PHP_QUERY_RFC1738): string {}
|
||||
|
||||
function http_get_last_response_headers(): ?array {}
|
||||
|
||||
function http_clear_last_response_headers(): void {}
|
||||
|
||||
/**
|
||||
* @param array|null $options
|
||||
* @return array<int, array>
|
||||
|
||||
10
ext/standard/basic_functions_arginfo.h
generated
10
ext/standard/basic_functions_arginfo.h
generated
@@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: b8ea4527467c70a6f665129cd5d5f34ea2386a70 */
|
||||
* Stub hash: 2094d8e51f7bfd0fd7b61060786a1e8ae182b0d3 */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0)
|
||||
@@ -1502,6 +1502,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_http_build_query, 0, 1, IS_STRIN
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding_type, IS_LONG, 0, "PHP_QUERY_RFC1738")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_http_get_last_response_headers arginfo_error_get_last
|
||||
|
||||
#define arginfo_http_clear_last_response_headers arginfo_flush
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_request_parse_body, 0, 0, IS_ARRAY, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
@@ -2713,6 +2717,8 @@ ZEND_FUNCTION(vfprintf);
|
||||
ZEND_FUNCTION(fsockopen);
|
||||
ZEND_FUNCTION(pfsockopen);
|
||||
ZEND_FUNCTION(http_build_query);
|
||||
ZEND_FUNCTION(http_get_last_response_headers);
|
||||
ZEND_FUNCTION(http_clear_last_response_headers);
|
||||
ZEND_FUNCTION(request_parse_body);
|
||||
ZEND_FUNCTION(image_type_to_mime_type);
|
||||
ZEND_FUNCTION(image_type_to_extension);
|
||||
@@ -3350,6 +3356,8 @@ static const zend_function_entry ext_functions[] = {
|
||||
ZEND_FE(fsockopen, arginfo_fsockopen)
|
||||
ZEND_FE(pfsockopen, arginfo_pfsockopen)
|
||||
ZEND_FE(http_build_query, arginfo_http_build_query)
|
||||
ZEND_FE(http_get_last_response_headers, arginfo_http_get_last_response_headers)
|
||||
ZEND_FE(http_clear_last_response_headers, arginfo_http_clear_last_response_headers)
|
||||
ZEND_FE(request_parse_body, arginfo_request_parse_body)
|
||||
ZEND_RAW_FENTRY("image_type_to_mime_type", zif_image_type_to_mime_type, arginfo_image_type_to_mime_type, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL)
|
||||
ZEND_RAW_FENTRY("image_type_to_extension", zif_image_type_to_extension, arginfo_image_type_to_extension, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "SAPI.h"
|
||||
#include "zend_exceptions.h"
|
||||
#include "ext/spl/spl_exceptions.h"
|
||||
#include "basic_functions.h"
|
||||
|
||||
static void php_url_encode_scalar(zval *scalar, smart_str *form_str,
|
||||
int encoding_type, zend_ulong index_int,
|
||||
@@ -360,3 +361,26 @@ exit:
|
||||
SG(request_parse_body_context).throw_exceptions = false;
|
||||
memset(&SG(request_parse_body_context).options_cache, 0, sizeof(SG(request_parse_body_context).options_cache));
|
||||
}
|
||||
|
||||
PHP_FUNCTION(http_get_last_response_headers)
|
||||
{
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (!Z_ISUNDEF(BG(last_http_headers))) {
|
||||
RETURN_COPY(&BG(last_http_headers));
|
||||
} else {
|
||||
RETURN_NULL();
|
||||
}
|
||||
}
|
||||
|
||||
PHP_FUNCTION(http_clear_last_response_headers)
|
||||
{
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&BG(last_http_headers));
|
||||
ZVAL_UNDEF(&BG(last_http_headers));
|
||||
}
|
||||
|
||||
@@ -982,13 +982,19 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, const char *pa
|
||||
{
|
||||
php_stream *stream;
|
||||
zval headers;
|
||||
|
||||
ZVAL_UNDEF(&headers);
|
||||
|
||||
zval_ptr_dtor(&BG(last_http_headers));
|
||||
ZVAL_UNDEF(&BG(last_http_headers));
|
||||
|
||||
stream = php_stream_url_wrap_http_ex(
|
||||
wrapper, path, mode, options, opened_path, context,
|
||||
PHP_URL_REDIRECT_MAX, HTTP_WRAPPER_HEADER_INIT, &headers STREAMS_CC);
|
||||
|
||||
if (!Z_ISUNDEF(headers)) {
|
||||
ZVAL_COPY(&BG(last_http_headers), &headers);
|
||||
|
||||
if (FAILURE == zend_set_local_var_str(
|
||||
"http_response_header", sizeof("http_response_header")-1, &headers, 0)) {
|
||||
zval_ptr_dtor(&headers);
|
||||
|
||||
@@ -14,13 +14,17 @@ $responses = array(
|
||||
|
||||
['pid' => $pid, 'uri' => $uri] = http_server($responses, $output);
|
||||
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
var_dump(file_get_contents($uri));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
NULL
|
||||
string(0) ""
|
||||
array(2) {
|
||||
[0]=>
|
||||
@@ -28,3 +32,9 @@ array(2) {
|
||||
[1]=>
|
||||
string(14) "Content-Length"
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(15) "HTTP/1.0 200 Ok"
|
||||
[1]=>
|
||||
string(14) "Content-Length"
|
||||
}
|
||||
|
||||
@@ -23,14 +23,26 @@ $options = [
|
||||
|
||||
$ctx = stream_context_create($options);
|
||||
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
$fd = fopen($uri, 'rb', false, $ctx);
|
||||
fclose($fd);
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
NULL
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(32) "HTTP/1.1 101 Switching Protocols"
|
||||
[1]=>
|
||||
string(15) "Header1: Value1"
|
||||
[2]=>
|
||||
string(15) "Header2: Value2"
|
||||
}
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(32) "HTTP/1.1 101 Switching Protocols"
|
||||
|
||||
@@ -16,8 +16,14 @@ $responses = array(
|
||||
['pid' => $pid, 'uri' => $uri] = http_server($responses, $output);
|
||||
|
||||
for ($i = 0; $i < count($responses); ++$i) {
|
||||
echo 'http_get_last_response_headers() before stream layer call:', PHP_EOL;
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
$f = @fopen($uri, "r");
|
||||
echo '$http_response_header', PHP_EOL;
|
||||
var_dump($http_response_header);
|
||||
echo 'http_get_last_response_headers() after stream layer call:', PHP_EOL;
|
||||
var_dump(http_get_last_response_headers());
|
||||
fclose($f);
|
||||
}
|
||||
|
||||
@@ -25,12 +31,37 @@ http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
http_get_last_response_headers() before stream layer call:
|
||||
NULL
|
||||
$http_response_header
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(126) "HTTP/1.1 200 Some very long reason-phrase to test that this is properly handled by our code without adding a new header like "
|
||||
[1]=>
|
||||
string(12) "Good: Header"
|
||||
}
|
||||
http_get_last_response_headers() after stream layer call:
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(126) "HTTP/1.1 200 Some very long reason-phrase to test that this is properly handled by our code without adding a new header like "
|
||||
[1]=>
|
||||
string(12) "Good: Header"
|
||||
}
|
||||
http_get_last_response_headers() before stream layer call:
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(126) "HTTP/1.1 200 Some very long reason-phrase to test that this is properly handled by our code without adding a new header like "
|
||||
[1]=>
|
||||
string(12) "Good: Header"
|
||||
}
|
||||
$http_response_header
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(13) "HTTP/1.1 200 "
|
||||
[1]=>
|
||||
string(12) "Good: Header"
|
||||
}
|
||||
http_get_last_response_headers() after stream layer call:
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(13) "HTTP/1.1 200 "
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
--TEST--
|
||||
Verify that http_clear_last_response_headers() clears the headers.
|
||||
--SKIPIF--
|
||||
<?php require 'server.inc'; http_server_skipif(); ?>
|
||||
--INI--
|
||||
allow_url_fopen=1
|
||||
--FILE--
|
||||
<?php
|
||||
require 'server.inc';
|
||||
|
||||
$responses = array(
|
||||
"data://text/plain,HTTP/1.0 200 Ok\r\nSome: Header\r\nSome: Header\r\n\r\nBody",
|
||||
);
|
||||
|
||||
['pid' => $pid, 'uri' => $uri] = http_server($responses, $output);
|
||||
|
||||
$f = file_get_contents($uri);
|
||||
var_dump($f);
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
// Clear headers
|
||||
http_clear_last_response_headers();
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(4) "Body"
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(15) "HTTP/1.0 200 Ok"
|
||||
[1]=>
|
||||
string(12) "Some: Header"
|
||||
[2]=>
|
||||
string(12) "Some: Header"
|
||||
}
|
||||
NULL
|
||||
@@ -14,14 +14,18 @@ $responses = array(
|
||||
|
||||
['pid' => $pid, 'uri' => $uri] = http_server($responses, $output);
|
||||
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
$f = file_get_contents($uri);
|
||||
var_dump($f);
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
NULL
|
||||
string(4) "Body"
|
||||
array(3) {
|
||||
[0]=>
|
||||
@@ -31,3 +35,11 @@ array(3) {
|
||||
[2]=>
|
||||
string(12) "Some: Header"
|
||||
}
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(15) "HTTP/1.0 200 Ok"
|
||||
[1]=>
|
||||
string(12) "Some: Header"
|
||||
[2]=>
|
||||
string(12) "Some: Header"
|
||||
}
|
||||
|
||||
@@ -16,14 +16,18 @@ $responses = array(
|
||||
|
||||
['pid' => $pid, 'uri' => $uri] = http_server($responses, $output);
|
||||
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
$f = file_get_contents($uri);
|
||||
var_dump($f);
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
NULL
|
||||
string(4) "Body"
|
||||
array(5) {
|
||||
[0]=>
|
||||
@@ -37,3 +41,15 @@ array(5) {
|
||||
[4]=>
|
||||
string(12) "Some: Header"
|
||||
}
|
||||
array(5) {
|
||||
[0]=>
|
||||
string(18) "HTTP/1.0 302 Found"
|
||||
[1]=>
|
||||
string(12) "Some: Header"
|
||||
[2]=>
|
||||
string(20) "Location: /try-again"
|
||||
[3]=>
|
||||
string(15) "HTTP/1.0 200 Ok"
|
||||
[4]=>
|
||||
string(12) "Some: Header"
|
||||
}
|
||||
|
||||
@@ -16,14 +16,19 @@ $responses = array(
|
||||
|
||||
['pid' => $pid, 'uri' => $uri] = http_server($responses, $output);
|
||||
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
$f = file_get_contents($uri);
|
||||
var_dump($f);
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
NULL
|
||||
|
||||
Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found%a
|
||||
bool(false)
|
||||
array(5) {
|
||||
@@ -38,3 +43,15 @@ array(5) {
|
||||
[4]=>
|
||||
string(12) "Some: Header"
|
||||
}
|
||||
array(5) {
|
||||
[0]=>
|
||||
string(18) "HTTP/1.0 302 Found"
|
||||
[1]=>
|
||||
string(12) "Some: Header"
|
||||
[2]=>
|
||||
string(20) "Location: /try-again"
|
||||
[3]=>
|
||||
string(22) "HTTP/1.0 404 Not Found"
|
||||
[4]=>
|
||||
string(12) "Some: Header"
|
||||
}
|
||||
|
||||
@@ -14,14 +14,18 @@ $responses = array(
|
||||
|
||||
['pid' => $pid, 'uri' => $uri] = http_server($responses, $output);
|
||||
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
$f = file_get_contents($uri);
|
||||
var_dump($f);
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
NULL
|
||||
string(4) "Body"
|
||||
array(2) {
|
||||
[0]=>
|
||||
@@ -29,3 +33,9 @@ array(2) {
|
||||
[1]=>
|
||||
string(14) "Some: Header"
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(15) "HTTP/1.0 200 Ok"
|
||||
[1]=>
|
||||
string(14) "Some: Header"
|
||||
}
|
||||
|
||||
@@ -14,14 +14,18 @@ $responses = array(
|
||||
|
||||
['pid' => $pid, 'uri' => $uri] = http_server($responses, $output);
|
||||
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
$f = file_get_contents($uri);
|
||||
var_dump($f);
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
NULL
|
||||
string(4) "Body"
|
||||
array(2) {
|
||||
[0]=>
|
||||
@@ -29,3 +33,9 @@ array(2) {
|
||||
[1]=>
|
||||
string(0) ""
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(15) "HTTP/1.0 200 Ok"
|
||||
[1]=>
|
||||
string(0) ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user