We help IT Professionals succeed at work.

$_SERVER Variable question

Silas2
Silas2 asked
on
916 Views
Last Modified: 2017-03-24
I'm new to PHP and I'm working with the monster Magento, in my shared ISP environment my header 'Authorization' (used for REST) is getting stripped and being put into $_SERVER['REDIRECT_HTTP_AUTHORIZATION'].
Is there a way to inject the $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] into the headers as 'Authorization:xxxx' ?
Comment
Watch Question

Most Valuable Expert 2011
Author of the Year 2014

Commented:
Please see: http://php.net/manual/en/features.http-auth.php

Can you please do two things for us.  Please show us the exact PHP header() statements you're using, and please install this little PHP script, shown here in its entirety, and post a link so we can visit your site and see your PHP settings.  You can take it down after we visit, but we need to see what's set up in the PHP environment.  Thanks.
<?php phpinfo();

Open in new window

Author

Commented:
Connected to chamberspetsupplies.co.uk.
Escape character is '^]'.
POST /p10.headers.php HTTP/1.1
Authorization: OAuth oauth_callback="http%3A%2F%2Flocalhost%3A8888",oauth_consumer_key="xxx",oauth_nonce="xg6dlqngr7r7kvwn",oauth_signature="yyy",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1489768227",oauth_version="1.0"
Content-Type: application/json
Accept: application/json
User-Agent: RestSharp/105.2.3.0
Host: chamberspetsupplies.co.uk
Content-Length: 0
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

HTTP/1.1 200 OK
Date: Mon, 20 Mar 2017 17:53:48 GMT
Server: Apache
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html

90b
Array
(
[Connection] => close
[Accept-Encoding] => gzip, deflate
[Content-Length] => 0
[Host] => chamberspetsupplies.co.uk
[User-Agent] => RestSharp/105.2.3.0
[Accept] => application/json
[Content-Type] => application/json
)
Array
(
[HTTP_USER_AGENT] => RestSharp/105.2.3.0
[HTTP_ACCEPT] => application/json
[CONTENT_TYPE] => application/json
[REDIRECT_STATUS] => 200
[REDIRECT_HANDLER] => hs-php55-script
[REDIRECT_HTTP_AUTHORIZATION] => OAuth oauth_callback="http%3A%2F%2Flocalhost%3A8888",oauth_consumer_key="xxx",oauth_nonce="xg6dlqngr7r7kvwn",oauth_signature="yyy",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1489768227",oauth_version="1.0"
[FCGI_ROLE] => RESPONDER
[PHP_SELF] => /p10.headers.php
[REQUEST_TIME_FLOAT] => 1490032432.9059
[REQUEST_TIME] => 1490032432
[argv] => Array
(
)

[argc] => 0
)

===

You can see the HTTP_AUTHORIZATION / AUTHORIZATION header is passed in $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] due to the nature of FastCGI PHP

Author

Commented:
Is that ok Ray? You can see the Authorization header going out in the Post:
Authorization: OAuth oauth_callback="http%3A%2F%2Flocalhost%3A8888",oauth_consumer_key="xxx",oauth_nonce="xg6dlqngr7r7kvwn",oauth_signature="yyy",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1489768227",oauth_version="1.0" 

Open in new window

