Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Empty responses in same (keep-alive) connection after innaccurate middleware call #999

Closed
justdmitry opened this issue Jul 20, 2016 · 1 comment

Comments

@justdmitry
Copy link

If some middleware replaces context.Response.Body with new stream and does not return original one back (due to exception, for example) - then all subsequent requests (to other middleware!) in this keep-alive connection (that's important) will return empty body.

Sample Startup.cs:

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace IISIntegrationResponseBug
{
    public class Startup
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(System.IO.Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .Build();

            host.Run();
        }

        public void ConfigureServices(IServiceCollection services)
        {
            // Nothing
        }

        public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(LogLevel.Debug);

            app.UseDeveloperExceptionPage();

            app.Use(async (context, next) =>
            {
                if (context.Request.Path == "/fail")
                {
                    var originalResponse = context.Response.Body;

                    context.Response.Body = new System.IO.MemoryStream();
                    // ^^^^ This is a cause

                    throw new Exception();
                }
                if (context.Request.Path == "/")
                {
                    await context.Response.WriteAsync("Hello, World");
                    return;
                }
                await next.Invoke();
            });
        }
    }
}

Sample project.json (nothing special, just FYI):

{
  "dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.0.0",
      "type": "platform"
    },
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
    "Microsoft.Extensions.Logging": "1.0.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "Microsoft.AspNetCore.Diagnostics": "1.0.0"
  },

  "frameworks": {
    "netcoreapp1.0": {}
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "runtimeOptions": {
    "configProperties": { "System.GC.Server": true }
  }
}

Now start app, open browser and navigate to http://localhost:5000/ - "Hello World" is shown, good.

Now open http://localhost:5000/fail - nothing is shown. A little strange (where is DeveloperExceptionPage?), but the most interesting is ahead...

Open http://localhost:5000/ again - nothing is shown. There is no "Hello World" here.
Middleware had been called and produced an answer, but it's lost. You will never receive any response body in this keep-alive connection.

@benaadams
Copy link
Contributor

benaadams commented Jul 20, 2016

Dupe/Previous issue: #940
Workaround: #940 (comment)
Fix: #955

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants