2e5010
Adapted for 7.2.7 from 7.3 by remi
2e5010
2e5010
2e5010
From 0ea4013f101d64fbeb9221260b36e98f10ed1ddd Mon Sep 17 00:00:00 2001
2e5010
From: Remi Collet <remi@remirepo.net>
2e5010
Date: Wed, 4 Jul 2018 08:48:38 +0200
2e5010
Subject: [PATCH] Fixed bug #62596 add getallheaders (apache_request_headers)
2e5010
 missing function in FPM add sapi_add_request_header in public API (was
2e5010
 add_request_header) fix arginfo for fastcgi_finish_request fucntion
2e5010
2e5010
---
2e5010
 main/SAPI.c                       | 50 +++++++++++++++++++++++++++++
2e5010
 main/SAPI.h                       |  1 +
2e5010
 sapi/cgi/cgi_main.c               | 51 +----------------------------
2e5010
 sapi/fpm/fpm/fpm_main.c           | 25 ++++++++++++++-
2e5010
 sapi/fpm/tests/getallheaders.phpt | 67 +++++++++++++++++++++++++++++++++++++++
2e5010
 5 files changed, 143 insertions(+), 51 deletions(-)
2e5010
 create mode 100644 sapi/fpm/tests/getallheaders.phpt
2e5010
2e5010
diff --git a/main/SAPI.c b/main/SAPI.c
2e5010
index b6c3329..7e0c7c8 100644
2e5010
--- a/main/SAPI.c
2e5010
+++ b/main/SAPI.c
2e5010
@@ -1104,6 +1104,56 @@ SAPI_API void sapi_terminate_process(void) {
2e5010
 	}
2e5010
 }
2e5010
 
2e5010
+SAPI_API void sapi_add_request_header(char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg) /* {{{ */
2e5010
+{
2e5010
+	zval *return_value = (zval*)arg;
2e5010
+	char *str = NULL;
2e5010
+
2e5010
+	ALLOCA_FLAG(use_heap)
2e5010
+
2e5010
+	if (var_len > 5 &&
2e5010
+	    var[0] == 'H' &&
2e5010
+	    var[1] == 'T' &&
2e5010
+	    var[2] == 'T' &&
2e5010
+	    var[3] == 'P' &&
2e5010
+	    var[4] == '_') {
2e5010
+
2e5010
+		char *p;
2e5010
+
2e5010
+		var_len -= 5;
2e5010
+		p = var + 5;
2e5010
+		var = str = do_alloca(var_len + 1, use_heap);
2e5010
+		*str++ = *p++;
2e5010
+		while (*p) {
2e5010
+			if (*p == '_') {
2e5010
+				*str++ = '-';
2e5010
+				p++;
2e5010
+				if (*p) {
2e5010
+					*str++ = *p++;
2e5010
+				}
2e5010
+			} else if (*p >= 'A' && *p <= 'Z') {
2e5010
+				*str++ = (*p++ - 'A' + 'a');
2e5010
+			} else {
2e5010
+				*str++ = *p++;
2e5010
+			}
2e5010
+		}
2e5010
+		*str = 0;
2e5010
+	} else if (var_len == sizeof("CONTENT_TYPE")-1 &&
2e5010
+	           memcmp(var, "CONTENT_TYPE", sizeof("CONTENT_TYPE")-1) == 0) {
2e5010
+		var = "Content-Type";
2e5010
+	} else if (var_len == sizeof("CONTENT_LENGTH")-1 &&
2e5010
+	           memcmp(var, "CONTENT_LENGTH", sizeof("CONTENT_LENGTH")-1) == 0) {
2e5010
+		var = "Content-Length";
2e5010
+	} else {
2e5010
+		return;
2e5010
+	}
2e5010
+	add_assoc_stringl_ex(return_value, var, var_len, val, val_len);
2e5010
+	if (str) {
2e5010
+		free_alloca(var, use_heap);
2e5010
+	}
2e5010
+}
2e5010
+/* }}} */
2e5010
+
2e5010
 /*
2e5010
  * Local variables:
2e5010
  * tab-width: 4
2e5010
diff --git a/main/SAPI.h b/main/SAPI.h
2e5010
index f829fd7..4b8e223 100644
2e5010
--- a/main/SAPI.h
2e5010
+++ b/main/SAPI.h
2e5010
@@ -151,6 +151,7 @@ SAPI_API void sapi_shutdown(void);
2e5010
 SAPI_API void sapi_activate(void);
2e5010
 SAPI_API void sapi_deactivate(void);
2e5010
 SAPI_API void sapi_initialize_empty_request(void);
2e5010
+SAPI_API void sapi_add_request_header(char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg);
2e5010
 END_EXTERN_C()
2e5010
 
2e5010
 /*
2e5010
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
2e5010
index 2e9cefe..350846d 100644
2e5010
--- a/sapi/cgi/cgi_main.c
2e5010
+++ b/sapi/cgi/cgi_main.c
2e5010
@@ -1591,54 +1591,6 @@ PHP_FUNCTION(apache_child_terminate) /*
2e5010
 }
2e5010
 /* }}} */
