Tôi đã chơi xung quanh bằng cách sử dụng API Web (Máy chủ web) làm máy chủ proxy và đã gặp sự cố với cách proxy Web API xử lý phản hồi bằng "Chuyển mã hóa : chunked "tiêu đề.API Web dưới dạng Proxy và Mã hóa chuyển chunked
Khi bỏ qua proxy, tài nguyên từ xa gửi các tiêu đề phản ứng sau đây:
Cache-Control:no-cache
Content-Encoding:gzip
Content-Type:text/html
Date:Fri, 24 May 2013 12:42:27 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
Transfer-Encoding:chunked
Vary:Accept-Encoding
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
Khi đi qua proxy dựa Web API của tôi, yêu cầu của tôi bị treo trừ khi tôi dứt khoát thiết lập lại tài sản TransferEncodingChunked vào tiêu đề đối phó với sai :
response.Headers.TransferEncodingChunked = false;
tôi thừa nhận, tôi không hoàn toàn hiểu những gì tác động thiết lập thuộc tính TransferEncodingChunked có, nhưng có vẻ như xa lạ với tôi rằng để thực hiện công việc ủy quyền như mong đợi, tôi cần phải đặt khách sạn này là false khi rõ ràng phản hồi đến có tiêu đề "Chuyển mã hóa: chunked". Tôi cũng lo ngại về tác dụng phụ để thiết lập rõ ràng tài sản này. Bất cứ ai có thể giúp tôi hiểu những gì đang xảy ra và tại sao thiết lập tài sản này là bắt buộc?
CẬP NHẬT: Vì vậy, tôi đã nghiên cứu thêm một chút về sự khác biệt trong phản hồi khi đi qua proxy so với không. Cho dù tôi đặt rõ ràng thuộc tính TransferEncodingChunked thành false, tiêu đề phản hồi khi đến thông qua proxy cũng giống như khi không thông qua proxy. Tuy nhiên, nội dung phản hồi là khác nhau. Dưới đây là một số mẫu (tôi đã tắt mã hóa gzip):
// With TransferEncodingChunked = false
2d\r\n
This was sent with transfer-encoding: chunked\r\n
0\r\n
// Without explicitly setting TransferEncodingChunked
This was sent with transfer-encoding: chunked
Rõ ràng, nội dung được gửi với TransferEncodingChọn được đặt thành sai được chuyển thực tế được mã hóa. Đây thực sự là câu trả lời chính xác vì nó được nhận từ tài nguyên được yêu cầu phía sau proxy. Điều gì tiếp tục là lạ là kịch bản thứ hai trong đó tôi không rõ ràng đặt TransferEncodingChunked trên phản hồi (nhưng nó nằm trong tiêu đề phản hồi nhận được từ dịch vụ proxy). Rõ ràng, trong trường hợp này, phản ứng KHÔNG thực sự được chuyển mã hóa bởi IIS, mặc dù thực tế là đáp ứng thực tế là. Lạ ... điều này đang bắt đầu cảm thấy như hành vi thiết kế (trong trường hợp đó, tôi rất muốn biết làm thế nào/tại sao) hoặc một lỗi trong IIS, ASP.Net, hoặc Web API.
Đây là một phiên bản đơn giản của mã Tôi đang chạy:
Proxy Web ứng dụng API:
// WebApiConfig.cs
config.Routes.MapHttpRoute(
name: "Proxy",
routeTemplate: "{*path}",
handler: HttpClientFactory.CreatePipeline(
innerHandler: new HttpClientHandler(), // Routes the request to an external resource
handlers: new DelegatingHandler[] { new ProxyHandler() }
),
defaults: new { path = RouteParameter.Optional },
constraints: null
);
// ProxyHandler.cs
public class ProxyHandler : DelegatingHandler
{
protected override async System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
// Route the request to my web application
var uri = new Uri("http://localhost:49591" + request.RequestUri.PathAndQuery);
request.RequestUri = uri;
// For GET requests, somewhere upstream, Web API creates an empty stream for the request.Content property
// HttpClientHandler doesn't like this for GET requests, so set it back to null before sending along the request
if (request.Method == HttpMethod.Get)
{
request.Content = null;
}
var response = await base.SendAsync(request, cancellationToken);
// If I comment this out, any response that already has the Transfer-Encoding: chunked header will hang in the browser
response.Headers.TransferEncodingChunked = false;
return response;
}
}
Và điều khiển ứng dụng web của tôi mà tạo ra một "chửi rủa" phản ứng (cũng Web API):
public class ChunkedController : ApiController
{
public HttpResponseMessage Get()
{
var response = Request.CreateResponse(HttpStatusCode.OK);
var content = "This was sent with transfer-encoding: chunked";
var bytes = System.Text.Encoding.ASCII.GetBytes(content);
var stream = new MemoryStream(bytes);
response.Content = new ChunkedStreamContent(stream);
return response;
}
}
public class ChunkedStreamContent : StreamContent
{
public ChunkedStreamContent(Stream stream)
: base(stream) { }
protected override bool TryComputeLength(out long length)
{
length = 0L;
return false;
}
}
tiêu đề trông giống như thế nào trên yêu cầu gửi đi (proxy) khi nó bị treo? so sánh cái này với cái được bỏ qua. – wal