0

I have the following middleware code:

public class UoWMiddleware : OwinMiddleware
{
    readonly IUoW uow;
    public UoWMiddleware(OwinMiddleware next, IUoW uow) : base(next)
    {
        this.uow = uow;
    }

    public override async Task Invoke(IOwinContext context)
    {
        try
        {
            await Next.Invoke(context);
        }
        catch
        {
            uow.RollBack();
            throw;
        }
        finally
        {
            if (uow.Status == Base.SharedDomain.UoWStatus.Running)
            {
                var response = context.Response;
                if (response.StatusCode < 400)
                {
                    Thread.Sleep(1000);
                    uow.Commit();
                }
                else
                    uow.RollBack();
            }
        }
    }
}

Occasionally we observe that the response returns to client before calling uow.Commit() via fiddler. For example we put a break point to uow.Commit and we see the response is returned to client despite that we are on the breakpoint waiting. This is somewhat unexpected. I would think the response will strictly return after the Invoke method ends. Am I missing something?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Onur Gumus
  • 1,389
  • 11
  • 27

1 Answers1

2

In Owin/Katana the response body (and, of course, the headers) are sent to the client at the precise moment when a middleware calls Write on the Response object of the IOwinContext.

This means that if your next middleware is writing the response body your client will receive it before your server-side code returns from the call to await Next.Invoke().

That's how Owin is designed, and depends on the fact that the Response stream may be written just once in a single Request/Response life-cycle.

Looking at your code, I can't see any major problem in such behavior, because you are simply reading the response headers after the response is written to the stream, and thus not altering it.

If, instead, you require to alter the response written by your next middleware, or you strictly need to write the response after you execute further logic server-side, then your only option is to buffer the response body into a memory stream, and than copy it into the real response stream (as per this answer) when you are ready.

I have successfully tested this approach in a different use case (but sharing the same concept) that you may find looking at this answer: https://stackoverflow.com/a/36755639/3670737

Reference:
Changing the response object from OWIN Middleware

Community
  • 1
  • 1
Federico Dipuma
  • 17,655
  • 4
  • 39
  • 56
  • Let me make something clear. I am observering the response is "completed" before my owin method returns. So do you say that this is by design ? – Onur Gumus Apr 27 '16 at 12:48
  • 1
    Yes it is, the response is sent at the same instant a middleware calls `Write`, and this, I assume, happens inside your *next* middleware (e.g. Web API). That's why you see the HTTP response in fiddler before your method returns. – Federico Dipuma Apr 27 '16 at 12:54
  • Yes apparently you are right. In my case I just wanted to hook to the moment response being sent. So OnSendingHeaders callback is what I want. Your post lead me to the correct direction. – Onur Gumus Apr 27 '16 at 14:59