Can't get custom http headers

Marco Gasi
Marco Gasi used Ask the Experts™
Hi everybody.
I'm writing the php backend for an Android native app developed by another team.
They are sending to the server in the http headers the value of user_token but I'm not able to get it. I used getllheaders() functions but it doesn't return it.
I have added to .htaccess following lines:
RewriteEngine on
RewriteRule .? - [E=user_token:%{HTTP:user_token}]

Open in new window

and then tried to find the value in the superglobal $_SERVER. the index is present but it is empty.

I performed several tests using but with no success (

I really don't know how to solve this issue: any idea?
Thank you
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

If they're sending values via HTTP headers, then you shouldn't need the .htaccess. HTTP headers will automatically come through in $_SERVER. Trying removing the .htaccess file from the equation.
Marco GasiFreelancer
Top Expert 2010


Hello gr8gonzo. I tried (and I have already tried): my custom header is missing. If I add the htaccess it is present but empty, probably because of the htaccess.
It looks like my custom header is totally ignored and I confess I don't know anything about this so I can't guess what is the issue. I read about CORS, but in my script there is no meta tag at all, just plain php...
Dave BaldwinFixer of Problems
Most Valuable Expert 2014

I would write a PHP test page that sets your custom header with the PHP 'header' command and see if it comes thru.  If it does and you're not getting it from the app, then maybe they need to show you that it exists.
Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

If it's not there without the .htaccess, then it's not being sent. The fact that the .htaccess makes an empty header appear just reinforces this - the .htaccess is adding a header but it has no source value, so the entry is empty.
Most Valuable Expert 2017
Distinguished Expert 2018
If getallheaders() is not seeing the header then
a) It is not being sent
b) It is not being sent properly

Create yourself a good reflection script - this is a script you can point your app at and it will dump what is sent to it.
reflect('POST', $_POST);
reflect('GET', $_GET);
reflect('COOKIES', $_COOKIE);
reflect('FILES', $_FILES);
reflect('SERVER', $_SERVER);
$raw = file_get_contents('php://input');
reflect('RAW', $raw);
$headers = getallheaders();
reflect('HEADERS', $headers);

function reflect($source, $item)
  $msg = date('Y-m-d H:i:s') . "[{$source}] - " . print_r($item, true) . "\n";

  file_put_contents(REFLECT_FILE, $msg, FILE_APPEND);

Open in new window

Point your app to that then view the reflect.log (or whatever log file you used) to see what was sent.

I used my apitester to send the header Auth-token:abcdef to the above script
It gave me this
2018-04-19 23:29:31[HEADERS] - Array
    [Host] => server
    [User-Agent] => Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
    [Accept] => text/plain, */*; q=0.01
    [Accept-Language] => en-US,en;q=0.5
    [Accept-Encoding] => gzip, deflate
    [Referer] => http://domain/apitester.html
    [Content-Type] => application/json
    [Auth-token] => abcdef            <=============== HEADER
    [X-Requested-With] => XMLHttpRequest
    [Content-Length] => 15
    [Cookie] => PHPSESSID=kfkb1crrcfne7i10vf8rv7gga0
    [Connection] => keep-alive

Open in new window

So here's a quick testing script:
// thispage.php

  $ch = curl_init("http://localhost/thispage.php?test=1");
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
  curl_setopt($ch, CURLOPT_POSTFIELDS, array());
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('usertoken: abcdef0123456789'));
  $result = curl_exec($ch);
  echo "<pre>" . $result . "</pre>";

Open in new window

The script uses cURL to post to itself along with a custom HTTP header called "usertoken". When the script is called this way, it will dump the $_SERVER contents. When I tried this on my local dev server, I see this as a result:

    [HTTP_HOST] => localhost
    [HTTP_ACCEPT] => */*
    [HTTP_USERTOKEN] => abcdef0123456789   <-------------------------------
    [PATH] => C:\....blahblahblah

Open in new window

So you can see that the token is passed through.

The problem may be that underscores _ are not valid characters in HTTP headers. Use dashes if you need to separate words in headers, like "User-Token", NOT "User_Token" - the underscore will likely NOT be seen as a valid header and thus not come through.

Looks like Julian and I were on the same page but he beat me to the punch with the reflection script.
Marco GasiFreelancer
Top Expert 2010


Thank you guys. I'll try your scripts. Using with a my test script in another domain, everything works fine. So in the domain of my client there is something which is blocking custom headers.
Now the questions: where do I have to look for? In the main htaccess in the web root? Or Do I have to check if Php is installed as Apache extension or CGI script? Or something else?

Could be a variety of sources. I would just follow the path of the request: 
--> recipient IP receiver (router / firewall)
  --> possible software firewall on the server hosting Apache
    --> Apache main config (any directives that might strip out headers or rewrite the request)
      --> Apache plugins (any security plugins / modules that might adjust headers)
        --> .htaccess file
          --> PHP code that might run before yours

Without knowing the infrastructure, it's hard to say for sure what places to look. However, I will say that it's far more likely that the request is being intercepted and rewritten/rerouted to the final location than it is for the headers to simply be stripped out.

I would personally use a network script or application for sending the HTTP requests instead of, so you can use a proxy like Fiddler to watch the traffic and see if the request is being redirected somewhere along the line.
Marco GasiFreelancer
Top Expert 2010


The hyphen vs underscore was the origin of my issue! Thank you gr8gonzo for having pointed it out. And thanks to Julian for his good script, I'm sure I'll use it soon or later :)

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial