顯示具有 IIS 標籤的文章。 顯示所有文章
顯示具有 IIS 標籤的文章。 顯示所有文章

2018-01-16

C# URL Encoding

被這東西咬第二次了,想想還是釐清楚記下來。

這個議題事實上已經被講很多了,寫得最好得應該是 [1];候選的函式有:HttpUtility.UrlEncode()、Uri.EscapeUriString()、Uri.EscapeDataString(),主要差異在於:
  1. 適用的輸入是 URL 整體,還是個別參數? 上面三個只有 Uri.EscapeUriString() 不會對 ':' 跟 '/' 字元編碼,可以用在 URL 整體,另外兩者都不行。
  2. 會處理的字元跟未編碼字元各有哪些?HttpUtility.UrlEncode() 跟 Uri.EscapeDataString() 除了會對 ':', '/' 編碼外,還會處理 ' ' (space), '?', '+', ' (single quote),對於 '.' (dot) 都不處理。
Uri.EscapeUriString() 雖然可以直接丟整個 URL 進去,但主要問題在於:太多特殊字元都不處理,包括 ' (single quote), '+', '?' 等。至於在 HttpUtility.UrlEncode() 跟 Uri.EscapeDataString() 間選擇時,差異不大,只有大小寫跟空白字元處理方式,兩者都是合法的,可以自由挑選;但也都因為不能處理完整的 URL,所以需要自己另寫一段程式 [1]
  • 分離 query parameter 與原本的 URL;
  • 將 query parameter 的 key 與 value 都使用 Uri.EscapeDataString() 編碼。
注意:範例中的程式碼不處理 path parameter,如需套用至 path parameter 應該也是可行,但當使用 encoded string 發出 request 時,IIS 預設的 request filtering 會擋掉該 request 並拋出 HTTP substatus 404.11 (URL Double Escaped),需要將 allowDoubleEscaping 設定為 true 才能通過。

Encoding vs Double Escaping?

這邊需要釐清兩件事:
  • 何謂 double escaping?
  • 將 URL 中的 query parameters 編碼是否屬於 double escaping?
由於在 RFC 2396 [2] 中,將特殊字元轉換為 '%' 加上 16 進位數字的動作稱為 escaped encoding,因此 HttpUtility 使用了 encode 這個動詞,而 Uri 與 IIS request filtering 使用 escape,實質上是可以互換通用的。

其次,一般只呼叫一次 Uri.EscapeDataString() 的結果字串屬於 single escaping,並不符合 double escaping 的條件,但由於 ' ' (space) → '+' (plus sign) → %25 這個轉換路徑,IIS request filter 誤以為 %25 是源自 ' ' (space),歷經 double escaping 得到,因此拋出 404.11 錯誤。

這邊有一篇文章 [3] 寫得非常仔細,將 request URL 經 Windows Http.sys、IIS Request Filtering、IIS Core、Handlers 等四層處理過程都詳細解說,值得一讀。

see also:
[1] Huan-Lin 學習筆記: URL 編解碼問題
[2] RFC 2396
[3] Use of special characters like '%' ‘.’ and ‘:’ in an IIS URL

2016-07-10

Remote Debug .NET Web Application with Visual Studio

.NET platform 的 remote debug 機制不像 Java 內建於 JVM,.NET CLR 並無內建此機制,需要在受測端安裝 agent (remote tools),控制端只要安裝 Visual Studio 即可。從 client/server 架構來看:

  • Server (受測端):需執行 Remote Debugging Monitor (msvsmon.exe) 與 IIS worker process (w3wp.exe)
  • Client (控制端):執行 Visual Studio
Note:
  • 基本上是 client/server 架構,client 執行 Visual Studio,server 要裝對應版本的 remote tools,預設 port 是 4016;版本不匹配可能會找不到或直接顯示版本錯誤的訊息。
  • 針對 web application 的 remote debug 要 Visual Studio 2005 以後的版本,2012 開始 Community Edition 也支援 remote debug。
  • Attach 的 process 是 IIS worker process (w3wp.exe),因為一台機器上可能同時跑多個 workers,確認 target process 可以參考 [1]
  • Authentication 只支援 Windows 認證,需要在 server side 與 client side 都建立相同的帳號;不然就是不認證 (no authentication; since Visual Studio 2012)。當使用 Windows 認證時,client side 需以 debugging 用的帳號執行 Visual Studio。
see also: