1. kiyocy24

    Posted

    kiyocy24
Changes in title
+【mod_rewrite】httpsとhttpd.confと.htaccessでハマった話
Changes in tags
Changes in body
Source | HTML | Preview

今まで無料のドメインを使っていたのですが、あることを契機に有料ドメインに変更するにあたって、ハマった話とその解決方法についてお話します。

mod_rewriteとは
httpd.confと.htaccessの罠
httpsの罠

mod_rewriteとは

mod_rewriteとは、Apache上で利用できる機能の1つです。
一言で言えば、リダイレクト機能になります。

htmlやJavaScriptでもリダイレクト機能は実装することができますが、一般的かつGoogleにも推奨されている方法がWebサーバによるリダイレクトです。mod_rewriteはサーバによるリダイレクト手法のうちの1つになります。
【unitopi】Webページをリダイレクトする3つの方法とベストプラクティス

よくあるのは強制https化だったり、URLの正規化(www有無など)だったりします。
かくいう私も強制https化でmod_rewriteを使っています。

しかし、同じ要領でドメインの変更も大したことないだろうと思っていたら、痛い目を見ました。

httpd.confと.htaccessの罠

基本的にmod_writeを記述するのはhttpd.confまたは.htaccessのどちらかになります。
人によってはmod_write.confを作成したりする例もあるみたいです。

httpd.conf.htaccessの違いはRewriteが行われる順番と処理速度です。
簡単にいうと、httpd.confでRewriteされたあと、.htaccessでRewriteが行われます。

また、それぞれのRewiteの処理速度を比較すると、httpd.conf > .htaccess
となり、httpd.confの方が早いです。
理由は.htaccessが再度リクエストをサーバに投げるからなのですが、詳しくはこちらを見てください。
【ブログ】「.htaccess」と「httpd.conf」での設定による違い

私の場合、この関係を理解していなかった上に、.htaccessファイルにmod_writeを記述していたのを忘れていて、httpd.confを見ながら小一時間唸っていました。

やっぱり、備忘録は必要なんだなぁ、と実感

httpsの罠

タイトルどおり、https周りでつまづきました。

失敗例

まず、失敗したhttpd.confを載せます。

httpd.conf
<IfModule mod_rewrite.c>
RewriteEngine On

# (1) sample.tk -> sample.com:443
RewriteCond %{HTTP_HOST} ^sample.tk
RewriteRule ^(.*)$ https://sample.com%{REQUEST_URI} [R=301,L]

# (2) *:80 -> *:443
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

</IfModule>

ドメインをtkからcomに変えるためのRewriteRuleと、
強制的にhttpsにアクセスさせるための`RewriteRuleの2つがあります。

(1)で、ホスト名が旧ドメインだった場合は新ドメインのhttpsにアクセスします。
(2)で、ドメインが新旧に関わらず、httpでのリクエストはすべてhttpsにリダイレクトします。

上手くいきそうに見えます。
しかし、実際にアクセスしてみると…
http://sample.tk -> https://sample.com (成功)
https://sample.tk -> https://sample.tk (失敗)
http://sample.com -> https://sample.com (成功)

なぜか、httpsのときだけ、リダイレクトされない??

原因と対処法

原因はずばり、httpd.confにあります。
httpd.confの上の方、40行目あたりに気になる記述があります。

httpd.conf
...
Listen 80
...

はい、もうお分かりですね。
httpd.confは基本的に80ポート、つまりhttp通信にしか適用されません(そりゃそうだ)。

つまり、httpd.confにいくらhttpsに関する記述をしたところで意味がないわけです。
というわけで、別ファイルにRewrite内容を書きましょう。

rewrite.conf
<VirtualHost *:443>
  ServerName tkl-craft.tk:443
  RewriteEngine on
  RewriteCond %{HTTP_HOST} ^tkl-craft.tk
  RewriteRule ^(.*)$ https://tkl-craft.com%{REQUEST_URI} [R=301,L]
</VirtualHost>

VirtualHostについては省略します。
内容は失敗例のhttpd.confで書いたものと全く同じです。
ホスト名が旧ドメインだったら新ドメインにRewriteするというものです。

これでようやく、httpsに対してもRewriteを行うことができました。

参考リンク