Mo Valipour
Mo Valipour

Reputation: 13496

Rewrite the response in Owin Middleware

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

Answers (2)

Johnny
Johnny

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

jpatapoff
jpatapoff

Reputation: 335

You should call Next.Invoke only if someCondition(context) is false. I think you'll find this blog post helpful.

Upvotes: 0

Related Questions