古き良きクエリ文字列のURL構造を使用したアプリケーションがあります。
?x=1&y=2&z=3&a=4&b=5&c=6
そしてそれをパス構造に変更しました:
/x/1/y/2/z/3/a/4/b/5/c/6
ASP.NET MVCと(当然)ASP.NETルーティングを使用しています。
問題は、パラメーターが動的であり、(理論的には)対応する必要があるパラメーターの量に制限がないことです。
これは、次の列車にぶつかるまで大丈夫です。
HTTPエラー400.0-不正な要求ASP.NETはURLで無効な文字を検出しました。
URLが特定の長さを超えると、IISはこのエラーをスローします。
私たちが見つけたものは次のとおりです。
IISには最大パス長の制限がありますが、上記のエラーはこれではありません。
Dot iis dot netを学ぶリクエストフィルタリングセクション「リクエスト制限に基づくフィルター」の使用方法
IISにとってパスが長すぎる場合、400.0ではなく404.14がスローされます。
また、IIS最大パス(およびクエリ)長さは構成可能です:
<requestLimits
maxAllowedContentLength="30000000"
maxUrl="260"
maxQueryString="25"
/>
いくつかの周りをつついた後:
IISフォーラムスレッド:ASP.NET 2.0の最大URL長さ? http://forums.iis.net/t/1105360.aspx
これはASP.NET(実際には.NETの)問題であることがわかりました。
問題の核心は、私が知る限り、ASP.NETは260文字を超えるパスを処理できないことです。
これがフィル・ザ・ハーク自身によって確認されているというinの中の釘:
スタックオーバーフローASP.NET url MAX_PATH制限質問ID 265251
それでは、質問は何ですか?
問題は、これはどの程度の制限ですか?
私のアプリの場合、これは取引キラーです。ほとんどのアプリでは、おそらく問題ではありません。
開示はどうですか? ASP.NET Routingが言及されている場所では、この制限についてのぞき見を聞いたことはありません。 ASP.NET MVCがASP.NETルーティングを使用するという事実は、この影響をさらに大きくします。
どう思いますか?
Mvc2と.Net Framework 4.0を使用してこの問題を解決するために、web.configで次を使用することになりました
<httpRuntime maxUrlLength="1000" relaxedUrlToFileSystemMapping="true" />
Http.sysサービスは、Urlセグメントごとにデフォルトの最大260文字でコーディングされます。
このコンテキストでの「URLセグメント」は、URLの「/」文字の間のコンテンツです。例えば:
http://www.example.com/segment-one/segment-two/segment-three
許可される最大のUrlセグメント長は、レジストリ設定で変更できます。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters
UrlSegmentMaxLength
Http.sys設定の詳細: http://support.Microsoft.com/kb/820129
最大許容値は32766です。これより大きな値を指定すると、無視されます。 (クレジット:Juan Mendes)
この設定の変更を有効にするには、PCの再起動が必要です。 (クレジット:David Rettenbacher、Juan Mendes)
これを解決するには、次を実行します。
プロジェクトのルートweb.configのsystem.webノードの下:
<system.web>
<httpRuntime maxUrlLength="10999" maxQueryStringLength="2097151" />
...
さらに、system.webServerノードの下にこれを追加するか、長いクエリ文字列のセキュリティエラーが発生しました。
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxUrl="10999" maxQueryString="2097151" />
</requestFiltering>
</security>
...
わかりましたので、これを投稿した理由の一部は、回避策を見つけたためでもありました。
これが将来誰かに役立つことを願っています:D
回避策は非常に単純であり、非常に優れています。
サイトのどの部分が動的パラメーターを使用する必要があるかがわかっているため(動的なパスと長さがあるため)、ASP.NETに到達する前にインターセプトすることで、この長いURLをASP.NETルーティングに送信することを回避できます
IIS7 Url Rewriting(または同等の書き換えモジュール)を入力します。
次のようなルールを設定します。
_ <rewrite>
<rules>
<rule>
<rule name="Remove Category Request Parameters From Url">
<match url="^category/(\d+)/{0,1}(.*)$" />
<action type="Rewrite" url="category/{R:1}" />
</rule>
</rules>
</rewrite>
_
基本的に、私たちがしていることは、ダウンストリームの正しいルートを呼び出すことができるのに十分なパスを維持することです。ハッキングするURLパスの残りの部分。
URLの残りはどこに行きますか?
書き換えルールが実行されると、IIS7 URL書き換えモジュールはリクエストにこのヘッダーを自動的に設定します。
_HTTP_X_ORIGINAL_URL
_
下流では、パスを調べる代わりに、動的パスを解析するアプリの一部で:
_HttpContext.Request.Url.PathAndQuery
_
代わりにそのヘッダーを確認します。
_HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]
_
問題は解決しました...ほとんど!
知っておく必要がある場合、IIS7 Rewrite Moduleヘッダーにアクセスするには、次の2つの方法でアクセスできます。
_HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]
_
または
_HttpContext.Request.Headers["X-ORIGINAL-URL"]
_
また、上記の設定では、すべての相対パス(「〜」で定義されたURL)が壊れていることに気付くでしょう。
これには、ASP.NET MVC HtmlHelper
およびUrlHelper
メソッド(Url.Route("Bla")
など)で定義されたURLが含まれます。
ASP.NET MVCコードへのアクセスが素晴らしい場所です。
System.Web.Mvc.PathHelper.GenerateClientUrlInternal()
メソッドでは、同じURL Rewriteモジュールヘッダーが存在するかどうかを確認するチェックが行われます(上記を参照)。
_// we only want to manipulate the path if URL rewriting is active, else we risk breaking the generated URL
NameValueCollection serverVars = httpContext.Request.ServerVariables;
bool urlRewriterIsEnabled = (serverVars != null && serverVars[_urlRewriterServerVar] != null);
if (!urlRewriterIsEnabled) {
return contentPath;
}
_
存在する場合は、元のURLを保持するためにいくつかの作業が行われます。
私たちの場合、「通常の」方法でURL書き換えを使用していないため、このプロセスを省略したいと考えています。
元のURLのコンテキストで相対パスを考慮する必要がないため、URLの書き換えが行われていないように見せたいと考えています。
私が考えることができる最も簡単なハックは、そのサーバー変数を完全に削除することでした。したがって、ASP.NET MVCはそれを見つけられませんでした。
_protected void Application_BeginRequest()
{
string iis7UrlRewriteServerVariable = "HTTP_X_ORIGINAL_URL";
string headerValue = Request.ServerVariables[iis7UrlRewriteServerVariable];
if (String.IsNullOrEmpty(headerValue) == false)
{
Request.ServerVariables.Remove(iis7UrlRewriteServerVariable);
Context.Items.Add(iis7UrlRewriteServerVariable, headerValue);
}
}
_
(上記の方法では、_Request.ServerVariables
_からヘッダーを削除していますが、_Context.Items
_に隠しておくことに注意してください。この理由は、後でヘッダー値にアクセスする必要があるためです。リクエストパイプ内)
お役に立てれば!
GETを使いにくいと思っています。リクエストメソッドをPOSTに変更して、これらのクエリ文字列パラメーターをリクエスト本文に入れてみてください。
長いURLはSEOにも役立ちませんか?
ハードコードされた最大URL長は 。NET 4.0で修正済み になっているようです。特に、現在web.config
セクション:
<httpRuntime maxRequestPathLength="260" maxQueryStringLength="2048" />
これにより、許可されるURLの範囲を拡大できます。
ASP.NET Web API 4を使用して同様の最大URL長の問題が発生していましたが、わずかに異なるエラーが生成されました:
私のための修正は、上記のWeb.configを以下のタグの両方で更新することで説明されました。
<system.web>
<httpRuntime maxUrlLength="10999" maxQueryStringLength="2097151" />
そして
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxUrl="10999" maxQueryString="2097151" />
</requestFiltering>
</security>