Skip to content

Commit aee271e

Browse files
Implemented FR #65917 (getallheaders() is not supported by the built-in...)
- Implemented apache_request_headers() and getallheaders() alias in CLI server - Implemented apache_response_headers() in CLI server using FastCGI code Conflicts: NEWS UPGRADING
1 parent 1984919 commit aee271e

File tree

5 files changed

+134
-2
lines changed

5 files changed

+134
-2
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ PHP NEWS
66
. Fixed whitespace part of bug #64874 ("json_decode handles whitespace and
77
case-sensitivity incorrectly"). (Andrea Faulds)
88

9+
- CLI server:
10+
. Implemented FR #65917 (getallheaders() is not supported by the built-in web
11+
server) - also implements apache_response_headers() (Andrea Faulds)
12+
913

1014
14 Nov 2013, PHP 5.5.6
1115

UPGRADING

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ PHP 5.5 UPGRADE NOTES
8585
configure this. The service can now use Type=notify in the systemd
8686
unit file. (Remi)
8787

88+
- CLI server:
89+
Now supports apache_request_headers() and apache_response_headers()
90+
8891
========================================
8992
3. Deprecated Functionality
9093
========================================

sapi/cgi/cgi_main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,8 +1688,8 @@ static void add_response_header(sapi_header_struct *h, zval *return_value TSRMLS
16881688

16891689
PHP_FUNCTION(apache_response_headers) /* {{{ */
16901690
{
1691-
if (ZEND_NUM_ARGS() > 0) {
1692-
WRONG_PARAM_COUNT;
1691+
if (zend_parse_parameters_none() == FAILURE) {
1692+
return;
16931693
}
16941694

16951695
if (!&SG(sapi_headers).headers) {

sapi/cli/php_cli_server.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ typedef struct php_cli_server_request {
133133
char *query_string;
134134
size_t query_string_len;
135135
HashTable headers;
136+
HashTable headers_original_case;
136137
char *content;
137138
size_t content_len;
138139
const char *ext;
@@ -435,6 +436,75 @@ static const char *get_mime_type(const char *ext, size_t ext_len) /* {{{ */
435436
return NULL;
436437
} /* }}} */
437438

439+
PHP_FUNCTION(apache_request_headers) /* {{{ */
440+
{
441+
php_cli_server_client *client;
442+
HashTable *headers;
443+
char *key;
444+
uint key_len;
445+
char **value_pointer;
446+
HashPosition pos;
447+
448+
if (zend_parse_parameters_none() == FAILURE) {
449+
return;
450+
}
451+
452+
client = SG(server_context);
453+
headers = &client->request.headers_original_case;
454+
455+
array_init_size(return_value, zend_hash_num_elements(headers));
456+
457+
zend_hash_internal_pointer_reset_ex(headers, &pos);
458+
while (zend_hash_get_current_data_ex(headers, (void **)&value_pointer, &pos) == SUCCESS) {
459+
zend_hash_get_current_key_ex(headers, &key, &key_len, NULL, 0, &pos);
460+
add_assoc_string_ex(return_value, key, key_len, *value_pointer, 1);
461+
zend_hash_move_forward_ex(headers, &pos);
462+
}
463+
}
464+
/* }}} */
465+
466+
static void add_response_header(sapi_header_struct *h, zval *return_value TSRMLS_DC) /* {{{ */
467+
{
468+
char *s, *p;
469+
int len;
470+
ALLOCA_FLAG(use_heap)
471+
472+
if (h->header_len > 0) {
473+
p = strchr(h->header, ':');
474+
len = p - h->header;
475+
if (p && (len > 0)) {
476+
while (len > 0 && (h->header[len-1] == ' ' || h->header[len-1] == '\t')) {
477+
len--;
478+
}
479+
if (len) {
480+
s = do_alloca(len + 1, use_heap);
481+
memcpy(s, h->header, len);
482+
s[len] = 0;
483+
do {
484+
p++;
485+
} while (*p == ' ' || *p == '\t');
486+
add_assoc_stringl_ex(return_value, s, len+1, p, h->header_len - (p - h->header), 1);
487+
free_alloca(s, use_heap);
488+
}
489+
}
490+
}
491+
}
492+
/* }}} */
493+
494+
PHP_FUNCTION(apache_response_headers) /* {{{ */
495+
{
496+
if (zend_parse_parameters_none() == FAILURE) {
497+
return;
498+
}
499+
500+
if (!&SG(sapi_headers).headers) {
501+
RETURN_FALSE;
502+
}
503+
array_init(return_value);
504+
zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t)add_response_header, return_value TSRMLS_CC);
505+
}
506+
/* }}} */
507+
438508
/* {{{ cli_server module
439509
*/
440510

@@ -479,9 +549,15 @@ zend_module_entry cli_server_module_entry = {
479549
};
480550
/* }}} */
481551

552+
ZEND_BEGIN_ARG_INFO(arginfo_no_args, 0)
553+
ZEND_END_ARG_INFO()
554+
482555
const zend_function_entry server_additional_functions[] = {
483556
PHP_FE(cli_set_process_title, arginfo_cli_set_process_title)
484557
PHP_FE(cli_get_process_title, arginfo_cli_get_process_title)
558+
PHP_FE(apache_request_headers, arginfo_no_args)
559+
PHP_FE(apache_response_headers, arginfo_no_args)
560+
PHP_FALIAS(getallheaders, apache_request_headers, arginfo_no_args)
485561
{NULL, NULL, NULL}
486562
};
487563

@@ -1300,6 +1376,7 @@ static int php_cli_server_request_ctor(php_cli_server_request *req) /* {{{ */
13001376
req->query_string = NULL;
13011377
req->query_string_len = 0;
13021378
zend_hash_init(&req->headers, 0, NULL, (void(*)(void*))char_ptr_dtor_p, 1);
1379+
zend_hash_init(&req->headers_original_case, 0, NULL, NULL, 1);
13031380
req->content = NULL;
13041381
req->content_len = 0;
13051382
req->ext = NULL;
@@ -1325,6 +1402,7 @@ static void php_cli_server_request_dtor(php_cli_server_request *req) /* {{{ */
13251402
pefree(req->query_string, 1);
13261403
}
13271404
zend_hash_destroy(&req->headers);
1405+
zend_hash_destroy(&req->headers_original_case);
13281406
if (req->content) {
13291407
pefree(req->content, 1);
13301408
}
@@ -1569,6 +1647,7 @@ static int php_cli_server_client_read_request_on_header_value(php_http_parser *p
15691647
{
15701648
char *header_name = zend_str_tolower_dup(client->current_header_name, client->current_header_name_len);
15711649
zend_hash_add(&client->request.headers, header_name, client->current_header_name_len + 1, &value, sizeof(char *), NULL);
1650+
zend_hash_add(&client->request.headers_original_case, client->current_header_name, client->current_header_name_len + 1, &value, sizeof(char *), NULL);
15721651
efree(header_name);
15731652
}
15741653

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
Implement Req #65917 (getallheaders() is not supported by the built-in web server)
3+
--SKIPIF--
4+
<?php
5+
include "skipif.inc";
6+
?>
7+
--FILE--
8+
<?php
9+
include "php_cli_server.inc";
10+
php_cli_server_start(<<<'PHP'
11+
header('Content-Type: text/plain');
12+
var_dump(getallheaders());
13+
var_dump(apache_request_headers());
14+
var_dump(apache_response_headers());
15+
PHP
16+
);
17+
18+
$opts = array(
19+
'http'=>array(
20+
'method'=>"GET",
21+
'header'=>"Foo-Bar: bar\r\n"
22+
)
23+
);
24+
25+
$context = stream_context_create($opts);
26+
echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS, false, $context);
27+
?>
28+
--EXPECTF--
29+
array(2) {
30+
["Host"]=>
31+
string(%s) "%s:%s"
32+
["Foo-Bar"]=>
33+
string(3) "bar"
34+
}
35+
array(2) {
36+
["Host"]=>
37+
string(%s) "%s:%s"
38+
["Foo-Bar"]=>
39+
string(3) "bar"
40+
}
41+
array(2) {
42+
["X-Powered-By"]=>
43+
string(%s) "PHP/%s"
44+
["Content-Type"]=>
45+
string(10) "text/plain"
46+
}

0 commit comments

Comments
 (0)