HTTPからHTTPSにクエリパラメータも含めて転送

超がつくほど今更ですが、HTTPS対応した後で、従来のHTTPへのアクセスをHTTPSに転送したい場合は多いと思います。

そして、もしCGIなどの理由でクエリパラメータを使っていた場合、クエリパラメータも含めて転送したいのではないでしょうか。

http://example.jp/myapp/app.cgi?s=12
↓
https://example.jp/myapp/app.cgi?s=12

意外なことに、こういった「クエリパラメータもそのまま転送」が出てきません。なので、調べました。

結論。apacheのサイトを丸ごとHTTPS化するなら、次のような .htaccess ファイルにします。

<IfModule mod_rewrite.c>
   RewriteEngine on
   RewriteCond %{HTTPS} off
   RewriteCond %{QUERY_STRING} .+
   RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}?%{QUERY_STRING}
   RewriteCond %{HTTPS} off
   RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}
</IfModule>

HTTPからHTTPSへの転送用 .htaccess とだいたい同じですが、3~5行目は普通の例にはない部分です。

RewriteRuleによる置換は、そのままだとクエリパラメータを含んでくれないため、まずクエリパラメータがある場合の転送を書いて、その後にクエリパラメータなしの転送を書いています。この順序は逆にはできません(クエリパラメータがあっても、なしパターンで転送されるので)。

なお、転送してもハッシュ(フラグメント)は維持されます。

だめだったパターン

  • Redirect(Redirect / https://%{HTTP_HOST}/)だと、同じサイトをHTTPS対応している場合、リダイレクトが無限ループします(実際はブラウザが途中でエラーを出します)。
  • RewriteRuleで「http://」を「https://」に書き換えようとしても、RewriteRuleの置換対象にプロトコル部分は入らないので書き換えられません。

httpd.apache.org