aspnet / AspNetKatana

Microsoft's OWIN implementation, the Katana project
Apache License 2.0
960 stars 331 forks source link

ObjectDisposedException calling IOwinResponse.Context.Request #456

Closed abatishchev closed 2 years ago

abatishchev commented 2 years ago

Under certain (unknown) circumstances the following code fails with ObjectDisposedException:

public override Task Invoke(IOwinContext context)
{
    var response = context.Response;
    response?.OnSendingHeaders(
        state => UpdateResponse((IOwinResponse)state),
        response);
    return this.Next.Invoke(context);
}

private void UpdateResponse(IOwinResponse response)
{
  string requestUri = response.Context.Request.Path.Value;
  string host = response.Context.Request.Uri.Host; // <-- here
}

Stack trace (note HttpListenerRequest):

Object name: 'System.Net.HttpListenerRequest'.
   at System.Net.HttpListenerRequest.CheckDisposed()
   at System.Net.HttpListenerRequest.GetKnownHeader(HttpRequestHeader header)
   at System.Net.HttpListenerRequest.get_ContentLength64()
   at System.Net.HttpListenerRequest.get_HasEntityBody()
   at System.Net.HttpListenerRequest.get_InputStream()
   at Microsoft.Owin.Host.HttpListener.RequestProcessing.OwinHttpListenerContext.GetRequestBody()
   at Microsoft.Owin.Host.HttpListener.RequestProcessing.CallEnvironment.get_RequestBody()
   at Microsoft.Owin.Host.HttpListener.RequestProcessing.CallEnvironment.PropertiesTryGetValue(String key, Object& value)
   at Microsoft.Owin.Host.HttpListener.RequestProcessing.CallEnvironment.TryGetValue(String key, Object& value)
   at Microsoft.Owin.OwinRequest.Get[T](String key)
   at System.Web.Http.Owin.HttpMessageHandlerAdapter.<InvokeCore>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.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__5.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.AAD.Throttling.GatewayService.Middleware.UpdateResponseHeaders.UpdateResponseHeadersMiddleware.<Invoke>d__2.MoveNext() in C:\source\src\Service\GatewayService\Middleware\UpdateResponseHeaders\UpdateResponseHeadersMiddleware.cs:line 42
--- 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.AAD.Throttling.GatewayService.Middleware.Reporting.LoggerMiddleware.<Invoke>d__8.MoveNext() in C:\source\src\Service\GatewayService\Middleware\Reporting\LoggerMiddleware.cs:line 45

and (note HttpListenerResponse):

Object name: 'System.Net.HttpListenerResponse'.
   at System.Net.HttpListenerResponse.CheckDisposed()
   at System.Net.HttpListenerResponse.set_ContentLength64(Int64 value)
   at Microsoft.Owin.Host.HttpListener.RequestProcessing.HeadersDictionaryBase.Set(String key, String[] value)
   at System.Web.Http.Owin.HttpMessageHandlerAdapter.SendResponseMessageAsync(HttpRequestMessage request, HttpResponseMessage response, IOwinResponse owinResponse, CancellationToken cancellationToken)
   at System.Web.Http.Owin.HttpMessageHandlerAdapter.<InvokeCore>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.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__5.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.AAD.Throttling.GatewayService.Middleware.UpdateResponseHeaders.UpdateResponseHeadersMiddleware.<Invoke>d__2.MoveNext() in C:\source\src\Service\GatewayService\Middleware\UpdateResponseHeaders\UpdateResponseHeadersMiddleware.cs:line 42
--- 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.AAD.Throttling.GatewayService.Middleware.Reporting.LoggerMiddleware.<Invoke>d__8.MoveNext() in C:\source\src\Service\GatewayService\Middleware\Reporting\LoggerMiddleware.cs:line 45

Environment:

.NET Framework 4.6.2
Azure Service Fabric

Packages:

<PackageReference Include="Microsoft.Owin" Version="4.2.0" />
<PackageReference Include="Microsoft.Owin.FileSystems" Version="4.2.0" />
<PackageReference Include="Microsoft.Owin.Host.HttpListener" Version="4.2.0" />
<PackageReference Include="Microsoft.Owin.Hosting" Version="4.2.0" />
<PackageReference Include="Microsoft.Owin.Security" Version="4.2.0" />
<PackageReference Include="Microsoft.Owin.Security.ActiveDirectory" Version="4.2.0" />
<PackageReference Include="Microsoft.Owin.StaticFiles" Version="4.2.0" />
abatishchev commented 2 years ago