And then server side its stripped from the headers, but turns up in $_SERVER['REDIRECT_HTTP_AUTHORIZATION']  (something to do with security in shared (i.e. cheap) hosting the ISP's telling me.
I'd like to be able to inject it back into the header so the OAuth libraries work in Magento without hacking the core..is that possible?
CERTIFIED EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
How are you attempting to access the headers?
Most Valuable Expert 2011
Author of the Year 2014
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
Its  Magento core, Http.php (called with the param 'Authorization') BUT just going to copy/paste that, I saw the bottom bit of it....don't know if it help.:
 public function getHeader($header)
    {
        if (empty($header)) {
            #require_once 'Zend/Controller/Request/Exception.php';
            throw new Zend_Controller_Request_Exception('An HTTP header name is required');
        }

        // Try to get it from the $_SERVER array first
        $temp = strtoupper(str_replace('-', '_', $header));
        if (isset($_SERVER['HTTP_' . $temp])) {
            return $_SERVER['HTTP_' . $temp];
        }
// This seems to be the only way to get the Authorization header on
        // Apache
        if (function_exists('apache_request_headers')) {
            $headers = apache_request_headers();
            if (isset($headers[$header])) {
                return $headers[$header];
            }
            $header = strtolower($header);
            foreach ($headers as $key => $value) {
                if (strtolower($key) == $header) {
                    return $value;
                }
            }

Open in new window

Author

Commented:
Thanks for that suggestion Ray, I'll try it tomorrow.
Most Valuable Expert 2011
Author of the Year 2014

Commented:
Sounds good.  If it doesn't work, post back and we can try something else.
Ref: http://php.net/manual/en/function.apache-request-headers.php

Author

Commented:
Sorry to ask such a question, but I can't seem to find this anywhere on the web, can I actually write to $_SERVER variables?
When I run this code:
 header("Authorization: testvalue" );
foreach (getallheaders() as $name => $value) {
    fwrite($myfile, "$name: $value\n"); ;
}

Open in new window

I can't see the header being added, nor can I see my new value in the $_SERVER array..?
Most Valuable Expert 2011
Author of the Year 2014

Commented:
You may need the assistance of a Magento/PHP expert, but before we start spending a lot of money on consultant services, let's take a step back and follow the behavior of client/server protocols.

The client makes a request (both "client" and "request" are terms of art*).  The request includes a series of request variables.  These are things like the protocol (probably HTTP 1.1) the method, like GET or HEAD, the URL, the user-agent, the cookies, etc.  The client request will include the authorization, if any.

The request is atomic, complete and stateless.  After making the request, the client sits and waits for the server response.

Upon receiving the request, the server makes a response ("server" and "response" are terms of art*).  Your PHP script will be started with certain variables pre-loaded by the server environment.  These include $_GET, $_POST, $_COOKIE, $_SERVER, etc.  I believe, but cannot verify, that your client is sending an authorization in the request, and your server is putting this into your $_SERVER array.  So let's please go back to this comment and see if we can get the information we asked for:
https://www.experts-exchange.com/questions/29010605/SERVER-Variable-question.html#a42058053

* Please see this article for an explanation of these terms.
https://www.experts-exchange.com/articles/11271/Understanding-Client-Server-Protocols-and-Web-Applications.html

Sidebar note: You might want to check this:
https://validator.w3.org/check?uri=http%3A%2F%2Fchamberspetsupplies.co.uk%2F&charset=%28detect+automatically%29&doctype=Inline&group=0

Author

Commented:
Thanks for that, but just a simple yes/no, can I write to the $_SERVER array?
CERTIFIED EXPERT
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION
Most Valuable Expert 2011
Author of the Year 2014

Commented:
If by "write to" you mean set values in the array, yes, you can write to the $_SERVER array.  But don't do that.  It's a hack.  Here is how you can test the idea for yourself.
<?php $_SERVER['foo'] = 'bar';
var_dump($_SERVER);

Open in new window


It probably should be immutable, but it's not.  And so you can change it.  You can change any of the PHP superglobal variables, but when you do, you write code that is brittle, unportable, and impossible to test.

When you wrote above that you're new to PHP, it causes me to think that you might benefit from some guidance about things like this.  I would never let a programmer write PHP code to modify the $_SERVER array.  It's not something we do, ever.  So if you can explain what you're trying to accomplish by modifying $_SERVER, maybe we can find a more mainstream way to help you get to your goals.

Author

Commented:
Thanks for that. I'm getting this spooky thing, if I run a $_SERVER dump in a test.php file I can see the elusive REDIRECT_HTTP_AUTHORIZATION value, BUT if I do the same dump at the top of the Magento index.php file, it's gone...?
I guess it must be something to do with the rewrite as I'm making the request myshop.com/oauth/initiate, is there anyway I can get it back?
CERTIFIED EXPERT

Commented:
So if you can explain what you're trying to accomplish by modifying $_SERVER, maybe we can find a more mainstream way to help you get to your goals.

hi @ray : from what i gather magento implements 3 way authentication ( probably with an additional sso involved ) and the headers are messed up by the shared environment. the goal is not to send a header back but rather get magento to use the REDIRECTED_xx header rather than xx

so this boils down to either
- change the magento code ( easy but not sure the core can be hacked in a clean way that survives updates )
- change the php superglobals ( i'm against as well usually, but in this case this might be the simplest way and using an auto prepended script keeps the hosting-related hacks together with the hosting-related stuff )
- add an extra proxying layer to rewrite the headers ( probably not allowed by the host )
- fight with the host so they stop messing with the headers ( i think they're bound to say no )
- change hosting
- ... and whatever other solutions i did not think of

Author

Commented:
I prepared to hack the Magento core now, I don't care anymore!!! but I didn't realise the variables have disappeared in the index.php...can I get them back?
CERTIFIED EXPERT

Commented:
hmm... are you sure index.php is actually the first file that is called ?
you might want to print get_included_files just to make sure there is no other script removing stuff beforehand

Author

Commented:
I Just did a dump of get_included_files as the first line of index.php and it is only coming back with :
chamberspetsupplies.co.uk/index.php
Most Valuable Expert 2011
Author of the Year 2014

Commented:
I think i would probably recommend a change in hosting.  I attend PHP conferences occasionally and it's pretty rare to find anyone trying to run Magento on shared hosting.  Even GoDaddy says it's a bad practice, and when GoDaddy says it's bad, it's got to be truly horrid.  The Magento forums recommend at least VPS.

I haven't evaluated this, but it looks interesting and certainly better than hacking your ecommerce software!
https://www.cloudways.com/blog/magento-on-google-cloud/

Author

Commented:
I just paid for a year!!! I can't believe I can't scrape that value out somehow, its getting to the server. would an auto_prepend impact performance?

Author

Commented:
Can I set an environment variable in .htaccess from REDIRECT_HTTP_AUTHORIZATION?
CERTIFIED EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
Thanks,I don't mind hacking Magento anymore....I'm losing the REDIRECT_HTTP_AUTHORIZATION goodness in index.php.
I'm trying to set an environment variable in .htacess, I can add the variable with:
SetEnv ZZZMYVAR %{ENV:REDIRECT_HTTP_AUTHORIZATION}
It is adding ZZZMYVAR , but its populating with  "%{ENV:REDIRECT_HTTP_AUTHORIZATION}", any idea if I can pull the variable out?
Most Valuable Expert 2011
Author of the Year 2014

Commented:
Try this and show us what you get:
<?php var_dump($_SERVER);

Open in new window

Author

Commented:
Actually the penny's dropping a bit. Apparently a rewrite rule creates a new request and appends REDIRECT so as the value already has a REDIRECT on it, it gets lost on the index.php rewrite rule when the redirect happens.

Author

Commented:
Errrr.....right to that end....from this page:
https://httpd.apache.org/docs/2.4/rewrite/advanced.html
this post:

You say: "Note that environment variables do not survive an external redirect." It is not too much definitely. Actually, environment variables sometimes do not survive an internal redirect too. It is worth to mention here that if in .htaccess context path is rewritten and env var named Name is set, on next round it can be accessed under name REDIRECT_Name, not Name.
Well, the most popular snippet with "redirecting everything to index.php":
 
# Naive attempt to protect agains looping:
RewriteCond "%{ENV:rewritten}" "!=1"
RewriteRule   "(.*)"   "index.php/$1" [E=rewritten:1]

# in .htaccess should look like this:
RewriteCond "%{ENV:REDIRECT_rewritten}" "!=1"
RewriteRule   "(.*)"   "index.php/$1" [E=rewritten:1]
I didn't quite follow the logic (at all if I'm honest!) but I pasted that (non-naïve even though I qualify as naïve) , in and.....I am getting my values but the value is 'REDIRECT_REDIRECT_REDIRECT_HTTP_AUTHORIZATION: OAuth oauth_callback
three recusive depths down....

Author

Commented:
Yippee, I'm getting the Authorisation to work, but all I've done is remove the rewrite rule for index.php, so the htaccess looks like this:
RewriteEngine On
	RewriteBase /
#	RewriteRule ^index\.php$ - [L]
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteCond %{REQUEST_FILENAME} !-d

Open in new window

So NO rewrites of index.php, although it seems to be processing requests ok.
The vanilla magento has this:
RewriteEngine On
	RewriteBase /
	RewriteRule ^index\.php$ - [L]
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteCond %{REQUEST_FILENAME} !-d
	RewriteRule . /index.php [L]

Open in new window

I can retrieve the authorization value with :
$_SERVER['REDIRECT_REDIRECT_HTTP_AUTHORIZATION']
Its getting a second redirect even though I've turned the rewrite rule off  + in the header dump its doing this:
REDIRECT_STATUS: 200
REDIRECT_HANDLER: hs-php55-script
REDIRECT_REDIRECT_HTTP_AUTHORIZATION: OAuth oauth_callback="http%3A%2F%2Flocalhost%3A8888",oauth_consumer_key="xxx",oauth_nonce="hm8wdk4ji6xht2jt",oauth_signature="yyy,oauth_signature_method="HMAC-SHA1",oauth_timestamp="1490210500",oauth_version="1.0"
REDIRECT_REDIRECT_STATUS: 200
REDIRECT_REDIRECT_REDIRECT_HTTP_AUTHORIZATION: OAuth oauth_callback="http%3A%2F%2Flocalhost%3A8888",oauth_consumer_key="xxx",oauth_nonce="hm8wdk4ji6xht2jt",oauth_signature="yyy",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1490210500",oauth_version="1.0"

Open in new window

so it looks like its doing a second redirect, anyone shed any light on this?
CERTIFIED EXPERT

Commented:
its getting to the server. would an auto_prepend impact performance?
the impact would be negectible given the fact you are using magento

I am getting my values but the value is 'REDIRECT_REDIRECT_REDIRECT_HTTP_AUTHORIZATION: OAuth oauth_callback
three recusive depths down....

if you are ready to hack magento that's easy to hack through, even with unlimited depth.

be careful when hacking redirections : you are very likely to produce a mess...
but in your case you seem to be preventing a generic redirection of */index.php to /index.php. no idea what is the impact on magento but there should likely be none to little.but i would not do it nevertheless : i believe hacking $_SERVER or preventing this behavior altogether to be much safer

so it looks like its doing a second redirect, anyone shed any light on this?

2 reasons
- apache redirects work by looping unless there is no change so you actually may get redirected at least once before ou even reach an url ending in /index.php
- there may be a previous change performed by the host with a proxy or possible handling of virtual hosts through redirects ( so the server loads fast )

Author

Commented:
I would rather hack the $_SERVER variables, but tell me how could I do that when, if it performs the redirect I've removed, the variable I need has been removed before hitting the first line of index.php?
CERTIFIED EXPERT

Commented:
i assume you figured it out since you closed the question.
feel free to ask for more help if needed, or post the actual hack you used in the end for future readers reference.
regards

Author

Commented:
Thanks for the offer, because I isolated the problem to removing a rewrite rule its fixed but I don't understand why!! So I thought the topic had changed so I've asked another question about rewrite rules.....please please if you can shed any light:
https://www.experts-exchange.com/questions/29011196/Rewrite-Rule-head-scratcher.html

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.