PHP header location absolute URL - php

I came across an issue where an absolute path set in header location wouldn't work but pointing to the file itself did. This only affected a few customers. One of them was nice enough to try connecting through a VPN which made the header location work.
Didn't work:
header('Location: http://www.example.com' . $_SERVER['PHP_SELF']);
Works:
header('Location: ' . $_SERVER['PHP_SELF']);
Can anyone shine some light on this?
Thanks

Your affected customers are not able to resolve the http://www.example.com (or whatever it actually is) URL for some reason. You can verify this by having them just try and visit the http://www.example.com by manually typing it in the browser location bar. That should fail too.
This can happen you have a site that is available under a number of domains, or directly by the IP address. Even www / non-www versions can make this happen. They hit the site at one domain or IP address that works for them, and then you try and redirect them to a URL they can not resolve. This explains why redirecting to just the path works, but an absolute URL doesn't.
If they can reach http://www.example.com in the browser, but not by redirect, ask them to blow out the browser cache.

Also always exit the script afterwards because otherwise in my experience in certain circumstances code that comes after the redirect might still be executed. So a good example would look like this:
header("location:http://www.example.com/path/to/myfile.php");
exit;
Often you would use a server variable for this case:
$url = $_SERVER["HTTP_HOST"]."/path/to/myfile.php";
header("location:".$url);
exit;
Cheers!
Link answer: https://tousu.in/qa/?qa=1091514/

Related

PHP Header Location: ../location vs $_SERVER[DOCUMENT_ROOT]/location

So, I made a simple PHP login, but when I tried to redirect like this:
$path = $_SERVER["DOCUMENT_ROOT"];
header("Location: $path/admin/index.php");
it seemed like it did nothing, but after I refreshed the page I was logged in.
After I changed my code to this:
header("Location: ../admin/index.php");
it works.
Could someone please explain this to me?
Ps. sorry for my bad english
The header is sent to the browser, so it is not an internal server maneuver. And with it not being an internal redirect, you don't deal with internal paths. When you use DOCUMENT_ROOT you will get the internal server path to the directory where your files are located.
If you want to reference the root of the site as a URL, just use /.
header("Location: /admin/index.php");
header("Location: /"); # go to homepage, for example
Your .. worked because you probably were on a subdirectory, and .. was translated to the parent directory which is where admin is.
$_SERVER["DOCUMENT_ROOT"];
returns path like /var/www/html/yourfolder/, but you have to redirect to website.com/yourfolder/ or localhost/yourfolder/.
hence that won't work.
Have you tried printing the value of $path?
the value of $path is relative to the actual file location
e.g. $path = '/c/inetpub/sites/example/main/'
You probably wanted something like '/c/inetpub/sites/example/' or '/c/inetpub/sites/example/main/..'

Automatically get URL of a site displaying my image?

I've been trying to get the URL (including GET parameters) of a site that is displaying my image. This is because I want to extract one parameter of the URL.
A friend told me that she knew someone that could achieve this, but I don't know if he was doing it with an image. Also I don't think I can do it with a link because when going to external sites it will appear a warning page saying that you're being redirected outside, so if I put a link to my page and someone clicks, I will get the referrer URL of redirection warning page. I can't assure if my friend was telling the truth about this, but it's very likely that it was true.
All I could get with the image was the IP and other things of the HTTP header, but the referrer part is empty and I thought that the referrer contained the full URL I'm talking about.
This is what I have tried.
First the img tag in the other site in BBCode:
[img]http://______.com/get_image.php?i=myimage[/img]
And in my site this script in PHP, although any language that does the work would be good for me:
<?php
// Get name of image to be displayed (non-sanitized here for simplicity)
$filename = $_GET["i"];
// Here I want to get the site where image is being viewed
if (!empty($_SERVER['HTTP_REFERER'])) {
$visitor_url = $_SERVER['HTTP_REFERER'];
} else {
$visitor_url = "none";
}
// And write the referrer to a file just to test if it works
$fp = fopen('referer.txt', 'w');
fwrite($fp, $visitor_url);
fclose($fp);
// Eventually display the image
header('Content-Type: image/png');
readfile($filename . '.png');
?>
So my questions are:
Is it possible to get full URL of a site that is displaying my image?
If not, is there any other method to get the full URL?
Thank you in advance.
Note: I don't have any permision in the other site where I'm posting the image, I'm just an user there. Please tell me if I'm missing something or I have to ask this in another way, I'm new to StackOverflow.
Try REMOTE_HOST instead of HTTP_REFERER:
// Here I want to get the site where image is being viewed
if (!empty($_SERVER['REMOTE_HOST'])) {
$visitor_url = $_SERVER['REMOTE_HOST'];
} else {
$visitor_url = "none";
}
The web server where you are serving the image will need to be configured properly. If using Apache, this is with HostNameLookups On.
See http://php.net/manual/en/reserved.variables.server.php
Normally browsers are sending full referer with all URL components including query parameters - $_GET params. If they don't then there is no other way to achieve that URL while passing throught an image content.
Sometimes sending referer may be blocked, for eg. in some batch URL processing using some crawler like program/script or on some proxies.
In PHP receiving referer is done by $_SERVER['HTTP_REFERER'] because it's normally just http header from request and it's the only $_SERVER array key with referer info.
You added the .htaccess tag so I think you're using the Apache web server. If you'd like to prevent the issue entirely, you can disable hotlinking entirely by going one layer lower. Instead of managing in PHP, you can configure the web server to not serve content to domains other than the one you are hosting.
Check out the guide for more details.
I fixed this problem by switching my site (where image is hosted) to HTTPS. The code in my question was doing its job correctly.
It looks that HTTP_REFERER was blank because of it coming from an HTTPS site and my site being HTTP it would always send it blank. I was aware that it could be a problem, but didn't make much sense for me because HTTP_REFERER was also blank when coming from another HTTP site (which I think it's not normal) so I thought the error was in another place.
Usually HTTP_REFERER is sent when it comes from and goes to:
from HTTP to HTTP
from HTTPS to HTTPS
from HTTP to HTTPS
But it's not sent when it comes from and goes to:
from HTTPS to HTTP
And in my case, I don't know why, it wasn't being sent from HTTP to HTTP which was confusing me.

