サーバー上の301リダイレクトチェーンの量を削減しようとしています。サブドメインをwww以外のリダイレクト(サブドメインがdev
の場合を除く)にHTTPからHTTPSへのリダイレクト( %{HTTP:X-Forwarded-Proto}
)インスタンスがロードバランサーの背後にあるため。
これが.htaccess
にこれまでにあるものです。
# move http to https
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=301]
# Remove leading www
RewriteCond %{HTTP_Host} ^www.example.net [NC]
RewriteRule ^(.*)$ https://example.net/$1 [R=301,L]
現在の実装には3つの問題があります。
http://www.example.net
へのリクエストには2つのリダイレクトがあります。
このサイトのほとんどのwwwからwww以外へのリダイレクトの例と同様に、ww.
またはwwww.
はリダイレクトされません。そのため、私の分析には、リダイレクトされていない多くの誤って入力されたサブドメインがあります。
私はdev.
サブドメインをリダイレクトから除外したいので、http://dev.example.net
とそのhttps
兄弟です。開発とリリースのステージングにdev.
を使用しているためです。
これを組み合わせるにはどうすればよいですか?
1)_
http://www.example.net
_へのリクエストには2つのリダイレクトがあります。
これは、2つのルールを逆にするだけで解決できます。次に、_www.example.net
_が最初のリダイレクトでHTTPSにリダイレクトされるため、HTTPからHTTPSへのリダイレクトはトリガーする必要がありません。
(ただし、これは [〜#〜] hsts [〜#〜] を実装する意図がないことを前提としています。この場合、2つのリダイレクトとして保持する必要があります。同じホスト名firstが要件です。)
2)このサイトのほとんどのwwwからwww以外へのリダイレクトの例と同様に、_
ww.
_または_wwww.
_はリダイレクトされないため、分析にはリダイレクトされていない多くの誤って入力されたサブドメインがあります。
通常、_ww.
_または_wwww.
_サブドメインへのリクエストは単に解決されないため、通常これは問題になりません。これが機能するには、DNSでwildcardサブドメインを構成し、そのような要求を受け入れるようにサーバーを構成する必要があります。
しかし、これは正規表現(スニペット)を_^www\.
_から_^w{2,4}\.
_に変更することで説明できます。
3)_
dev.
_サブドメインをリダイレクトから除外したいので、開発とリリースのステージングに_http://dev.example.net
_を使用しているため、_dev.
_とそのhttps
兄弟です。
これはHTTPからHTTPSへのルールにのみ適用されるため、ここで追加の条件を適用して、_dev.
_で始まるホスト名を除外できます。
上記の点をまとめて、以下を試してください:
_# Remove leading ww, www or wwww (and redirect to HTTPS)
RewriteCond %{HTTP_Host} ^w{2,4}\.example\.net [NC]
RewriteRule (.*) https://example.net/$1 [R=301,L]
# Move http to https (except dev subdomain)
RewriteCond %{HTTP:Host} !^dev\. [NC]
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP:Host}%{REQUEST_URI} [R=301,L]
_
これがロードバランサーの要件である場合に備えて、_HTTP:Host
_の使用を同じにしました(Host
HTTPリクエストヘッダーにアクセスするため)。それ以外の場合は、ここで_HTTP_Host
_サーバー変数を使用する方が一般的です。
CondPatternの_!
_接頭辞(つまり、_!^dev\.
_)は正規表現を否定するため、Host
は_dev.
_で始まりませんではありません。 (私は_www.dev.
_は事ではないと思いますか?)
_(.*)
_は、デフォルトでは正規表現が貪欲であるため、^(.*)$
と同じです。
テストする前に、ブラウザのキャッシュをクリアする必要があります。キャッシュの問題を回避するために、最初に302(一時)リダイレクトでテストすることをお勧めします。
# Remove leading www, always using https regardless of the current URL scheme
RewriteCond %{HTTP_Host} ^w{2,4}.example.net(?::|$) [NC,NV]
RewriteRule .* https://example.net%{REQUEST_URI} [L,R=301]
# move http to https, except for dev.example.net
RewriteCond %{HTTP:X-Forwarded-Proto} =http [NC,NV]
RewriteCond %{HTTP_Host} !^dev.example.net(?::|$) [NC,NV]
RewriteRule .* https://%{HTTP_Host}%{REQUEST_URI} [L,R=301]
X-Forwarded-Proto
条件にNC
(nocase
)フラグを追加しました。これは、値が大文字と小文字を区別しないように見えるためです(つまり、HTTP = Http = hTTp = http
)。これは自由に削除できます。X-Forwarded-Proto
条件にNV
(novary
)フラグを追加して、Vary
応答ヘッダーから非表示にしました。繰り返しますが、これが当てはまらない場合(特にリバースプロキシがクライアントに送信する前に自動的にフィルタリングする)、または正しいキャッシュ動作に必要な場合(キャッシュはhttp
とhttps
のコンテンツを区別しません)であれば、これを自由に削除できます。 。NV
ヘッダー条件にnovary
(Host
)フラグを追加して、Vary
応答ヘッダーからそれを非表示にしました。キャッシュサーバーが壊れている場合は、これを削除することもできます。RewriteRule
フラグの順序に一貫性を持たせました(L,R=301
とR=301,L
は基本的に同じです)。www.example.net.but.not.actually.yours.com
が認識されないようにしましたが、たとえばwww.example.net:443
。%{REQUEST_URI}
を置換として使用します。ww
およびwwww
も認識します。