I've been trying to plug some OWIN middleware into an existing WebApi project. My start-up originally contained only the following lines:
application.UseOAuthBearerAuthentication(newOAuthBearerAuthenticationOptions());
application.UseWebApi(config);
With this configuration, I was intermittently, and mainly after an iisreset, receiving malformed responses (as identified by fiddler) that were being caused by the middleware trying to add headers but after the response had been sent, this was being reported as the exception:
Server cannot append header after HTTP headers have been sent.
I recompiled Microsoft.Owin.Security.OAuth to add some additional tracing to show the order that thing were happening and I got the following output:
Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware Information: 0 : : OAUTH: Authenticating...
System.Web.Http.Request: ;;http://localhost:555/entityinstance/member
System.Web.Http.Controllers: WebHostHttpControllerTypeResolver;GetControllerTypes;:
System.Web.Http.Controllers: WebHostHttpControllerTypeResolver;GetControllerTypes;:
System.Web.Http.MessageHandlers: LogHandler;SendAsync;:
System.Web.Http.Controllers: DefaultHttpControllerSelector;SelectController;Route='entityDefinitionName:member,controller:EntityInstance'
System.Web.Http.Controllers: DefaultHttpControllerSelector;SelectController;EntityInstance
System.Web.Http.Controllers: HttpControllerDescriptor;CreateController;:
System.Web.Http.Controllers: WindsorCompositionRoot;Create;:
System.Web.Http.Controllers: WindsorCompositionRoot;Create;Loyalty.Services.WebApi.Controllers.EntityInstanceController
System.Web.Http.Controllers: HttpControllerDescriptor;CreateController;Loyalty.Services.WebApi.Controllers.EntityInstanceController
System.Web.Http.Controllers: EntityInstanceController;ExecuteAsync;:
System.Web.Http.Action: ApiControllerActionSelector;SelectAction;:
System.Web.Http.Action: ApiControllerActionSelector;SelectAction;Selected action 'Get(String entityDefinitionName)'
System.Net.Http.Formatting: DefaultContentNegotiator;Negotiate;Type='HttpError', formatters=[JsonMediaTypeFormatterTracer, XmlMediaTypeFormatterTracer, FormUrlEncodedMediaTypeFormatterTracer, FormUrlEncodedMediaTypeFormatterTracer]
System.Net.Http.Formatting: JsonMediaTypeFormatter;GetPerRequestFormatterInstance;Obtaining formatter of type 'JsonMediaTypeFormatter' for type='HttpError', mediaType='application/json; charset=utf-8'
System.Net.Http.Formatting: JsonMediaTypeFormatter;GetPerRequestFormatterInstance;Will use same 'JsonMediaTypeFormatter' formatter
System.Net.Http.Formatting: DefaultContentNegotiator;Negotiate;Selected formatter='JsonMediaTypeFormatter', content-type='application/json; charset=utf-8'
System.Web.Http.Controllers: EntityInstanceController;ExecuteAsync;:
System.Net.Http.Formatting: JsonMediaTypeFormatter;WriteToStreamAsync;Value='System.Web.Http.HttpError', type='HttpError', content-type='application/json; charset=utf-8'
System.Net.Http.Formatting: JsonMediaTypeFormatter;WriteToStreamAsync;:
System.Web.Http.Request: ;;Content-type='application/json; charset=utf-8', content-length=68
System.Web.Http.Controllers: EntityInstanceController;Dispose;:
System.Web.Http.Controllers: EntityInstanceController;Dispose;:
Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware Information: 0 : : OAUTH: Applying Challange...
A first chance exception of type 'System.Web.HttpException' occurred in System.Web.dll
So what it looks like is that the response handling part of the middleware, following the Russian doll model is trying to modify headers, but the response has already been completed at a previous stage. I have tried adding different stage markers to control this behavior, but nothing seems to help.
The surprising thing after seeing that trace, was that it wasn't happening all the time. I wrote my own version of this middleware with a more minimal implementation and after registering this, in place of the MS one, I did indeed start to see the error on every request, I'm wondering if it was always being thrown, but swallowed on occasion or whether fiddler wasn't waiting around for long enough to see it.
My current best guess is this problem is happening as a result of using a different HttpConfiguration for Owin than the WebApi setup. Unfortnately, I can't swap out the entirety of the HTTPApplication and go over to OWIN lock stock because of way that delegating handlers run inside a different context in OWIN, where you don't have access to route data, as this would break a lot of our existing infrastructure.
Can any give me any pointers as to what's going on here, is this a supported scenario? Am I missing something obvious?