しばやん雑記

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

IIS Express TestKit で Outbound Rules のテストを書けるようにした話

前回作った IIS Express TestKit が Inbound の一部にしか対応出来ていなかったので、少し気合を入れて利用範囲を広げる対応を行いました。はいふりが始まる前だったので少し急ぎました。

タイトルにも書いたように Outbound Rules に対するテストが書けるようになりました。Outbound Rules については IIS 公式サイトにドキュメントがあるので紹介しておきます。

Creating Outbound Rules for URL Rewrite Module : The Official Microsoft IIS Site
Using Outbound Rules to add Web Analytics tracking code : The Official Microsoft IIS Site

ざっくりと説明するとレスポンスをルールベースで書き換える機能です。

面白いことに HTML のタグ単位での書き換えが出来るので、アプリケーションを弄ることなくリソースの向き先を CDN に変えてしまうといったことが簡単にできます。

簡単な Outbound Rule を使ったサンプルを紹介します。まずは HTML です。

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <a class="test" href="/hoge" rel="me">hoge</a>
</body>
</html>

テンプレート的な HTML に a タグを 1 つだけ足してあります。

Outbound Rules では、この a タグに対しての書き換えルールを追加します。今回は /hoge から始まるリンクを /translated 以下に書き換えるルールを作成しておきました。

<outboundRules>
  <rule name="Rewrite" preCondition="IsHTML">
    <match filterByTags="A" pattern="^/(hoge.*)" />
    <action type="Rewrite" value="/translated/{R:1}" />
  </rule>
  <preConditions>
    <preCondition name="IsHTML">
      <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
    </preCondition>
  </preConditions>
</outboundRules>

事前条件として Content-Type が text/html の時だけルールが有効になるようにしています。

使いこなせるととても便利な機能なんですが、この Outbound Rules は書く難易度が Inbound に比べて格段に高いので、簡単にテストを行える環境が欲しかったです。

まだ NuGet には上げてないですが、GitHub に公開している IIS Express TestKit を使うと、Outbound Rules のテストを以下のようなコードで書くことが出来ます。

[Fact]
public void OutboundRuleのテスト()
{
    Iis.Request("/outbound.html", @".\outbound.html")
       .IsHeaderValue("Content-Type", "text/html")
       .HtmlAttribute("a", "href", "/translated/hoge")
       .IsStatusCode(HttpStatusCode.OK);
}

レスポンスヘッダーの値と a タグの href 属性の値をチェックするようなコードになっています。

Request メソッドの引数で、このリクエストで返すコンテンツを指定できるようにしたので、outbound.html というリクエストを投げると、カレントディレクトリの outbound.html を返します。

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

ちなみにプロジェクト構成は上のような感じです。もうちょっとリクエスト周りは洗練させたい感じがありますが、今後改善して行けたらいいと思ってます。

このテストコードを実行すると成功するので、Outbound Rules の書き換えが正しく動作していることが、簡単に確認できました。Contains メソッドを使うと含まれているか、大雑把に確認も出来ます。

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

全体的にインターフェースを改善していきたい感じがあるので、そろそろ機能が十分になったと思ったタイミングで見直していく予定です。

追加機能としては、リクエストのパラメータ設定や、Inbound Rules の IsFile / IsDirectory への対応、そして既存の仮想アプリケーションに対して実行できるようにしたいと思います。