昨天處理好了Google網站管理員中的500錯誤,今天處理了一些400處理,比如下面的以制表符(tab)結尾的URL:
http://www.cnblogs.com/me-sa/archive/2008/05/16/1200329.html%09 http://www.cnblogs.com/JimmyZhang/archive/2007/12/20/1006555.html%09 ...
訪問這些URL時,IIS會返回400 bad request的錯誤:
Bad Request - Invalid URL
HTTP Error 400. The request URL is invalid.
這個錯誤頁面是由IIS的底層http.sys直接返回的,既不能自定義錯誤頁面,也不能進行URL重寫。而我們想要的結果是訪問這樣的URL時,能自動跳轉至正確的URL(去掉結尾的制表符)。
於是想借助IIS URL Rewrite Module來實現,但現在請求直接被http.sys在底層攔截了,根本到達不了URL Rewrite Module。還好,可以通過注冊表設置讓http.sys不攔截這樣的URL。
注冊表設置方法如下:
- regedit打開注冊表編輯器,進入HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters
- 添加鍵值:AllowRestrictedChars REG_DWORD 1 (默認為0,會攔截\x00-\x1F與\x7F-\x9F的字符,制表符的ASCII碼是\x09)
- 重啟http.sys與IIS,使注冊表的設置生效:
net stop http
net start http
iisreset
這樣設置之后,URL中包含制表符的請求就能到達IIS URL Rewrite Module,然后用一條URL重寫規則進行重定向跳轉。結果卻發現根本不起作用,沒進行跳轉,依然是400錯誤,只不過現在是由ASP.NET返回的。
HTTP Error 400.0 - Bad Request
ASP.NET detected invalid characters in the URL.
這估計是URL Rewrite Module的一個小bug。
后來采用了一個折衷的解決方法,不進行重定向跳轉,只進行URL重寫,這樣雖然URL不對,但至少頁面可以正常訪問。
於是最終采用了下面的URL重寫規則折衷地解決了問題:
<rule name="endwith_tab" stopProcessing="true"> <match url="^([^.]+\.(?:html|aspx))[\x09]" /> <conditions logicalGrouping="MatchAll" trackAllCaptures="false" /> <action type="Rewrite" url="{R:1}" appendQueryString="false" /> </rule>
【參考資料】
Http.sys registry settings for Windows
Use of special characters like '%' ‘.’ and ‘:’ in an IIS URL