2010-07-13 36 views
4

概述如何使用自定義IHttpModule和HttpRequest過濾器來修改POST請求?

我希望能夠將請求參數和內容修改爲第三方Web服務(ArcGIS Server)。這將用於創建存在於任何客戶端應用程序和服務器應用程序之間的安全層。

我認爲我已經找到了解決方案,但我目前在實施中遇到了一些困難。

潛在的解決方案:修改了自定義請求過濾

對我實施嚴格基於sample shown on MSDN自定義請求過濾解決方案要求。我已經'增強'了代碼,以便我可以使用正則表達式來搜索和替換必要的內容。這包括:

  1. 將內容(存儲在字節數組中)轉換爲字符串。
  2. 搜索字符串並執行任何必要的修改。
  3. 將修改後的字符串轉換爲字節數組並將其寫入緩衝區。

一個示例如下所示:

public override int Read(byte[] buffer, int offset, int count) 
{ 
    int bytesRead = _stream.Read(buffer, offset, count); 

    string orgContent = Encoding.UTF8.GetString(buffer, offset, bytesRead); 
    string orgContentDecoded = HttpUtility.UrlDecode(orgContent); 

    string layersPattern = @"&layers=(show|hide|include|exclude):([0-9]+,?)+"; 
    Regex layersRegex = new Regex(layersPattern, RegexOptions.IgnoreCase); 

    string[] permittedLayers = new string[] { "0" , "1" }; 
    string replacementLayers = "&layers=show:" + String.Join(",", permittedLayers); 
    string newContentDecoded = layersRegex.Replace(orgContentDecoded, replacementLayers); 

    string newContent = newContentDecoded.Replace(",", "%2C").Replace(":", "%3A"); 

    byte[] newBuffer = Encoding.UTF8.GetBytes(newContent); 
    int newByteCountLength = Encoding.UTF8.GetByteCount(newContent); 

    Encoding.UTF8.GetBytes(newContent, 0, Encoding.UTF8.GetByteCount(newContent), buffer, 0); 

    return bytesRead; 
} 

這似乎只要經修改的內容長度不大於原始內容的長度不同,以很好地工作。例如,如果我用1代替1,那麼一切正常。但是,如果我用10替換1(從而將消息大小增加1),那麼我會從ArcGIS Server收到格式不受支持的錯誤。

這帶來了兩個問題引起我的注意:

  1. 當前的實現不處理分塊請求。也就是說,如果請求sie足夠大,則對於單個請求可能會多次調用Read。 在這種情況下應該如何處理chunking?
  2. 錯誤信息的根本原因是什麼?與內容長度相關的問題是否與流長度不同? 如何正確修改內容以便更改其長度不是問題?

有什麼想法?

回答

4

這個問題的第二部分的答案是返回修改後的內容大小,而不是原始流的大小。看哪!

// return bytesRead; 
return newByteCountLength; 
2

這個問題和你的回答對我來說真的很有用,但答案是沒有,如果你想插入大量數據到流原委:

返回修改後的內容大小隻有在您插入到流中的數據不會佔用通過count值讀入緩衝區的字節數時纔有效。如果您嘗試插入太多數據,則要麼發現buffer對象不夠大,無法保存要插入的數據,要麼將多於count字節寫入緩衝區,則會覆蓋緩衝區末尾的一些數據本來應該放在一邊。

如果您需要插入比當前buffer對象容納的數據更多的數據,那麼您必須將數據緩存在單獨的字節數組中,並在製作對stream.read的調用時將其複製爲塊。

相關問題