簡體   English   中英

在 ASP.NET 5 響應中設置 Content-Length 標頭

[英]Setting Content-Length header in ASP.NET 5 response

TL; DR我有一個 ASP.NET 5 (MVC 6) 應用程序,只是嘗試設置 HTTP Content-Length 標頭以避免分塊響應。

令我驚訝的是,這恰好是在 ASP.NET 5 中完成的一項非常棘手的任務。一切都在 Kestrel 上運行,Kestrel 來自 ASP.NET 5 Beta7, 當沒有為響應指定內容長度時,它支持自動編寫分塊響應

還有一個類似的問題在這里,但不同的是,OP只是想算的響應大小,而我需要確保的Content-Length頭的響應中發送。 到目前為止嘗試了很多東西,唯一有效的是編寫自定義中間件:

public class WebApiMiddleware {
    RequestDelegate _next;

    public WebApiMiddleware(RequestDelegate next) {
        _next = next;
    }

    public async Task Invoke(HttpContext context) {
         using (var buffer = new MemoryStream()) {
            var response = context.Response;

            var bodyStream = response.Body;
            response.Body = buffer;

            await _next(context);

            response.Headers.Add("Content-Length", new[] { buffer.Length.ToString()});
            buffer.Position = 0;
            await buffer.CopyToAsync(bodyStream);
        }
     }
}

然而,這是非常低效的,因為我們在處理每個請求時都在使用額外的內存。 使用僅環繞context.Response.Body流並額外計算字節的自定義流不起作用,因為 Microsoft 團隊表示,一旦他們願意緩沖的數據量已寫入,它就會在線路上消失並且他們不再存儲它,所以我最多可以將 Content-Length 添加到最后一個塊,這不是所希望的行為 - 我想完全避免分塊。

任何幫助表示高度贊賞!

ps 我知道分塊是 HTTP/1.1 的常規功能,但在我的場景中它會降低性能,所以我想避免它而不強制客戶端發送 HTTP/1.0 請求。

您需要在發送響應之前發送標頭,因此您需要在發送之前存儲整個響應以確定長度。

正如您所說, context.Response.Body流在發送之前不會存儲太多,因此開銷並不大。

有做類似事情的中間件: https : //github.com/aspnet/BasicMiddleware/blob/master/src/Microsoft.AspNetCore.Buffering/ResponseBufferingMiddleware.cs它與您編寫的非常相似,但支持IHttpBufferingFeature等附加功能允許其他中間件控制緩沖。

檢查bufferStream.CanSeek是為了確保沒有人已經將響應流包裝到緩沖流中並避免雙緩沖。

對於您的第二個問題:這個地方是中間件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM