しばやん雑記

ASP.NET とメイドさんが大好きなフリーランスのプログラマーのブログ

URL Rewrite の Outbound Rule と gzip 圧縮は共存できないという都市伝説

デフォルトのまま Outbound Rule と gzip 圧縮を有効にしようとしてエラーになったことがある人は多そうです。もはや都市伝説的な感じすらしますが、適切に設定を行えば共存は可能です。

当時は IIS 開発チームだった Ruslan 氏が IIS Forums 回答しています。

URL Rewrite Outbound Rules w/ Compression : The Official Microsoft IIS Forums

回答を要約すると以下のようになるかと。IIS のパイプラインを考えると理解できますね。

  • Outbound Rule と IIS の Static Compression は共存できない
    • Static Compression はキャッシュを保存したりするので当然という感じはある
  • LogRewrittenUrlEnabled レジストリキーを追加する
  • dynamicCompressionBeforeCache を false に設定する
  • DynamicCompressionModule の順番を URL Rewrite より前にする

これで終わりなんですが、実際に動作することを確認しておくことにします。何となく EC2 を使いました。

ちなみにレジストリを弄る必要があるので Azure Web Apps では動作しませんが、前段にいる ARR が勝手に gzip して返すので問題ありません。

デフォルトの状態で試す

Elastic Beanstalk で Windows Server 2016 のインスタンスを作成して、Outbound Rule の追加を行いました。良くありそうな body 閉じタグの直前に何かを追加する処理です。

f:id:shiba-yan:20170905231629p:plain

次に Dynamic Compression の設定を有効にしておきます。

f:id:shiba-yan:20170905231206p:plain

ここまで終わった状態でブラウザでページを表示しようとするとエラーとなります。以下のページは詳細な情報を表示するようにしてるので、細かくエラーが出ています。

f:id:shiba-yan:20170905231136p:plain

このページを見たことがある人は割と多いでしょう。自分も当然見たことがあります。これから先は、このエラーページを消すために追加設定を行います。

LogRewrittenUrlEnabled を追加

設定の肝となる LogRewrittenUrlEnabled をオフにします。32bit と 64bit でそれぞれに設定をしておいても良いかも知れませんが、今時は 64bit しか使ってないとは思います。

reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp\Rewrite /v LogRewrittenUrlEnabled /t REG_DWORD /d 0

reg add HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432node\Microsoft\Inetstp\Rewrite /v LogRewrittenUrlEnabled /t REG_DWORD /d 0

レジストリに書き込んだ後は iisreset を呼び出してワーカープロセスを再起動します。

iisreset

UserData とかで設定を行った場合は特に必要はないはずです。多分。

dynamicCompressionBeforeCache を false に

IIS Manager からは設定する項目が見つからなかったので、Web.config を直接弄ります。以下をコピペで問題ないでしょう、これ以上 urlCompression で弄っていることはほぼ無いと思います。

<urlCompression doStaticCompression="false" doDynamicCompression="true" dynamicCompressionBeforeCache="false" />

doDynamicCompression だけが有効になっているように設定します。

DynamicCompressionModule の順番を確認

最後に IIS Manager を立ち上げて IIS Module の順番を確認します。Elastic Beanstalk の Windows Server 2016 は予め適切な順番になっているようでした。

f:id:shiba-yan:20170905231543p:plain

なので特に何もすることはありません。Windows Server 2016 以外の場合は確認してません。

同時に有効になっていることを確認

普通にブラウザでアクセスすると、問題なくページが表示されます。ちゃんとエラーは消えましたし、レスポンスヘッダーを見ると gzip が有効になっていることも分かります。

f:id:shiba-yan:20170905231821p:plain

ページのソースを表示すると、ちゃんと body 閉じタグの前に Outbound Rule で設定した内容が追加されていることも確認できました。

f:id:shiba-yan:20170905231843p:plain

たったこれだけです。最近はリバースプロキシとかがいい感じに圧縮してくれますが、それ以外のケースで使うこともあるのかなと思いました。

実は URL Rewrite をインストールされた時に一緒に入る rewrite_readme.htm に、圧縮するための方法が書いてあるのですが、このファイルの存在に気が付く人はあまりいない気がします。

f:id:shiba-yan:20170905235637p:plain

レジストリで設定可能な項目についても書いてあるので、興味がある人は読んでおいても良さそうです。