Reputation: 13496
In my OWIN app, I register a middleware to intercept the outcome of other middlewares down in the pipeline and if a condition is met, I need to totally change the response from whatever it is (could be 302
or 200
) to 403
(forbidden).
There is ofcourse a not-very-clean-way and that is to manually clear all the headers, content type, etc. and set the statusCode to 403
but this feels to me a wrong approach.
public override async Task Invoke(IOwinContext context)
{
await this.Next.Invoke(context);
if (someCondition(context))
{
var headers = context.Response.Headers;
headers.Keys.ForEach(k => headers.Remove(k));
context.Response.StatusCode = 403;
context.Response.ContentType = string.Empty;
context.Response.ContentLength = null;
await context.Response.WriteAsync(string.Empty);
}
}
Plus the fact that this approach doesn't work when overwriting a 200
response (when it hits the line where we set StatusCode
, it jumps out and flushes the response).
I'm new to OWIN and I may be misunderstanding the way it works.
Is there any other way you would do this?
Upvotes: 3
Views: 3902
Reputation: 795
Here is what I discovered.
If you try to change the response headers after you reached the controller, the headers might already have been sent.
That's why you should subscribe to the OnSendingHeaders(Action<object> callback, object state)
before continuing the pipeline.
Example:
...
context.Response.OnSendingHeaders(obj => { /* Do stuff */ }, new object());
// Then call the next middleware
await this.Next.Invoke(context);
...
Upvotes: 3
Reputation: 335
You should call Next.Invoke only if someCondition(context) is false. I think you'll find this blog post helpful.
Upvotes: 0