How to write streaming output in NancyFX?

I am writing a simple web application using Nancy. At least one request results in a stream of unknown length, so I cannot provide Content-Length. I would like to use Transfer-Encoding: chunkedor (equally acceptable in this case Connection: close).

I had a quick hack into Nancy's source code, and I added some Response.BufferOutputcode to install HttpContext.Response.BufferOutputin false. You can see it here:

public class HomeModule : NancyModule
{
    public HomeModule()
    {
        Get["/slow"] = _ => new SlowStreamResponse();
    }

    private class SlowStreamResponse : Response
    {
        public SlowStreamResponse()
        {
            ContentType = "text/plain";
            BufferOutput = false;
            Contents = s => {
                byte[] bytes = Encoding.UTF8.GetBytes("Hello World\n");
                for (int i = 0; i < 10; ++i)
                {
                    s.Write(bytes, 0, bytes.Length);
                    Thread.Sleep(500);
                }
            };
        }
    }

This seems to have no effect. The answer appears immediately after 5 seconds. I tested this simple client WebRequest.

How do I get the output file to work in Nancy? I use ASP.NET hosting, but I would be interested in answers to other hosting options.

HttpListener, SendChunked true, , .

+5
3

, . web.config, Nancy Wiki. , , disableoutputbuffer ( ), , . , Nancy.Hosting.Aspnet.DefaultNancyAspNetBootstrapper . .

<configSections>
  <section name="nancyFx" type="Nancy.Hosting.Aspnet.NancyFxSection" />
</configSections>
<nancyFx>
  <bootstrapper assembly="YourAssembly" type="YourBootstrapper"/>
  <disableoutputbuffer value="true" />
</nancyFx>

Transfer-Encoding. , , -, IIS Express Chrome:

Get["/chunked"] = _ =>
{
  var response = new Response();
  response.ContentType = "text/plain";
  response.Contents = s =>
  {
    byte[] bytes = System.Text.Encoding.UTF8.GetBytes("Hello World ");
    for (int i = 0; i < 10; ++i)
    {
      for (var j = 0; j < 86; j++)
      {
        s.Write(bytes, 0, bytes.Length);
      }
      s.WriteByte(10);
      s.Flush();
      System.Threading.Thread.Sleep(500);
    }
  };

  return response;
};

, , - , fooobar.com/questions/307144/...

+5

Flush() Write(), . , Google Chrome , .

, , , .

+4

.NET 4.5+, Stream.CopyTo .

Get["/chunked"] = _ =>
{
  var response = new Response();
  response.ContentType = "text/plain";
  response.Contents = s =>
  {
    using(var helloStream = new MemoryStream(Encoding.UTF8.GetBytes("Hello World ")))
      helloStream.CopyTo(s);
  }
  return response;
}
0

All Articles