0

ManagedFusion Rewriter をリバース プロキシとして使用しています。構成はかなり単純です。

RewriteRule ^/api/(.*) http://www.example.com/api/$1 [P]

これは、どの URL でもほとんど機能します。ただし、URL がたまたま末尾のスラッシュで終わっていない場合、失敗します。

このようなリクエストは完全にうまくいきます:GET api/report/

2013-10-10T11:27:11 [Rewrite] Input: http://localhost:50070/api/report/
2013-10-10T11:27:11 [Rule 0] Input: /api/report/
2013-10-10T11:27:11 [Rule 0] Rule Pattern Matched
2013-10-10T11:27:11 [Rule 0] Output: http://www.example.com/api/report/
2013-10-10T11:27:11 [Rewrite] Proxy: http://www.example.com/api/report/
2013-10-10T11:27:11 **********************************************************************************
2013-10-10T11:27:11 [Proxy] Request: http://www.example.com/api/report/
2013-10-10T11:27:12 [Proxy] System.Net.HttpWebResponse
2013-10-10T11:27:12 [Proxy] Received '200 OK'
2013-10-10T11:27:12 [Proxy] Response: http://localhost:50070/api/report/
2013-10-10T11:27:12 [Proxy] Response is being buffered
2013-10-10T11:27:12 [Proxy] Responding '200 OK'

ただし、このようなリクエストは、プロキシされた URL でリクエストを行うことなく 404 を返します。GET api/report/1

2013-10-10T11:27:13 [Rewrite] Input: http://localhost:50070/api/report/1
2013-10-10T11:27:13 [Rule 0] Input: /api/report/1
2013-10-10T11:27:13 [Rule 0] Rule Pattern Matched
2013-10-10T11:27:13 [Rule 0] Output: http://www.example.com/api/report/1
2013-10-10T11:27:13 [Rewrite] Proxy: http://www.example.com/api/report/1
(the log file finishes right here)

これは私の構成ファイル全体です:

RewriteEngine On
RewriteLog "log.txt"
RewriteLogLevel 9
RewriteRule ^/api/(.*) http://www.example.com/api/$1 [P]

どこが間違っているのでしょうか?

4

1 に答える 1

0

編集:私の回避策は、リライター コードベースのソリューションとして受け入れられているため、これを受け入れられる回答にします。可能なアプローチについてフィードバックを提供してください。


回避策を見つけましたが、これが実際の解決策ではないと思うので、自分の質問に答えますが、答えとしては受け入れません。(後で気が変わらない限り。運命は気まぐれな愛人です。)

ManagedFusion.Rewriter のソース コード (最新のもの、どうやら GitHub から、こちら: https://github.com/managedfusion/managedfusion-rewriter/releases ) をダウンロードし、コード ベースに統合しました。

クラス ManagedFusion.Rewriter.RewriterModule には、次の 2 つのメソッドが含まれています。

private void context_PostResolveRequestCache(object sender, EventArgs e)
{
    var context = new HttpContextWrapper(((HttpApplication)sender).Context);

    // check to see if this is a proxy request
    if (context.Items.Contains(Manager.ProxyHandlerStorageName))
        context.RewritePath("~/RewriterProxy.axd");
}

private void context_PostMapRequestHandler(object sender, EventArgs e)
{
    var context = new HttpContextWrapper(((HttpApplication)sender).Context);

    // check to see if this is a proxy request
    if (context.Items.Contains(Manager.ProxyHandlerStorageName))
    {
        var proxy = context.Items[Manager.ProxyHandlerStorageName] as IHttpProxyHandler;

        context.RewritePath("~" + proxy.ResponseUrl.PathAndQuery);
        context.Handler = proxy;
    }
}

名前が示すように、1 つ目は のハンドラでPostResolveRequestCache、2 つ目は のハンドラですPostMapRequestHandler

両方のサンプル リクエストで、PostResolveRequestCacheハンドラーが呼び出され、正常に動作していました。ただし、失敗したリクエストでPostMapRequestHandlerは、実行されていませんでした。

これは、何らかの理由で、ディレクトリのように見えない特定のリソースを を使用してファイルのように見えるリソースに書き換えることでRewritePath、実際の実際のハンドラーがピックアップされなくなり、その結果、PostMapRequestHandler.

そのため、リライター プロジェクトを .NET 3.5 から 4.5 にアップグレードし、次の行を置き換えました。

if (context.Items.Contains(Manager.ProxyHandlerStorageName))
    context.RewritePath("~/RewriterProxy.axd");

これらによって

if (context.Items.Contains(Manager.ProxyHandlerStorageName)) {
    var proxyHandler = context.Items[Manager.ProxyHandlerStorageName] as IHttpHandler;
    context.RemapHandler(proxyHandler);
}

これにより、すべてのリクエストがハンドラーによって適切に取得され、機能し始めました。


余談ですが、元のルールにはいくつかの間違いがありました。

RewriteRule ^/api/(.*) http://www.example.com/api/$1 [P]

次のようになっているはずです。

RewriteRule ^/api/(.*) http://www.example.com/api/$1 [QSA,P,NC]
  • QSA元のリクエストのクエリ文字列を追加する
  • NC大文字と小文字を区別しない正規表現に一致させる
于 2013-10-11T20:41:52.137 に答える