PHP Redirect problem with subdomain - php

I'm using PHP to redirect a page back to the previous page with the following:
header("Location: {$_SERVER['HTTP_REFERER']}");
This set of pages will only be used by internal users, so I'm not terribly concerned about the fact that the referer will not always be available.
The problem I'm running in to is that if the referer looks like http://subdomain.domain.com/test.php?id=13, the redirect ends up going to http://subdomain.domain.com/.domain.com/test.php?id=13. Notice the additional .domain.com/ in the url.
I've tested by hardcoding the value, and it causes the problem as well. phpMyAdmin seems to suffer the same issue, but only on this particular server.
If this is not an SO question, please move accordingly.
EDIT: per #yaggo
test.php contains only header("Location: http://subdomain.domain.com/test2.php");
curl --head --referer 'http://subdomain.domain.com/' 'http://subdomain.domain.com/test.php'
HTTP/1.1 302 Found
Server: nginx/0.7.64
Date: Fri, 02 Apr 2010 17:21:45 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.2.12-pl0-gentoo
Location: .domain.com/test2.php

I've recreated both your programs on my server
once with
header("Location: http://subdomain.domain.com/some/place");
and once with
header("Location: {$_SERVER['HTTP_REFERER']}");
and both give the corret result
curl --head --referer 'http://subdomain.domain.com/some/place' 'http://subdomain.domain.com/test.php'
HTTP/1.1 302 Found
Date: Fri, 02 Apr 2010 17:48:54 GMT
Server: Apache/2.0.52 (Red Hat)
X-Powered-By: PHP/5.1.2
Location: http://subdomain.domain.com/some/place
Connection: close
Content-Type: text/html
I'm using a different version of PHP and a different webserver, so there's two things to investigate.

It seems that your nginx configuration is causing the problems.
Its totally possible that nginx is modifying the response headers. This is not by default - you could have a configuration that is aimed for it to behave as a reverse proxy etc.
Have you tried testing the redirect on a nginx with its default configuration?

[...] the redirect ends up going to http://subdomain.domain.com/.domain.com/test.php?id=13.
Can you isolate the problem a little bit more? Is that url exactly what is returned by PHP or is it how browser (Chrome?) sees it?
Can you check the actual headers e.g. with curl:
$ curl --head --referer 'http://your-referer' 'http://your-page/'

header("Location: ".$_SERVER['HTTP_REFERER']);
Edited:
Check you .htaccess settings or if no solution found u can use preg_replace to remove that last ".domain.com"
but it looks that is a not a php error.
OR use javascript to get the referer address...
then use window.location.href = url; to redirect ...

Related

Transfer-Encoding: chunked sent twice (chunk size included in response body)

I'm using Apache 2.2 and PHP 7.0.1. I force chunked encoding with flush() like in this example:
<?php
header('HTTP/1.1 200 OK');
echo "hello";
flush();
echo "world";
die;
And I get unwanted characters at the beginning and end of the response:
HTTP/1.1 200 OK
Date: Fri, 09 Sep 2016 15:58:20 GMT
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/7.0.9
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
a
helloworld
0
The first one is the chunk size in hex (10 = A). I'm using Klein as PHP router and I have found that the problem comes up only when the HTTP status header is rewritten. I guess there is a problem with my Apache config, but I wasn't able to figure it out.
Edited: My problem had nothing to do with Apache but Nginx and chunked_transfer_encoding directive. Check the answer below.
This is how Transfer-Encoding: chunked works. The extra characters you're seeing are part of the encoding, rather than the body.
A client that understands the encoding will not include them in the result; a client that doesn't doesn't support HTTP/1.1, and should be considered bugged.
As #Joe pointed out before, that is the normal behavior when Chunked transfer enconding is enabled. My tests where not accurate because I was requesting Apache directly on the server. Actually, when I was experiencing the problem in Chrome I was querying a Nginx service as a proxy for Apache.
By running tcpdump I realized that Nginx was rechunking responses, but only when rewritting HTTP status header (header('HTTP/1.1 200 OK')) in PHP. The solution to sending Transfer-Encoding: chunked twice is to set chunked_transfer_encoding off in the location context of my Nginx .php handler.

PHP HTTPS to HTTP

