14

We can force SSL in apache servers with following config:

RewriteEngine On 
RewriteCond %{HTTPS} off 
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Here, we tell the apache server that return a 301 Moved Permanently response to the client. But there is another status 101 Switching Protocols and I think this status code is more suitable since we are switching from plain HTTP to HTTPS.

Am I right? Anything wrong? Which status code should I use?

Ar Rakin
  • 243
  • 2
  • 7

3 Answers3

24

The correct status code to use here is without a doubt 301 Moved Permanently.

101 Switching Protocols is an internal status code that a server generally uses to automatically negotiate certain types of connections. It's not used when changing the URL from http to https. If you're curious about how it works, you can read about the 101 status code and the protocol upgrade mechanism on MDN, but you'll never need to know about it as a webmaster.

As a general rule, you should never directly use 100 series status codes unless you are actually developing web server software. The 300 and 400 series codes (especially 301, 302, and 404) are the ones you'll want to pay attention to when running a simple website.

Maximillian Laumeister
  • 16,461
  • 3
  • 32
  • 63
12

No - 101 Switching Protocols is not appropriate for redirecting to HTTPS, as this status indicates that the current connection should be upgraded to the new protocol, whereas a redirect instructs the client (browser) to retry the request at a new location.

The confusion may arise because, from your point of view, the two places are the same location, with the only difference being the protocol/port number used to access it. However, from the perspective of the URI scheme, these are two separately-addressable locations (as the protocol is part of the address), hence a redirect is the correct method to use.

With an upgrade request, the 101 Switching Protocols header is output and then the server immediately switches to using the new protocol on the same connection.

HappyDog
  • 221
  • 1
  • 7
3

RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

It seems to me that the simpler regex .* should work just as well.

Here, we tell the apache server that return a 301 Moved Permanently response to the client. But there is another status 101 Switching Protocols and I think this status code is more suitable since we are switching from plain HTTP to HTTPS.

No, the correct status code is 301, for two reasons:

  1. This is a redirect. Per RFC 7231, section 6, redirects are indicated by the 3xx series of status codes. Section 6.4.2 defines the 301 Moved Permanently status code, which is clearly the appropriate one for HTTP → HTTPS redirects.
  2. Apache does not take kindly to redirects with status codes outside the 3xx series:

However, if a status code is outside the redirect range (300-399) then the substitution string is dropped entirely, and rewriting is stopped as if the L were used.

A redirect instructs the web browser to create a new HTTP request. In this case, that request requires a new connection to a new origin: changing either the scheme or the port changes the origin, and in this case, you change both. This is very different to the 101 Switching Protocols status code, which immediately causes the current connection to switch to some other protocol. This other protocol could be anything (as agreed between the server and client), but will probably have nothing to do with HTTP!

Brian Drake
  • 131
  • 1