2013-06-18 27 views
1

我正在爲web-api應用程序進行一些壓縮/解壓縮。在web api中無縫地解壓縮請求內容

我已經實施了其中的大部分功能,感謝網頁上的multiple articlesquestions posted here

但是,我仍然堅持一個問題,顯然還沒有被質疑。

我簡短地說,我需要支持大量數據的流式傳輸,無論是響應和請求,還是壓縮。我已經實施了DelegatingHandler並創建了2個HttpContent類,一個用於壓縮內容(響應),另一個用於解壓縮內容(請求)。

壓縮響應使用下面的代碼

protected override Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context) 
{ 
    Stream compressionStream = this.Compressor.CreateCompressionStream(stream); 

    return this.OriginalContent.CopyToAsync(compressionStream).ContinueWith(task => 
    { 
     if (compressionStream != null) 
     { 
      compressionStream.Dispose(); 
     } 
    }); 
} 

我創建了一個壓縮流和複製的原始內容的壓縮數據流可以完美運行。但是,當解壓縮請求時,我正在使用以下代碼。

protected override Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context) 
{ 
    Stream compressionStream = 
     this.Compressor.CreateDecompressionStream(
             this.OriginalContent.ReadAsStreamAsync().Result); 

    return compressionStream.CopyToAsync(stream).ContinueWith(task => 
    { 
     if (compressionStream != null) 
     { 
      compressionStream.Dispose(); 
     } 
    }); 
} 

正如你所看到的,我有義務將其複製到減壓流之前讀取原始請求的流,並進一步發下來的管道。

將大量數據發佈到服務時,這可能不是一個好的做法。 所以現在的問題是,這是做到這一點的正確方法?我一直在尋找一種無縫的方式來做到這一點。

我在考慮實現一個Blocking Stream(適應新的TAP),但我又被卡住了,因爲HttpContent完全是TAP,這意味着所有東西都返回一個Task對象,而且我需要一個處理實際Stream。

回答

0

我可以回答你的問題的一部分。當您撥打this.OriginalContent.ReadAsStreamAsync()時,您的請求內容已被緩存。這是因爲默認Web API會緩存所有傳入的請求。但是,對於較大的請求,不使用此緩衝模式是有意義的。但是,您可以更改此默認緩衝策略。

實例下(如果你使用的是虛擬主機提供商這並不適用於Selfhost工作。):

config.Services.Replace(typeof(IHostBufferPolicySelector), new CustomBufferPolicySelector()); 

public class CustomBufferPolicySelector : WebHostBufferPolicySelector 
{ 
    // This method gets called for every incoming request. You can inspect the HttpContextBase instance 
    // to decide whether you would want buffered/non-buffered way of handling individual requests. 
    public override bool UseBufferedInputStream(object hostContext) 
    { 
     HttpContextBase contextBase = hostContext as HttpContextBase; 

     //by default, this returns 'true' 
     return base.UseBufferedInputStream(hostContext); 
    } 

    // just fyi 
    public override bool UseBufferedOutputStream(HttpResponseMessage response) 
    { 
     return base.UseBufferedOutputStream(response); 
    } 
} 

現在具有上述的自定義策略後,當你做一個this.OriginalContent.ReadAsStreamAsync(),你會正在接收緩衝流。

+0

有趣。我記得幾個星期前我讀過這個政策。但機智的是,我仍然在緩衝它,然後再通過解壓縮流。我希望新的HttpClient和便攜式壓縮庫會給我一些見解,但到目前爲止並不是真的。 – Ronald