I am having difficulty with the header function in PHP.
The call to the function is initiated on a secure HTTPS page. Every time I call the header function with http://, something somewhere is changing the protocol to HTTPS.
In my program, this example:
header("Location: http://www.google.com");
takes me to https://www.google.com instead.
My environment is IIS 7.5 Windows 2008 64-Bit
PHP 5.5.12 with Fast CGI
Is there something that I have accidentally enabled either in IIS or php.ini that would automatically force http to https?
This does not happen when launching the code from an http page, http to http works, http to https works and https to https work. However, https to http is failing.
I've been searching and most results keep reversing my question by showing me ways to force http to https. I need the opposite.
Thanks in advance for any assistance!
EDIT: Google was an example URL. Sorry.
header("Location: http://www.systronicsinc.com/");
is my actual URL that is failing. This keeps redirecting to https://www.systronicsinc.com/.
This is a raw header from Fiddler.
HTTP/1.1 303 See Other
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Type: text/html; charset=UTF-8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Location: https://www.systronicsinc.com/
Server: Microsoft-IIS/7.5
X-Powered-By: PHP/5.5.12
Set-Cookie: PHPSESSID=va1hh3ff8h0buus689kf86eoc1; path=/
Date: Fri, 24 Oct 2014 17:39:34 GMT
Content-Length: 156
<head><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found here</body>
I find it interesting that the link in the body retained the original http protocol as initially set, but the Location field in the header is modifying it to https. I've been hunting through IIS and my php.ini file. I cannot see anything that would dictate this behavior. Maybe this additional information will spark a thought with someone. Thanks!
Google uses SSL, so https://, for it's websites.
See: https://support.google.com/websearch/answer/173733?hl=en
and: https://www.seroundtable.com/google-ssl-drops-query-data-14188.html
No, Google redirects you to a secure page.
They probably use a function that does something like my https function. Feel free to use.
function https(){
$sv = $_SERVER;
if(!isset($sv['HTTPS'])){
header("LOCATION:https://{$sv['SERVER_NAME']}{$sv['PHP_SELF']}"); die;
}
}
function http(){
$sv = $_SERVER;
if(isset($sv['HTTPS'])){
unset($_SERVER['HTTPS']);
header("LOCATION:http://{$sv['SERVER_NAME']}{$sv['PHP_SELF']}"); die;
}
}

Why do some servers/applications send a second HTTP status header

