Unable to read custom headers from apache_request_headers()

#1
I've run into a strange problem in my Lightspeed environment (production) that doesn't happen in my two Apache environments (local and sandbox).

Local
OS X 10.9.4 (64-bit)
Apache 2.0 (API version 20051115)
PHP 5.3.27 (CGI)

Sandbox
Ubuntu 12.04.4 LTS (64-bit)
Apache 2.4.9 (API version 20120211)
PHP 5.5.14 (CGI)

Production
CloudLinux Server release 6.5 (Pavel Popovich)
Lightspeed V6.6
PHP 5.4.28 (LSAPI)

Here's how to simply recreate the trouble:

$headers = apache_request_headers();

var_dump($headers);
echo($headers['handshake']);

And send a custom header “handshake” with a value of an alphanumeric string like “982e7c3e992125a0cf0c24f67985d575”.

Run in local and sandbox, and it spits out the following:

array(10) {
["Host"]=>
string(20) “sandbox.example.com”
["Connection"]=>
string(10) "keep-alive"
["User-Agent"]=>
string(120) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"
["handshake"]=>
string(32) "982e7c3e992125a0cf0c24f67985d575"
["Postman-Token"]=>
string(36) "52c80c2b-a060-67c4-d9fb-5209d130aa0f"
["Accept"]=>
string(3) "*/*"
["DNT"]=>
string(1) "1"
["Accept-Encoding"]=>
string(17) "gzip,deflate,sdch"
["Accept-Language"]=>
string(14) "en-US,en;q=0.8"
["Cookie"]=>
string(59) "stage_last_visit=1085402127; stage_last_activity=1400762338"
}
string(32) "982e7c3e992125a0cf0c24f67985d575"

Run the same in production though, and you’ll get the following:

array(10) {
["Host"]=>
string(27) “www.example.com”
["Connection"]=>
string(10) "keep-alive"
["User-Agent"]=>
string(120) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"
["handshake"]=>
string(32) "982e7c3e992125a0cf0c24f67985d575"
["Postman-Token"]=>
string(36) "7beb573a-4587-e179-113b-23392c676dd9"
["Accept"]=>
string(3) "*/*"
["DNT"]=>
string(1) "1"
["Accept-Encoding"]=>
string(17) "gzip,deflate,sdch"
["Accept-Language"]=>
string(14) "en-US,en;q=0.8"
["Cookie"]=>
string(57) "prod_last_visit=1084717853; prod_last_activity=1400078006"
}
NULL

The same goes for Postman-Token, but all the other headers can be accessed directly. The only commonality between the headers that can’t be accessed in the Lightspeed environment is that they’re both custom headers.

I discovered that spitting out the array keys and values in a foreach loop works, strangely enough. It's just trying to access the array element through $array['key_name'] that doesn't work.
 

mistwang

LiteSpeed Staff
#2
It is caused by a bug in PHP LiteSpeed SAPI code, the patch is

--- lsapilib.c 10 Jul 2014 18:32:32 -0000 1.101
+++ lsapilib.c 11 Jul 2014 19:10:34 -0000 1.102
@@ -1928,6 +1928,7 @@
{
pKey = pReq->m_pHttpHeader + pCur->nameOff;
keyLen = pCur->nameLen;
+ *(pKey + keyLen ) = 0;

pValue = pReq->m_pHttpHeader + pCur->valueOff;
*(pValue + pCur->valueLen ) = 0;


Just add one line of code to add a \0 to the end of the header name.
You can rebuild lsphp binary to apply the change.
 
Top