darth_phoenixx
darth_phoenixx

Reputation: 952

Empty request body when Transfer-Encoding is Chunked - NancyFX

I have a very simple NancyFX module which I simply want to echo the results of an API call back to the sender.

I am using a facade which converts incoming XML to JSON before handing it off to the Nancy endpoint. This facade changes the content to JSON correctly as I can test it using the echo service for the api and can see the response.

However, because the facade removes the content-length header and sets transfer-encoding to chunked, the Request.Body is always empty in my Nancy module.

Is there a configuration needed to enable support for Chunked encoding in NancyFX?

I am hosting on IIS 7 currently, but have access to IIS 8 as well.

I can see that using OWIN hosting it is possible to enable chunked transfer using HostConfiguration, but due to other factors I cannot use OWIN hosting and rely on IIS hosting.

I have enabled chunked transfer on IIS with the command:

appcmd set config /section:asp /enableChunkedEncoding:True

My web.config is currently:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.5.1" />
    <httpHandlers>
      <add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*" />
    </httpHandlers>
    <httpRuntime targetFramework="4.5.1" />
    <webServices>
      <protocols>
        <add name="HttpGet" />
        <add name="HttpPost" />
      </protocols>
    </webServices>
  </system.web>
  <system.webServer>
    <modules>
      <remove name="WebDavModule" />
    </modules>
    <handlers>
      <remove name="WebDAV" />
      <add name="Nancy" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*" />
    </handlers>
    <validation validateIntegratedModeConfiguration="false" />
    <httpErrors existingResponse="PassThrough" />
  </system.webServer>
</configuration>

The module itself is very simple and consists of:

    Post["/"] = parameters =>
    {
        var traceRef = Guid.NewGuid();
        var body = this.Request.Body.AsString();
        Logger.Trace("Trace ref: {0}, request inbound.", traceRef);
        Logger.Trace(body);

        AuthRequest auth = new AuthRequest();
        try
        {
            auth = this.Bind<AuthRequest>();
        }
        catch (Exception ex)
        {
            Logger.Error("Trace ref: {0}, error: {1}. Exception: {2}", traceRef, ex.Message, ex);
        }

        var responseObject = new
        {
            this.Request.Headers,
            this.Request.Query,
            this.Request.Form,
            this.Request.Method,
            this.Request.Url,
            this.Request.Path,
            auth
        };

        return Response.AsJson(responseObject);
    };

Upvotes: 2

Views: 1898

Answers (1)

Joe B
Joe B

Reputation: 883

My first thought when reading this was Transfer-Encoding is only meant for responses not requests. Looking at the list of HTTP header fields, Transfer-Encoding is only listed under Response Fields. But the spec doesn't mention request or response just sender and recipient. Now I'm not so sure.

Anyway, the ASP.NET hosting code explicitly excludes the body if the content length is 0, but the self-hosting code doesn't seem to have the same restriction. I'm not sure if this difference is intentional. You could remove the if statement that checks the content length and send a PR to the Nancy team. See what they come back with.

Upvotes: 1

Related Questions