-1

I have this huge issue that I have no idea how to fix. I have a script that redirects to a url.

So far I have:

//do some mysql
$geo_included = true; //trying to fix infinite redirect loop.
if($geo_included === true){
    header('Location: '.$url["url"]); //this is causing the issue with redirect loop
}

$url["url"] for example is: www.google.com

But when I go to that PHP file it will redirect to:

www.sitename.com/www.google.com

and say there is an infinite redirect loop. Note: the above header location script is not in a while/for/foreach loop.

Here is my .htaccess for the / directory

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?group=$1 [L]

Any ideas?

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
MysteryDev
  • 610
  • 2
  • 12
  • 31

2 Answers2

7

You need to include the fully qualified domain name with scheme, otherwise it's interpreted as being in the current domain:

header('Location: google.com'); // Redirects to http://cursite.com/www.google.com
header('Location: http://google.com'); // Redirects as expected

If you are unsure if your URL includes a scheme, check the results from parse_url.

$url_scheme = parse_url($url, PHP_URL_SCHEME);
// www.google.com -> NULL
// http://google.com -> string(4) "http"
// ftp://site.com -> string(3) "ftp"
Mr. Llama
  • 20,202
  • 2
  • 62
  • 115
  • All good, but how can the original poster ensure that `http://` is prepended if it doesn’t already exist? Check my answer out to see how I am handling that. – Giacomo1968 Jun 10 '14 at 21:10
  • 1
    @JakeGould - Edited to include `parse_url` to check the URL. – Mr. Llama Jun 10 '14 at 21:20
0

The quick proof-of-concept solution here is to prepend http:// to the URL like this:

$geo_included = true;

if ($geo_included) {
    header('Location: http://' . $url["url"]);
}

I say “proof of concept” because what you should do is ensure the $url["url"] always has a protocol attached to it. Either before it gets into the database, or in this code snippet by doing a check on the $url["url"] value to see of it has http:// or https:// and if it doesn’t, prepend it. And here is a quickly thrown together example of what I mean which should work:

$geo_included = true;

if ($geo_included) {
    $protocol = (!preg_match("~^(?:ht)tps?://~i", $url["url"])) ? 'http://' : null;
    header('Location: ' $protocol . $url["url"]);
}

The line with $protocol = … does the check I explained before. The default is to add http:// if it’s not there.

Also, note I removed === true since the if ($geo_included) { is basically the same thing.

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103