I create a simple ASP .NET Application and write a generic web handler (HelloFilterWithClose.ashx).
HelloFilterWithClose.ashx ProcessRequest with setting a HttpResponse.Filter(MyFilter), and it response to http client with write a PDF file to http body. After writing a PDF file to http body, it Flush and Close HttpResponse.
Running the app on IIS 7.5 Windows Server 2008 R2 sets the transfer encoding of the response to chunked and Wireshark shows that there is only one data chunk but no end of chunked encoding("0\r\n") or tailer("\r\n")
Running the app on IIS 10 will have no above problem.
MyFilter:
public class MyFilter : Stream
{
private Stream m_stream;
public MyFilter(Stream stream)
{
m_stream = stream;
}
public override bool CanRead
{
get { return m_stream.CanRead; }
}
public override bool CanSeek
{
get { return m_stream.CanSeek; }
}
public override bool CanWrite
{
get { return m_stream.CanWrite; }
}
public override long Length
{
get { return m_stream.Length; }
}
public override long Position
{
get
{
return m_stream.Position;
}
set
{
m_stream.Position = value;
}
}
public override void Close()
{
m_stream.Close();
}
public override void Flush()
{
m_stream.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
return m_stream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return m_stream.Seek(offset, origin);
}
public override void SetLength(long value)
{
m_stream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
m_stream.Write(buffer, offset, count);
}
}
HelloFilterWithClose.ashx:
public class HelloFilterWithClose : IHttpHandler
{
public void SimpleRequest(HttpContext context)
{
context.Response.BufferOutput = false;
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("Content-Disposition", "attachment;FileName=filterWithClose.pdf");
context.Response.AddHeader("Content-Length", "32038");
context.Response.WriteFile("hello.pdf");
context.Response.Flush();
context.Response.Close();
}
private void SetFilter(HttpContext context)
{
HttpResponse response = context.Response;
Stream filterStream = response?.Filter;
if (null == filterStream)
{
return;
}
response.Filter = new MyFilter(filterStream);
}
public void ProcessRequest(HttpContext context)
{
SetFilter(context);
SimpleRequest(context);
}
public bool IsReusable
{
get
{
return false;
}
}
}
End