Я считаю, что неплохо разбираюсь в C#, но столкнулся с проблемой понимания следующего фрагмента кода:
using (var memoryStream = new MemoryStream())
{
var responseStream = httpContext.Response.Body;
httpContext.Response.Body = memoryStream;
await this.next(httpContext);
using (var compressedStream = new GZipStream(responseStream, CompressionLevel.Optimal))
{
httpContext.Response.Headers.Add("Content-Encoding", new [] { "gzip" });
memoryStream.Seek(0, SeekOrigin.Begin);
await memoryStream.CopyToAsync(compressedStream);
}
}
Этот код извлечен из промежуточного программного обеспечения ASP.Net Core, которое сжимает ответ HTTP, и "на удивление", он работает... или так кажется (я тестировал его с помощью Fiddler).
Позвольте мне сначала выразить свое понимание:
- Код начинается со ссылки на
httpContext.Response.Body
вresponseStream
. - Затем он заменяет ссылку
httpContext.Response.Body
вновь инициализированнойmemoryStream
. - Если я понимаю, как работают ссылки C#, я говорю, что у нас все еще есть ссылка на исходные данные
httpContext.Response.Body
сresponseStream
, аhttpContext.Response.Body
новые данные пусты. - Затем мы вызываем следующее промежуточное ПО в конвейере.
- Поскольку
this.next()
является ожидаемым, выполнение нашего кода «остановится» до тех пор, пока не вернутся все промежуточные программы. - Когда выполнение нашего кода «возобновляется», он инициализирует
GZipStream
, добавляет заголовок ответа и «ищет» началоmemoryStream
. - Наконец, он копирует содержимое или
memoryStream
вcompressedStream
, который записывает его вresponseStream
.
Итак, какова связь между memoryStream
, compressedStream
и responseStream
? Мы создали compressedStream
для записи в responseStream
, а затем в httpContext.Response.Body
, но ссылки с responseStream
на httpContext.Response.Body
больше нет?