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