2

I've written a script to force certain sections of the site to be accessed via http or https. We want the user to be redirected to the normal http page in case they land on the https version by accident, and vice versa. So far, so good, but I have 2 questions for you guys.

  1. What is the correct status header to send when switching protocol? I'm currently using this in both cases before redirecting:

    header('HTTP/1.1 301 Moved Permanently');
    
  2. What is the preferred way to detect if we're using https?

    // if ($_SERVER['SERVER_PORT'] == 443) /* EDIT: OK, not this? */
    
    if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) === 'on'))
    

    Something else? Both?

Replies to comments:

  • We're using Apache, but if there's a universal solution that would great.

  • We don't want to use .htaccess because the https required pages are "flagged" as such by the CMS we're using, and that this is a part of. We don't want to "hard-code" the URLs into a file.

Wesley Murch
  • 101,186
  • 37
  • 194
  • 228
  • IIRC, `$_SERVER['HTTPS']` is only present on some servers (namely Apache). – ceejayoz Jan 17 '12 at 22:11
  • 2
    Checking the port is unreliable. It is possible to run SSL on a port other than 443, and it's also possible to connect to port 443 *without* using HTTPS (although the server will usually kill the request with an error). – animuson Jan 17 '12 at 22:12
  • Why i don't smell htaccess here ? – Shankar Narayana Damodaran Jan 17 '12 at 22:20
  • So you need to use CMS input to decide on the desired protocol. That makes it almost impossible to create a 'universal' solution. Unless you can generate configuration files and restart Apache... – The Nail Jan 17 '12 at 22:27
  • @TheNail: We're redirecting to the same page with PHP, just swapping the normal base url with the secure base url. "Universal" is not all that important to me, I'm confident that this only needs to work on Apache. – Wesley Murch Jan 17 '12 at 22:30

1 Answers1

3
  1. The 301 redirect is the proper method. You cannot switch between HTTP and HTTPS mid-stream. The page must be reloaded in the client.
  2. The second method, via $_SERVER['HTTPS'] is the preferred method. Simply ensure that your web server supports it.
Marcus Adams
  • 53,009
  • 9
  • 91
  • 143
  • What do you mean "must be reloaded in the browser"? We're redirecting with `header('Location: ...')`. I just saw here http://stackoverflow.com/questions/452375/detecting-https-requests-in-php that there may be alternate methods with Apache, namely `$_SERVER['HTTP_HTTPS']`. Should I check for both/either? Should I totally ignore the `$_SERVER['SERVER_PORT']` value? As far as I hear, it's not reliable but does that mean it's useless? – Wesley Murch Jan 17 '12 at 22:38
  • Well, if not browser, then at least client. The request must be made over by the client using the proper protocol (HTTPS vs HTTP). The 301 redirect forces this. There's nothing you can send the client to have it switch over on the same request. Yes, some Apache server versions have HTTP_HTTPS instead. Just check the docs for your version. – Marcus Adams Jan 17 '12 at 22:41
  • Yeah it's a new request, all `$_POST` data and whatnot will be lost. Is that what you meant? I guess there's no harm in checking both `HTTP_HTTPS` and `HTTPS` to see if either one is "on", correct? – Wesley Murch Jan 17 '12 at 22:43