public async Task Invoke(HttpContext httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException("context");
            }

            CancellationToken cancellationToken = httpContext.RequestAborted;
            var httpRequest  = httpContext.Request;
            var httpResponse = httpContext.Response;

            var bufferInput = _bufferPolicySelector.UseBufferedInputStream(hostContext: httpContext);

            if (bufferInput)
            {
                if (!httpRequest.Body.CanSeek)
                {
                    httpRequest.EnableBuffering();
                    await httpRequest.Body.DrainAsync(cancellationToken);

                    httpRequest.Body.Position = 0;
                }
            }

            var request = httpContext.ToHttpRequestMessage();

            SetPrincipal(httpContext.User);

            HttpResponseMessage response = null;
            bool callNext;

            try
            {
                response = await _messageInvoker.SendAsync(request, cancellationToken);

                // Handle null responses
                if (response == null)
                {
                    throw new InvalidOperationException("The message handler did not return a response message.");
                }

                // Handle soft 404s where no route matched - call the next component
                if (IsSoftNotFound(request, response))
                {
                    callNext = true;
                }
                else
                {
                    callNext = false;

                    // Compute Content-Length before calling UseBufferedOutputStream because the default implementation
                    // accesses that header and we want to catch any exceptions calling TryComputeLength here.

                    if (response.Content == null || await ComputeContentLengthAsync(request, response, httpResponse, cancellationToken))
                    {
                        var bufferOutput = _bufferPolicySelector.UseBufferedOutputStream(response);

                        if (!bufferOutput)
                        {
                            var responseBodyFeature = httpContext.Features.Get <IHttpResponseBodyFeature>();
                            responseBodyFeature?.DisableBuffering();
                        }
                        else if (response.Content != null)
                        {
                            response = await BufferResponseContentAsync(request, response, cancellationToken);
                        }

                        if (await PrepareHeadersAsync(request, response, httpResponse, cancellationToken))
                        {
                            await SendResponseMessageAsync(request, response, httpContext, cancellationToken);
                        }
                    }
                }
            }
            finally
            {
                request.DisposeRequestResources();
                request.Dispose();
                if (response != null)
                {
                    response.Dispose();
                }
            }

            // Call the next component if no route matched
            if (callNext)
            {
                await _next(httpContext);
            }
        }
        public override async Task Invoke(IOwinContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            IOwinRequest  owinRequest  = context.Request;
            IOwinResponse owinResponse = context.Response;

            if (owinRequest == null)
            {
                throw new InvalidOperationException();
            }
            if (owinResponse == null)
            {
                throw new InvalidOperationException();
            }

            HttpRequestMessage request = CreateRequestMessage(owinRequest);

            MapRequestProperties(request, context);

            if (!owinRequest.Body.CanSeek && _bufferPolicySelector.UseBufferedInputStream(hostContext: context))
            {
                await BufferRequestBodyAsync(owinRequest, request.Content);
            }

            SetPrincipal(owinRequest.User);

            HttpResponseMessage response = null;
            bool callNext = false;

            try
            {
                response = await _messageInvoker.SendAsync(request, owinRequest.CallCancelled);

                // Handle null responses
                if (response == null)
                {
                    throw new InvalidOperationException();
                }

                if (_callNextPolicy(request, response))
                {
                    callNext = true;
                }
                else
                {
                    if (response.Content != null && _bufferPolicySelector.UseBufferedOutputStream(response))
                    {
                        response = await BufferResponseBodyAsync(request, response);
                    }

                    FixUpContentLengthHeaders(response);
                    await SendResponseMessageAsync(response, owinResponse);
                }
            }
            finally
            {
                // Note that the HttpRequestMessage is explicitly NOT disposed.  Disposing it would close the input stream
                // and prevent cascaded components from accessing it.  The server MUST handle any necessary cleanup upon
                // request completion.
                request.DisposeRequestResources();
                if (response != null)
                {
                    response.Dispose();
                }
            }

            // Call the next component if no route matched
            if (callNext && Next != null)
            {
                await Next.Invoke(context);
            }
        }
        private async Task InvokeCore(IOwinContext context, IOwinRequest owinRequest,
                                      IOwinResponse owinResponse)
        {
            CancellationToken cancellationToken = owinRequest.CallCancelled;
            HttpContent       requestContent;

            if (!owinRequest.Body.CanSeek && _bufferPolicySelector.UseBufferedInputStream(hostContext: context))
            {
                requestContent = await CreateBufferedRequestContentAsync(owinRequest, cancellationToken);
            }
            else
            {
                requestContent = CreateStreamedRequestContent(owinRequest);
            }

            HttpRequestMessage request = CreateRequestMessage(owinRequest, requestContent);

            MapRequestProperties(request, context);

            SetPrincipal(owinRequest.User);

            HttpResponseMessage response = null;
            bool callNext;

            try
            {
                response = await _messageInvoker.SendAsync(request, cancellationToken);

                // Handle null responses
                if (response == null)
                {
                    throw Error.InvalidOperation(OwinResources.SendAsync_ReturnedNull);
                }

                // Handle soft 404s where no route matched - call the next component
                if (IsSoftNotFound(request, response))
                {
                    callNext = true;
                }
                else
                {
                    callNext = false;

                    if (response.Content != null && _bufferPolicySelector.UseBufferedOutputStream(response))
                    {
                        response = await BufferResponseContentAsync(request, response, cancellationToken);
                    }

                    FixUpContentLengthHeaders(response);
                    await SendResponseMessageAsync(request, response, owinResponse, cancellationToken);
                }
            }
            finally
            {
                request.DisposeRequestResources();
                request.Dispose();
                if (response != null)
                {
                    response.Dispose();
                }
            }

            // Call the next component if no route matched
            if (callNext && Next != null)
            {
                await Next.Invoke(context);
            }
        }
        private async Task InvokeCore(
            IOwinContext context,
            IOwinRequest owinRequest,
            IOwinResponse owinResponse
            )
        {
            CancellationToken cancellationToken = owinRequest.CallCancelled;
            HttpContent       requestContent;

            bool bufferInput = _bufferPolicySelector.UseBufferedInputStream(hostContext: context);

            if (!bufferInput)
            {
                owinRequest.DisableBuffering();
            }

            if (!owinRequest.Body.CanSeek && bufferInput)
            {
                requestContent = await CreateBufferedRequestContentAsync(
                    owinRequest,
                    cancellationToken
                    );
            }
            else
            {
                requestContent = CreateStreamedRequestContent(owinRequest);
            }

            HttpRequestMessage request = CreateRequestMessage(owinRequest, requestContent);

            MapRequestProperties(request, context);

            SetPrincipal(owinRequest.User);

            HttpResponseMessage response = null;
            bool callNext;

            try
            {
                response = await _messageInvoker.SendAsync(request, cancellationToken);

                // Handle null responses
                if (response == null)
                {
                    throw Error.InvalidOperation(OwinResources.SendAsync_ReturnedNull);
                }

                // Handle soft 404s where no route matched - call the next component
                if (IsSoftNotFound(request, response))
                {
                    callNext = true;
                }
                else
                {
                    callNext = false;

                    // Compute Content-Length before calling UseBufferedOutputStream because the default implementation
                    // accesses that header and we want to catch any exceptions calling TryComputeLength here.

                    if (
                        response.Content == null ||
                        await ComputeContentLengthAsync(
                            request,
                            response,
                            owinResponse,
                            cancellationToken
                            )
                        )
                    {
                        bool bufferOutput = _bufferPolicySelector.UseBufferedOutputStream(response);

                        if (!bufferOutput)
                        {
                            owinResponse.DisableBuffering();
                        }
                        else if (response.Content != null)
                        {
                            response = await BufferResponseContentAsync(
                                request,
                                response,
                                cancellationToken
                                );
                        }

                        if (
                            await PrepareHeadersAsync(
                                request,
                                response,
                                owinResponse,
                                cancellationToken
                                )
                            )
                        {
                            await SendResponseMessageAsync(
                                request,
                                response,
                                owinResponse,
                                cancellationToken
                                );
                        }
                    }
                }
            }
            finally
            {
                request.DisposeRequestResources();
                request.Dispose();
                if (response != null)
                {
                    response.Dispose();
                }
            }

            // Call the next component if no route matched
            if (callNext && Next != null)
            {
                await Next.Invoke(context);
            }
        }
