2011-12-19 42 views
3

希望有人能夠解釋我們遇到的這個問題,因爲我在這裏不知所措。Global.asax中的ToLower()Application_BeginRequest尖峯CPU和轟炸應用程序

首先,一點背景:

我重寫URL重寫我們的應用程序和幾個星期前付諸實施。我在global.asax文件中使用Application_BeginRequest()這樣做,除了我做的一個小小的監督之外,我們的應用程序一切正常。當我重寫URL時,我只是檢查用戶請求的路徑中是否存在某些關鍵字,然後相應地重寫路徑。非常直白的東西,而不是在這裏發明輪子。幹碼,真的。但是,我檢查的文本全部是小寫,而路徑可能會帶有不同的情況。

例如:

string sPath = Request.Url.ToString(); 
sPath = sPath.Replace(Request.Url.Scheme + "://", "") 
      .Replace(Request.Url.Host, ""); 
if (sPath.TrimStart('/').TrimEnd('/').Split('/')[0].Contains("reports") && sPath.TrimStart('/').TrimEnd('/').Split('/').Length > 2) { 
      string[] aVariables = sPath.TrimStart('/').TrimEnd('/').Split('/'); 
      Context.RewritePath("/app/reports/report-logon.aspx?iLanguageID=" + aVariables[1] + "&sEventCode=" + aVariables[2]); 
} 

...如果有人進入頁面爲/報告/,該規則將不匹配,他們將收到一個404錯誤結果。

雖然簡單,但我想。只需要強制所請求的路徑字符串爲小寫字母,以便我嘗試與其匹配的任何內容都將查看所需路徑的小寫版本,並在以上情況下成功匹配。所以我調整了代碼閱讀:

string sPath = Request.Url.ToString(); 
    sPath = sPath.Replace(Request.Url.Scheme + "://", "") 
       .Replace(Request.Url.Host, ""); 
    sPath = sPath.ToLower(); // <--- New line 
    if (sPath.TrimStart('/').TrimEnd('/').Split('/')[0].Contains("reports") && sPath.TrimStart('/').TrimEnd('/').Split('/').Length > 2) { 
       string[] aVariables = sPath.TrimStart('/').TrimEnd('/').Split('/'); 
       Context.RewritePath("/app/reports/report-logon.aspx?iLanguageID=" + aVariables[1] + "&sEventCode=" + aVariables[2]); 
    } 

用此修復程序,當我要求對URL重寫匹配任何URL,但是,在服務器峯值爲100%,我的整個應用程序崩潰的CPU。我拿出.ToLower(),殺了應用程序池,應用程序再次完美。

我在這裏錯過了什麼!?!?是什麼賦予了?爲什麼這樣一個簡單的方法會導致我的應用程序爆炸? .ToLower()在我們的應用程序的其他地方工作,儘管我沒有廣泛使用,但我在應用程序的其他地方非常成功地使用它。

+2

它不涉及您的問題,但你應該保存' sPath.TrimStart('/')。TrimEnd('/')。Split('/')'在一個變量中,而不是三次計算。只是說。 – 2011-12-19 22:12:02

+0

@KooKiz點好評。謝謝,我會做出改變。 – 2011-12-19 22:19:21

+0

對於這個問題,如果有人輸入錯誤的URI,那麼404是合適的。如果他們輸入了錯誤的URI,但你可以根據自己的能力制定出他們的意思,301是最好的方法。這樣你就有成千上萬的URI意味着同樣的事情。至於這個原因,你是否確定你在原文中沒有錯別字。在過去,我曾經做過這樣的事情,當我打算處理一個領域時,導致我打電話給屬性。 – 2011-12-19 23:12:32

回答

4

不確定ToLower會導致這種情況的具體原因(我唯一能想到的就是它修改了request.url,它將asp.net變成狂熱),但有一個簡單的解決方法:使用ignorecase比較而不是把所有的東西都轉換成適合的

變化:

sPath.TrimStart('/').TrimEnd('/').Split('/')[0].Contains("reports") 

到:

sPath.TrimStart('/').TrimEnd('/').Split('/')[0].IndexOf("reports", StringComparison.InvariantCultureIgnoreCase) != -1 

並刪除ToLower將邏輯。

+0

哇,我們得到了同樣的頭;) – 2011-12-19 22:17:23

+0

@competent_tech - 我想修改request.url和它將.net引入狂熱的可能性相同。當它發生時,幾乎看起來像一個無限循環,所以就好像我迫使Requested Url小寫並重新請求它,然後強制小寫,重新請求等。但由於我將Request.Url的值分配給一個字符串變量,我不認爲我會直接修改Request.Url。無論如何,我一定會接受你的建議。看起來它應該工作。今晚我們會討論它,看看我的服務器是否會死掉。謝謝! – 2011-12-19 22:25:34

1

雖然我不能說爲什麼.toLower()帶來的是您的服務器關閉

你爲什麼不使用的indexOf嘗試

if (sPath.TrimStart('/').TrimEnd('/').Split('/')[0].IndexOf("reports",StringComparison.InvariantCultureIgnoreCase)>=0 && sPath.TrimStart('/').TrimEnd('/').Split('/').Length > 2) 
     { 
     string[] aVariables = sPath.TrimStart('/').TrimEnd('/').Split('/'); 
     Context.RewritePath("/app/reports/report-logon.aspx?iLanguageID=" + aVariables[1] + "&sEventCode=" + aVariables[2]); 
     }