Can't get custom http headers

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
LVL 32
Marco GasiFreelancerAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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 GasiFreelancerAuthor Commented:
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 ProblemsCommented:
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.
10 Tips to Protect Your Business from Ransomware

Did you know that ransomware is the most widespread, destructive malware in the world today? It accounts for 39% of all security breaches, with ransomware gangsters projected to make $11.5B in profits from online extortion by 2019.

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.
Julian HansenCommented:
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.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Looks like Julian and I were on the same page but he beat me to the punch with the reflection script.
Marco GasiFreelancerAuthor Commented:
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 GasiFreelancerAuthor Commented:
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 :)
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.