Here's an alternative stack trace for HttpListenerRequest:

Object name: 'System.Net.HttpListenerRequest'.
   at System.Net.HttpListenerRequest.CheckDisposed()
   at System.Net.HttpListenerRequest.get_LocalEndPoint()
   at System.Net.HttpListenerRequest.get_IsLocal()
   at Microsoft.Owin.Host.HttpListener.RequestProcessing.OwinHttpListenerContext.GetServerIsLocal()
   at Microsoft.Owin.Host.HttpListener.RequestProcessing.CallEnvironment.get_ServerIsLocal()
   at Microsoft.Owin.Host.HttpListener.RequestProcessing.CallEnvironment.PropertiesTryGetValue(String key, Object& value)
   at Microsoft.Owin.Host.HttpListener.RequestProcessing.CallEnvironment.TryGetValue(String key, Object& value)
   at Microsoft.Owin.OwinContext.Get[T](String key)
   at System.Web.Http.Owin.OwinHttpRequestContext.get_IsLocal()
   at System.Web.Http.Owin.OwinHttpRequestContext.get_IncludeErrorDetail()
   at System.Web.Http.ExceptionHandling.LastChanceExceptionHandler.CreateDefaultLastChanceResult(ExceptionContext context)
   at System.Web.Http.ExceptionHandling.LastChanceExceptionHandler.HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
   at System.Web.Http.ExceptionHandling.ExceptionHandlerExtensions.<HandleAsyncCore>d__1.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 System.Web.Http.HttpServer.<SendAsync>d__24.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 System.Web.Http.Owin.HttpMessageHandlerAdapter.<InvokeCore>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.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__5.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.AAD.Throttling.GatewayService.Middleware.UpdateResponseHeaders.UpdateResponseHeadersMiddleware.<Invoke>d__2.MoveNext() in C:\source\src\Service\GatewayService\Middleware\UpdateResponseHeaders\UpdateResponseHeadersMiddleware.cs:line 42
--- 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.AAD.Throttling.GatewayService.Middleware.Reporting.LoggerMiddleware.<Invoke>d__8.MoveNext() in C:\source\src\Service\GatewayService\Middleware\Reporting\LoggerMiddleware.cs:line 45
abatishchev commented 2 years ago

And for HttpListenerResponse:

Object name: 'System.Net.HttpListenerResponse'.
   at System.Net.HttpListenerResponse.CheckDisposed()
   at System.Net.HttpListenerResponse.set_ContentLength64(Int64 value)
   at Microsoft.Owin.Host.HttpListener.RequestProcessing.HeadersDictionaryBase.Set(String key, String[] value)
   at Microsoft.Owin.OwinResponse.set_ContentLength(Nullable`1 value)
   at Microsoft.Owin.StaticFiles.StaticFileContext.ApplyResponseHeaders(Int32 statusCode)
   at Microsoft.Owin.StaticFiles.StaticFileContext.SendAsync()
   at Microsoft.Owin.StaticFiles.StaticFileMiddleware.Invoke(IDictionary`2 environment)
   at Microsoft.Owin.StaticFiles.DefaultFilesMiddleware.Invoke(IDictionary`2 environment)
   at System.Web.Http.Owin.HttpMessageHandlerAdapter.<InvokeCore>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.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__5.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.AAD.Throttling.GatewayService.Middleware.UpdateResponseHeaders.UpdateResponseHeadersMiddleware.<Invoke>d__2.MoveNext() in C:\source\src\Service\GatewayService\Middleware\UpdateResponseHeaders\UpdateResponseHeadersMiddleware.cs:line 42
--- 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.AAD.Throttling.GatewayService.Middleware.Reporting.LoggerMiddleware.<Invoke>d__8.MoveNext() in C:\source\src\Service\GatewayService\Middleware\Reporting\LoggerMiddleware.cs:line 45
Tratcher commented 2 years ago

This could be related to https://github.com/aspnet/AspNetKatana/issues/430. Can you repro it using the new 4.2.1 release?

abatishchev commented 2 years ago

We're not using HTTP/2. But I've updated all packages to 4.2.1 and will monitor, see if the number of these exceptions will drop.

abatishchev commented 2 years ago

Looks like the error is gone after updating to 4.2.1 indeed. Cool!

Tratcher commented 2 years ago

Great. Does it help with your other three issues as well?