Why do some web applications/servers/etc issue a non-standard, second, Status header. For example, I'm working with an existing application where, in addition to that HTTP protocal line, there's a second header named status
$ curl -I 'http://example.com/404'
HTTP/1.1 404 Not Found
//...
Status: 404 Not Found
//...
and a stock apache 404 doesn't include it
HTTP/1.1 404 Not Found
Date: Thu, 24 Jul 2014 13:16:28 GMT
Server: Apache/2.2.3 (CentOS)
Connection: close
Content-Type: text/html; charset=iso-8859-1
I'd write this off as one quirky application developer, but I've seen this behavior is other applications over the years, and the Wikipedia article on HTTP headers mentions this header, although it points out the header isn't included in RFC7230.
? "Status" is not listed as a registered header. The "Status-Line" of a "Response" is defined by RFC7230[23] without any explicit "Status:" header name.
Does anyone know the deal here? Is there some browser that needed this at some point? Still needs it? Is this some weird bit of SEO voodoo?
Is there any practical effect to including/not-including this field? Has there ever been?
(I'm specifically working with PHP, if that matters)

Pingdom monitoring tool detecting HTTP 302 Found responses intermittently

I am experiencing intermittent issues when using the Pingdom monitoring tool to check the status of my website.
Every 10-15 minutes I get an alert to say that a 302 has been found. What I can't understand is - i'm not doing any 302 temporary redirects. I am, however, doing 301 redirects (in certain circumstances).
Could this be a false positive from Pingdom?
Also, I have a redirect in code that does this. Would not specifying the HTTP response code
cause an issue here?
header('Location: http://www.ayrshireminis.com');
exit();
The Pingdom data:
Request 1
GET / HTTP/1.0
User-Agent: Pingdom.com_bot_version_1.4_(http://www.pingdom.com/)
Host: www.ayrshireminis.com
Received header
302 Found
Date: Tue, 24 Jul 2012 13:13:25 GMT
Server: Apache
Set-Cookie: prev_session_id=2a7001f5caa79bd36995953bf4853675; expires=Thu, 23-Aug-2012 13:13:25 GMT; path=/; domain=ayrshireminis.com
Location: http://www.ayrshireminis.com/
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=ISO-8859-1
Looks to me like a cookie is being set on the response, then redirecting you to the same page. Because Pingdom uses a number of different monitoring sources, that cookie redirect behavior will cause a lot of problems. Then again, you may need it for actual website visitors.
Rather than monitor the root of the webpage, I would recommend creating a separate /status page just for Pingdom that:
Doesn't set or use cookies
Performs a cheap end-to-end health check of the application and backing services
Returns a 200 response code only if everything checks out OK

Does mod_php honor HEAD requests properly?

The HTTP/1.1 RFC stipulates "The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response." I know Apache honors the RFC but modules don't have to. My question is, does mod_php5 honor this?
The reason I ask is because I just came across an article saying that PHP developers should check this themselves with:
if (stripos($_SERVER['REQUEST_METHOD'], 'HEAD') !== FALSE) {
exit();
}
I googled a second and not much turned up, other than some people saying they try to strange things like mod_rewrite/redirect after getting HEAD requests and some old bug ticket from like 2002 claiming that mod_php still executed the rest of the script by default. So I just ran a quick test by using PECL::HTTP to run
http_head('http://mysite.com/test-head-request.php');
while having:
<?php error_log('REST OF SCRIPT STILL RAN'); ?>
in test-head-request.php to see if the rest of the script still executed, and it didn't.
I figure that should be enough to settle it, but want to get more feedback and maybe help clear up confusion for anyone else who has wondered about this. So if anyone knows off the top of their head (no pun intended) - or have any conventions they use for receiving HEAD requests, that'd be great. Otherwise, I'll grep the C source later and respond in a comment with my findings. Thanks.
The HEAD method is identical to GET
except that the server MUST NOT return
a message-body in the response.
That is why the check should not be performed. Clients should have confidence that HEAD requests process just the same as if a GET was issued (database connection, processing, etc...).
Addendum:
When performing
HEAD /test.php?a=3 HTTP/1.1
Host: somesite.com
PHP will still fill $_GET (and $_REQUEST) with the variables placed in the query string even though it was not a GET request. This allows compliance with the HEAD definition.
I just did a quick test with a PHP file, temp.php, which contains this portion of code :
<?php
echo "Hello, World!\n";
die;
Sending an HTTP GET request to that file gets me the content of the page :
$ telnet localhost 80
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /temp/temp.php HTTP/1.1
Host: localhost
HTTP/1.1 200 OK
Date: Thu, 08 Apr 2010 20:17:35 GMT
Server: Apache/2.2.12 (Ubuntu)
X-Powered-By: PHP/5.3.2RC2
Vary: Accept-Encoding
Content-Length: 14
Content-Type: text/html
Hello, World!
While sending an HTTP HEAD request doesn't :
$ telnet localhost 80
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
HEAD /temp/temp.php HTTP/1.1
Host: localhost
HTTP/1.1 200 OK
Date: Thu, 08 Apr 2010 20:17:50 GMT
Server: Apache/2.2.12 (Ubuntu)
X-Powered-By: PHP/5.3.2RC2
Vary: Accept-Encoding
Content-Type: text/html
Not sure this is always true, though...
I remember a situation (some time ago ; was PHP 5.1) in which I've had to test myself, in the PHP code, if I was getting a GET or a HEAD request.
EDIT : After an additionnal test
I just did another test : my temp.php file now contains this :
<?php
file_put_contents('/tmp/a.txt', $_SERVER['REQUEST_METHOD'], FILE_APPEND);
var_dump($_SERVER['REQUEST_METHOD']);
die;
Sending an HTTP HEAD request, I get this :
$ telnet localhost 80
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
HEAD /temp/temp.php HTTP/1.1
Host: localhost
HTTP/1.1 200 OK
Date: Thu, 08 Apr 2010 20:21:30 GMT
Server: Apache/2.2.12 (Ubuntu)
X-Powered-By: PHP/5.3.2RC2
Vary: Accept-Encoding
Content-Type: text/html
Connection closed by foreign host.
Here, no output.
BUT, looking at the /tmp/a.txt file :
$ cat /tmp/a.txt
HEAD
So : no output sent by the server doesn't mean that there is nothing done ;-)

Categories