Пример #5
0
        public async Task Invoke(IDictionary <string, object> environment)
        {
            if (environment == null)
            {
                throw new ArgumentNullException("environment");
            }

            Stream             requestBody = environment.GetOwinValue <Stream>(OwinConstants.RequestBodyKey);
            HttpRequestMessage request     = CreateRequestMessage(environment, requestBody);

            if (!requestBody.CanSeek && _bufferPolicySelector.UseBufferedInputStream(hostContext: environment))
            {
                await BufferRequestBodyAsync(environment, request.Content);
            }
            CancellationToken cancellationToken = environment.GetOwinValue <CancellationToken>(OwinConstants.CallCancelledKey);

            SetPrincipal(environment);

            HttpResponseMessage response = null;
            bool callNext = false;

            try
            {
                response = await _messageInvoker.SendAsync(request, cancellationToken);

                // Handle null responses
                if (response == null)
                {
                    throw Error.InvalidOperation(SRResources.SendAsync_ReturnedNull);
                }

                // Handle soft 404s where no route matched - call the next component
                if (IsSoftNotFound(request, response))
                {
                    callNext = true;
                }
                else
                {
                    if (response.Content != null && _bufferPolicySelector.UseBufferedOutputStream(response))
                    {
                        response = await BufferResponseBodyAsync(request, response);
                    }

                    await SendResponseMessageAsync(environment, response);
                }
            }
            finally
            {
                // Note that the HttpRequestMessage is explicitly NOT disposed.  Disposing it would close the input stream
                // and prevent cascaded components from accessing it.  The server MUST handle any necessary cleanup upon
                // request completion.
                request.DisposeRequestResources();
                if (response != null)
                {
                    response.Dispose();
                }
            }

            // Call the next component if no route matched
            if (callNext)
            {
                await _next.Invoke(environment);
            }
        }