Смятам, че съм доста добър в 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
вече я няма?