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

SendFileAsync has problem in core 1.1 #1375

Closed
alireza-naghizadeh opened this issue Feb 20, 2017 · 10 comments
Closed

SendFileAsync has problem in core 1.1 #1375

alireza-naghizadeh opened this issue Feb 20, 2017 · 10 comments

Comments

@alireza-naghizadeh
Copy link

alireza-naghizadeh commented Feb 20, 2017

Hi,
After updating from asp.net core 1.0 to 1.1
Response.SendFileAsync(...) works but in client side I have this error:

...ERR_INCOMPLETE_CHUNKED_ENCODING

I have a bad solution for now! by change "Microsoft.AspNetCore.Server.Kestrel" version to 1.0.2 or lower in "project.json" file...

What is the problem?! Why the server connection is alive after sending file?!
Thanks

@halter73
Copy link
Member

@alireza-naghizadeh Thanks for the bug report. Would it be possible to capture server-side console logs during a failed request made to a 1.1 server.

My current theory is that something in the application pipeline is throwing an exception. It could either be SendFileAsync or some other middleware. Console logs could help us determine if that's really the case.

@alireza-naghizadeh
Copy link
Author

There isn't any custom middleware! Please, Do these steps to simulate this problem:

  1. Open visual studio! and File -> New -> Project
  2. From templates select Visual C# -> Web -> ASP.NET Core Web Application (.NET Core)
  3. Choose Web Application from ASP.NET Core Templates
  4. Open Controllers->HomeController and Add new action & reference like this:

using Microsoft.AspNetCore.Http;

        public async Task Test()
        {
            await Response.SendFileAsync("c:\\test.jpg");
        }

  1. Save an image with name "test.jpg" in "C" drive... then run project
  2. Go to url "http://localhost:???/home/test" to load the image...
    Till now every thing is OK...
  3. Now Open "project.json" file for change .net core 1.0 to 1.1 like this:
{
  "dependencies": {
    "Microsoft.AspNetCore.Diagnostics": "1.1.0",
    "Microsoft.AspNetCore.Mvc": "1.1.0",
    "Microsoft.AspNetCore.Razor.Tools": {
      "version": "1.1.0-preview4-final",
      "type": "build"
    },
    "Microsoft.AspNetCore.Routing": "1.1.0",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
    "Microsoft.AspNetCore.StaticFiles": "1.1.0",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
    "Microsoft.Extensions.Configuration.Json": "1.1.0",
    "Microsoft.Extensions.Logging": "1.1.0",
    "Microsoft.Extensions.Logging.Console": "1.1.0",
    "Microsoft.Extensions.Logging.Debug": "1.1.0",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.1.0"
  },

  "tools": {
    "BundlerMinifier.Core": "2.0.238",
    "Microsoft.AspNetCore.Razor.Tools": "1.1.0-preview4-final",
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.1.0-preview4-final"
  },

  "frameworks": {
    "netcoreapp1.1": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.1.0"
        }
      },
      "imports": "dnxcore50"
    }
  },

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

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

  "publishOptions": {
    "include": [
      "wwwroot",
      "**/*.cshtml",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "prepublish": [ "bower install", "dotnet bundle" ],
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

  1. Run project and go to url "http://localhost:???/home/test" to load the image again...
  2. In chrome right-click to choose inspect and select Console tab...
  3. If you Empty Cache and Hard Reload... you can see the error:

GET http://localhost:???/home/test net::ERR_CONNECTION_RESET

@alireza-naghizadeh
Copy link
Author

This is the console logs of this project:

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:2481/home/test  
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executing action method WebApplication1.Controllers.HomeController.Test (WebApplication1) with arguments ((null)) - ModelState is Valid
The thread 0x35f8 has exited with code 0 (0x0).
The thread 0x3114 has exited with code 0 (0x0).
The thread 0x222c has exited with code 0 (0x0).
The thread 0x3088 has exited with code 0 (0x0).
The thread 0x20ac has exited with code 0 (0x0).
The thread 0x110c has exited with code 0 (0x0).
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action WebApplication1.Controllers.HomeController.Test (WebApplication1) in 12699.325ms
'dotnet.exe' (CoreCLR: clrhost): Loaded 'C:\Users\Naghizadeh\.nuget\packages\System.Diagnostics.StackTrace\4.3.0\lib\netstandard1.3\System.Diagnostics.StackTrace.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'dotnet.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\1.1.0\System.IO.MemoryMappedFiles.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'dotnet.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\1.1.0\System.IO.UnmanagedMemoryStream.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware:Error: An unhandled exception has occurred while executing the request

System.InvalidOperationException: OnStarting cannot be set, response has already started.
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.ThrowResponseAlreadyStartedException(String value)
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.OnStarting(Func`2 callback, Object state)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware:Warning: The response has already started, the error page middleware will not be executed.
Microsoft.AspNetCore.Server.Kestrel:Error: Connection id "0HL2Q6S10D52C": An unhandled exception was thrown by the application.

System.InvalidOperationException: OnStarting cannot be set, response has already started.
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.ThrowResponseAlreadyStartedException(String value)
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.OnStarting(Func`2 callback, Object state)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.<Invoke>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame`1.<RequestProcessingAsync>d__2.MoveNext()
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 12844.9601ms 200 
The thread 0x2080 has exited with code 0 (0x0).

@davidfowl
Copy link
Member

You might be running into this aspnet/Mvc#5555

@davidfowl
Copy link
Member

The work around is to use the proper action result, either PhysicalFile or File:

public IActionResult Test()
{
    return PhysicalFile("c:\\test.jpg", "image/jpeg");
}

@alireza-naghizadeh
Copy link
Author

That was a sample to show the bug (problem)...
In my project I can't do this! I have access to Response object only... I can't return any thing...
My code is in a service not a controller...
How can I solve this problem properly?
Thanks

@davidfowl
Copy link
Member

davidfowl commented Feb 21, 2017

You you elaborate? What component are you in that you only have access to the response object. The work around is to avoid writing to the response directly in the action method. You can do that by using a built in or custom action result.

If you can be more specific about what you're problem is (maybe posting a real sample), then we can help.

@alireza-naghizadeh
Copy link
Author

I have a temporary solution for now, but when and how you can solve the main problem?!
Your answer is not solution! I want to use SendFileAsync...
If we shouldn't use this method, so, delete this function from asp.net core!

@davidfowl
Copy link
Member

davidfowl commented Feb 21, 2017

See the issue I linked to aspnet/Mvc#5555

@halter73
Copy link
Member

@alireza-naghizadeh If the console logs you provided were from your simplified repo, it might help to include the console logs from your real application taken when the error occurs. If not, you really are running into aspnet/Mvc#5555 which will be fixed. My bet is that something is throwing an exception before the file can be (fully) written.

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

No branches or pull requests

3 participants