2e5010
 
2e5010
-static void add_request_header(char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg) /* {{{ */
2e5010
-{
2e5010
-	zval *return_value = (zval*)arg;
2e5010
-	char *str = NULL;
2e5010
-	char *p;
2e5010
-	ALLOCA_FLAG(use_heap)
2e5010
-
2e5010
-	if (var_len > 5 &&
2e5010
-	    var[0] == 'H' &&
2e5010
-	    var[1] == 'T' &&
2e5010
-	    var[2] == 'T' &&
2e5010
-	    var[3] == 'P' &&
2e5010
-	    var[4] == '_') {
2e5010
-
2e5010
-		var_len -= 5;
2e5010
-		p = var + 5;
2e5010
-		var = str = do_alloca(var_len + 1, use_heap);
2e5010
-		*str++ = *p++;
2e5010
-		while (*p) {
2e5010
-			if (*p == '_') {
2e5010
-				*str++ = '-';
2e5010
-				p++;
2e5010
-				if (*p) {
2e5010
-					*str++ = *p++;
2e5010
-				}
2e5010
-			} else if (*p >= 'A' && *p <= 'Z') {
2e5010
-				*str++ = (*p++ - 'A' + 'a');
2e5010
-			} else {
2e5010
-				*str++ = *p++;
2e5010
-			}
2e5010
-		}
2e5010
-		*str = 0;
2e5010
-	} else if (var_len == sizeof("CONTENT_TYPE")-1 &&
2e5010
-	           memcmp(var, "CONTENT_TYPE", sizeof("CONTENT_TYPE")-1) == 0) {
2e5010
-		var = "Content-Type";
2e5010
-	} else if (var_len == sizeof("CONTENT_LENGTH")-1 &&
2e5010
-	           memcmp(var, "CONTENT_LENGTH", sizeof("CONTENT_LENGTH")-1) == 0) {
2e5010
-		var = "Content-Length";
2e5010
-	} else {
2e5010
-		return;
2e5010
-	}
2e5010
-	add_assoc_stringl_ex(return_value, var, var_len, val, val_len);
2e5010
-	if (str) {
2e5010
-		free_alloca(var, use_heap);
2e5010
-	}
2e5010
-}
2e5010
-/* }}} */
2e5010
-
2e5010
 PHP_FUNCTION(apache_request_headers) /* {{{ */
2e5010
 {
2e5010
 	if (zend_parse_parameters_none()) {
2e5010
@@ -1648,7 +1600,7 @@ PHP_FUNCTION(apache_request_headers) /*
2e5010
 	if (fcgi_is_fastcgi()) {
2e5010
 		fcgi_request *request = (fcgi_request*) SG(server_context);
2e5010
 
2e5010
-		fcgi_loadenv(request, add_request_header, return_value);
2e5010
+		fcgi_loadenv(request, sapi_add_request_header, return_value);
2e5010
 	} else {
2e5010
 		char buf[128];
2e5010
 		char **env, *p, *q, *var, *val, *t = buf;
2e5010
diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c
2e5010
index 3256660..e815be4 100644
2e5010
--- a/sapi/fpm/fpm/fpm_main.c
2e5010
+++ b/sapi/fpm/fpm/fpm_main.c
2e5010
@@ -1533,6 +1533,10 @@ PHP_FUNCTION(fastcgi_finish_request) /* {{{ */
2e5010
 {
2e5010
 	fcgi_request *request = (fcgi_request*) SG(server_context);
2e5010
 
2e5010
+	if (zend_parse_parameters_none() == FAILURE) {
2e5010
+		return;
2e5010
+	}
2e5010
+
2e5010
 	if (!fcgi_is_closed(request)) {
2e5010
 		php_output_end_all();
2e5010
 		php_header();
2e5010
@@ -1547,8 +1551,27 @@ PHP_FUNCTION(fastcgi_finish_request) /* {{{ */
2e5010
 }
2e5010
 /* }}} */
2e5010
 
2e5010
+ZEND_BEGIN_ARG_INFO(cgi_fcgi_sapi_no_arginfo, 0)
2e5010
+ZEND_END_ARG_INFO()
2e5010
+
2e5010
+PHP_FUNCTION(apache_request_headers) /* {{{ */
2e5010
+{
2e5010
+	fcgi_request *request;
2e5010
+
2e5010
+	if (zend_parse_parameters_none() == FAILURE) {
2e5010
+		return;
2e5010
+	}
2e5010
+
2e5010
+	array_init(return_value);
2e5010
+	if ((request = (fcgi_request*) SG(server_context))) {
2e5010
+		fcgi_loadenv(request, sapi_add_request_header, return_value);
2e5010
+	}
2e5010
+} /* }}} */
2e5010
+
2e5010
 static const zend_function_entry cgi_fcgi_sapi_functions[] = {
2e5010
-	PHP_FE(fastcgi_finish_request,              NULL)
2e5010
+	PHP_FE(fastcgi_finish_request,                    cgi_fcgi_sapi_no_arginfo)
2e5010
+	PHP_FE(apache_request_headers,                    cgi_fcgi_sapi_no_arginfo)
2e5010
+	PHP_FALIAS(getallheaders, apache_request_headers, cgi_fcgi_sapi_no_arginfo)
2e5010
 	PHP_FE_END
2e5010
 };
2e5010
 
2e5010
diff --git a/sapi/fpm/tests/getallheaders.phpt b/sapi/fpm/tests/getallheaders.phpt
2e5010
new file mode 100644
2e5010
index 0000000..b41f1c6
2e5010
--- /dev/null
2e5010
+++ b/sapi/fpm/tests/getallheaders.phpt
2e5010
@@ -0,0 +1,67 @@
2e5010
+--TEST--
2e5010
+FPM: Function getallheaders basic test
2e5010
+--SKIPIF--
2e5010
+
2e5010
+--FILE--
2e5010
+
2e5010
+
2e5010
+require_once "tester.inc";
2e5010
+
2e5010
+$cfg = <<
2e5010
+[global]
2e5010
+error_log = {{FILE:LOG}}
2e5010
+[unconfined]
2e5010
+listen = {{ADDR}}
2e5010
+pm = dynamic
2e5010
+pm.max_children = 5
2e5010
+pm.start_servers = 1
2e5010
+pm.min_spare_servers = 1
2e5010
+pm.max_spare_servers = 3
2e5010
+EOT;
2e5010
+
2e5010
+$code = <<
2e5010
+
2e5010
+echo "Test Start\n";
2e5010
+var_dump(getallheaders());
2e5010
+echo "Test End\n";
2e5010
+EOT;
2e5010
+
2e5010
+$headers = [];
2e5010
+$tester = new FPM\Tester($cfg, $code);
2e5010
+$tester->start();
2e5010
+$tester->expectLogStartNotices();
2e5010
+$tester->request(
2e5010
+		'', 
2e5010
+		[
2e5010
+			'HTTP_X_FOO' => 'BAR',
2e5010
+			'HTTP_FOO'   => 'foo'
2e5010
+		]
2e5010
+	)->expectBody(
2e5010
+		[
2e5010
+			'Test Start',
2e5010
+			'array(4) {',
2e5010
+			'  ["Foo"]=>',
2e5010
+			'  string(3) "foo"',
2e5010
+			'  ["X-Foo"]=>',
2e5010
+			'  string(3) "BAR"',
2e5010
+			'  ["Content-Length"]=>',
2e5010
+			'  string(1) "0"',
2e5010
+			'  ["Content-Type"]=>',
2e5010
+			'  string(0) ""',
2e5010
+			'}',
2e5010
+			'Test End',
2e5010
+		]
2e5010
+	);
2e5010
+$tester->terminate();
2e5010
+$tester->expectLogTerminatingNotices();
2e5010
+$tester->close();
2e5010
+
2e5010
+?>
2e5010
+Done
2e5010
+--EXPECT--
2e5010
+Done
2e5010
+--CLEAN--
2e5010
+
2e5010
+require_once "tester.inc";
2e5010
+FPM\Tester::clean();
2e5010
+?>
2e5010
-- 
2e5010
2.1.4
2e5010