1
votes

I have some PHP pages that I need to force SSL for. I don't want to do it with mod_rewrite or anything like that, I want to keep all the logic in PHP. Right now I have code that looks like this:

if($_SERVER["HTTPS"] != "on") {
    header("HTTP/1.1 301 Moved Permanently");
    header("Location: https://" . $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"]);
    exit();
}

This does not work however because the server name is generic as I am hosting multiple sites with different domain names. So the SERVER_NAME is "www". The above code will redirect to https://www/index.php which is not valid.

I have tried print_r($_SERVER) to see the variables available to me but none of them give me the full URI request (http://example.com/index.php), and the next closest option I can see instead of SERVER_NAME is SERVER_ADDR which will also not help me, because going to https://127.0.0.1/index.php will go to the default apache site and not to the definition for "example.com" (not to mention that my SSL cert would no longer be valid).

Any suggestions?

5

5 Answers

1
votes

If you can't get the host name from any $_SERVER variable, and you don't want to explicitly set it in a config or anything, the only other option I can think of (besides doing it using mod_rewrite, which you stated you don't want to do for whatever reason) is to serve the user a blank page that says, "Please wait while we redirect you to the secure site..." and then handle the redirect using JavaScript to parse the current URL and redirect to the HTTPS version.

1
votes

In the end I had the guy who manages the Apache proxy server to add ProxyPreserveHost On to apache2.conf and this enabled forwarding of HTTP_HOST (and SERVER_NAME) properly to the backend Apache server.

Thank you everyone for your suggestions, I'm sorry the problem ended up being something stupid that wasn't even in the scope of my question. If the Apache server I was working on did not have a proxy in front of it, most of your suggestions would have proven completely accurate.

0
votes

I suspect you want to use the $_SERVER['HTTP_HOST'] setting in place of SERVER_NAME.

header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);

0
votes

If your site URL isn't in $_SERVER I'd guess that you'd have to register it somewhere as a global variable. Each site would then have to register it's own $SITE_URL variable or some such so that you could fill it in with that.

0
votes

In my humble opinion you should avoid doing theses absolute url stuff in your application. The right place to do it si behind your application, for several reasons:

  • your application could be used in the same time, via the same apache
    server, with different names
  • your application could be used behind some proxy, rewriting the base url. (But you can try to detect it)

See for a more detailled explanation this link http://www.makina-corpus.org/blog/relativeabsolute-url-and-proxies

So absolute url is bad, should avoid... I would build instead a nice url managment, where the rules would be simple (all /admin or /conn url needs to be on SSL) and let the proxys/web servers/load balancers handle it nicely. But if you really want to make this redirection in your application the used ways are:

  • using a configuration file where the https absolute url and the http abolute url is defined and unique (fine if your site name is unique and your application not done for large usage)
  • detect absolute url from proxy string in HTTP_X_FORWARDED_HOST and/or
    HTTP_HOST (better)

But most admins will say that absolutes url are bad :-)