Address Bar not changing - PHP

I am using header('Location:') to redirect the user to another webpage. But, instead of overwriting the previous address on the address bar, the new one gets appended to the one already present. For example:
The address bar currently holds:
localhost/v2/admin
and there is header('Location:'.DIRADMIN.'login.php');
where DIRADMIN is a constant defined as
define(DIRADMIN,'localhost/v2/admin/');
Then, after the redirect, the new address bar would be
localhost/v2/admin/localhost/v2/admin/login.php
I thought it was because of the server, I am using. I was using Uniform Server Zero. But then I installed WAMP and the problem continues.
I am still a noob, I have no idea what is causing this and if the problem is because of mod_rewrite, then on both servers the module was active. I already checked some of the problems like
redirect-PHP header(Location:..)
among others. I even did a google search for this but to no end.
How can I solve this problem?
header_remove();
will not work as the first address was typed in manually and not set by header();
Without the http prefix, browser is trying to find the path relative to your current one
Add "http://" as so
header('Location: '.DIRADMIN.'login.php');
If you want URL to be relative to your domain root path, you can just add '/'
header('Location: /'.DIRADMIN.'login.php');
You should always try to use a relative path - That way, if you change your domain, your code still works.
Define
define('DIRADMIN','localhost/v2/admin/);
As
define('DIRADMIN','http://localhost/v2/admin/');

301 Permanent Redirect

a website has used a "301 permanent redirect" to my site is there a way i can set code that detects this and displays a page when my website is accessed through this?
Does anyone have any idea about this?
You can get only a referer. I think you will not be able to get the http status code on server which the client gets during last request.
So my answer is NO, you cannot get the 301 status code on your server.
But you can do a little of needed magic with referer variable.
e.g. in PHP you can read this:
$_SERVER['HTTP_REFERER'];
Not much you can do. If you were doing the 301, you could set the referrer to the querystring. But since you're not, you can only grab what the request has given you.
You can try using PHP's $_SERVER['HTTP_REFERER'] to track the source URL from where your visitor comes from. I think it's a bit dodgy though and might not yield the same result in all browsers. Even PHP's documentation says 'it cannot really be trusted'.
Why do you have to use .htaccess for the redirect? You could do something like this:
Site A's index.php:
header("Location: http://siteb.com/?ref=".urlencode('http://sitea.com');
Site B's index.php:
if(isset($_GET['ref']))
{
if($_GET['ref']=='http://sitea.com')
{
// Do something
}
}
Edit:
If you can't edit Site A's code or server settings, try using:
if($_SERVER['HTTP_REFERER']=='http://sitea.com')
{
// Do something
}

Weird header("Location:"); error

I've done tons of redirects using PHP's header function. This one has stumped me.
On my dashboard controller, I check whether or not the $_SESSION['loggedin'] is set. If it's not set, I want to send the user back to the main page. However, I keep getting the "too many redirects" error, even though I only have it set once. Can anyone help me out? Thanks for the help in advance!
Here's my code -
function index() {
if(!isset($_SESSION['loggedin'])) {
header("Location: ./");
} else {
die("The user is logged in.");
}
}
./ means "here", so yes, you're redirecting in a circle. You probably mean /, the root.
The Location header field should really contain a complete, absolute URL though. So you should redirect to http://example.com/. Relative URLs just happen to be (incorrectly) accepted by some browsers.
This is because you just refresh the page. It means the user isn't redirected to different URL, he stays where he were.
You're using wrong path for Location header. ./ is equal to . which is a relative path and means current path. Certainly, you want to use / which is absolute path, ie. it's related to domain's root.
I would use absolute paths it will reduce possible errors.
You might need to use global to access the session variables in your case.

Categories