public async Task SendAsync_SetsRequestBackedRequestContextOnRequest_WhenRequestRequestContextIsNull()
        {
            // Arrange
            using (HttpConfiguration configuration = new HttpConfiguration())
                using (HttpControllerDispatcher dispatcher = new HttpControllerDispatcher(configuration))
                    using (HttpMessageInvoker invoker = new HttpMessageInvoker(dispatcher))
                        using (HttpRequestMessage request = new HttpRequestMessage())
                        {
                            Mock <IHttpController> controllerMock = new Mock <IHttpController>();
                            HttpRequestContext     requestContext = null;
                            controllerMock
                            .Setup(c => c.ExecuteAsync(It.IsAny <HttpControllerContext>(), CancellationToken.None))
                            .Callback <HttpControllerContext, CancellationToken>((c, t) =>
                            {
                                requestContext = request.GetRequestContext();
                            });
                            Mock <HttpControllerDescriptor> controllerDescriptorMock = new Mock <HttpControllerDescriptor>();
                            controllerDescriptorMock.Setup(d => d.CreateController(request)).Returns(controllerMock.Object);
                            HttpControllerDescriptor controllerDescriptor = controllerDescriptorMock.Object;
                            controllerDescriptor.Configuration = configuration;
                            Mock <IHttpControllerSelector> controllerSelectorMock = new Mock <IHttpControllerSelector>();
                            controllerSelectorMock.Setup(s => s.SelectController(request)).Returns(controllerDescriptor);
                            configuration.Services.Replace(typeof(IHttpControllerSelector), controllerSelectorMock.Object);

                            request.SetRouteData(new Mock <IHttpRouteData>(MockBehavior.Strict).Object);

                            // Act
                            HttpResponseMessage ignore = await invoker.SendAsync(request, CancellationToken.None);

                            // Assert
                            RequestBackedHttpRequestContext typedRequestContext = Assert.IsType <RequestBackedHttpRequestContext>(requestContext);
                            Assert.Same(request, typedRequestContext.Request);
                            Assert.Same(configuration, typedRequestContext.Configuration);
                        }
        }
Esempio n. 2
0
        private static HttpControllerContext CreateControllerContext(
            HttpRequestMessage request,
            HttpControllerDescriptor controllerDescriptor,
            IHttpController controller
            )
        {
            Contract.Assert(request != null);
            Contract.Assert(controllerDescriptor != null);
            Contract.Assert(controller != null);

            HttpConfiguration controllerConfiguration = controllerDescriptor.Configuration;

            // Set the controller configuration on the request properties
            HttpConfiguration requestConfig = request.GetConfiguration();

            if (requestConfig == null)
            {
                request.SetConfiguration(controllerConfiguration);
            }
            else
            {
                if (requestConfig != controllerConfiguration)
                {
                    request.SetConfiguration(controllerConfiguration);
                }
            }

            HttpRequestContext requestContext = request.GetRequestContext();

            // if the host doesn't create the context we will fallback to creating it.
            if (requestContext == null)
            {
                requestContext = new RequestBackedHttpRequestContext(request)
                {
                    // we are caching controller configuration to support per controller configuration.
                    Configuration = controllerConfiguration,
                };

                // if the host did not set a request context we will also set it back to the request.
                request.SetRequestContext(requestContext);
            }

            return(new HttpControllerContext(
                       requestContext,
                       request,
                       controllerDescriptor,
                       controller
                       ));
        }
Esempio n. 3
0
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            if (_disposed)
            {
                return(request.CreateErrorResponse(HttpStatusCode.ServiceUnavailable, SRResources.HttpServerDisposed));
            }

            // The first request initializes the server
            EnsureInitialized();

            // Capture current synchronization context and add it as a parameter to the request
            SynchronizationContext context = SynchronizationContext.Current;

            if (context != null)
            {
                request.SetSynchronizationContext(context);
            }

            // Add HttpConfiguration object as a parameter to the request
            request.SetConfiguration(_configuration);

            // Ensure we have a principal, even if the host didn't give us one
            IPrincipal originalPrincipal = Thread.CurrentPrincipal;

            if (originalPrincipal == null)
            {
                Thread.CurrentPrincipal = _anonymousPrincipal;
            }

            // Ensure we have a principal on the request context (if there is a request context).
            HttpRequestContext requestContext = request.GetRequestContext();

            if (requestContext == null)
            {
                requestContext = new RequestBackedHttpRequestContext(request);

                // if the host did not set a request context we will also set it back to the request.
                request.SetRequestContext(requestContext);
            }

            // we need this for the case where the context was set outside of HttpServer, but principal was not assigned.
            // HttpLegacyRequestContext already captures the Thread.CurrentPrincipal.
            if (requestContext.Principal == null)
            {
                requestContext.Principal = Thread.CurrentPrincipal;
            }

            try
            {
                return(await base.SendAsync(request, cancellationToken));
            }
            catch (HttpResponseException exception)
            {
                return(exception.Response);
            }
            catch (Exception exception)
            {
                return(request.CreateErrorResponse(HttpStatusCode.InternalServerError, exception));
            }
            finally
            {
                Thread.CurrentPrincipal = originalPrincipal;
            }
        }
Esempio n. 4
0
        private async Task ProcessRequest(MessageContext restbusContext, CancellationToken cancellationToken)
        {
            //NOTE: This method is called on a background thread and must be protected by an outer big-try catch

            try
            {
                if (machineHostName == null)
                {
                    machineHostName = Environment.MachineName;
                }
            }
            catch { }

            HttpRequestMessage  requestMsg;
            HttpResponseMessage responseMsg = null;

            if (!TryGetHttpRequestMessage(restbusContext.Request, appVirtualPath ?? (appVirtualPath = System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath), machineHostName, out requestMsg))
            {
                responseMsg = new HttpResponseMessage(HttpStatusCode.BadRequest)
                {
                    ReasonPhrase = "Bad Request"
                };
            }
            else
            {
                if (disposed)
                {
                    responseMsg = requestMsg.CreateErrorResponse(HttpStatusCode.ServiceUnavailable, "The server is no longer available.");
                }
                else
                {
                    requestHandler.EnsureInitialized();

                    // Add current synchronization context to request parameter
                    SynchronizationContext syncContext = SynchronizationContext.Current;
                    if (syncContext != null)
                    {
                        requestMsg.SetSynchronizationContext(syncContext);
                    }

                    // Add HttpConfiguration to request parameter
                    requestMsg.SetConfiguration(config);

                    // Ensure we have a principal, even if the host didn't give us one
                    IPrincipal originalPrincipal = Thread.CurrentPrincipal;
                    if (originalPrincipal == null)
                    {
                        Thread.CurrentPrincipal = anonymousPrincipal.Value;
                    }

                    // Ensure we have a principal on the request context (if there is a request context).
                    HttpRequestContext requestContext = requestMsg.GetRequestContext();

                    if (requestContext == null)
                    {
                        requestContext = new RequestBackedHttpRequestContext(requestMsg);

                        // if the host did not set a request context we will also set it back to the request.
                        requestMsg.SetRequestContext(requestContext);
                    }

                    try
                    {
                        try
                        {
                            responseMsg = await requestHandler.SendMessageAsync(requestMsg, cancellationToken);
                        }
                        catch (HttpResponseException exception)
                        {
                            responseMsg = exception.Response;
                        }
                        catch (NullReferenceException exception)
                        {
                            // There is a bug in older versions of HttpRoutingDispatcher which causes a null reference exception when
                            // a route could not be found
                            // This bug can be triggered by sending a request for a url that doesn't have a route
                            // This commit fixes the bug https://github.com/ASP-NET-MVC/aspnetwebstack/commit/6a0c03f9e549966a7f806f8b696ec4cb2ec272e6#diff-c89c7bee3d225a037a6d04e8e4447460

                            if (exception.TargetSite != null && exception.TargetSite.DeclaringType != null &&
                                exception.TargetSite.DeclaringType.FullName == "System.Web.Http.Dispatcher.HttpRoutingDispatcher" &&
                                exception.TargetSite.Name == "SendAsync")
                            {
                                //This is the bug, so send a 404 instead

                                const string NoRouteMatchedHttpPropertyKey = "MS_NoRouteMatched";

                                requestMsg.Properties.Add(NoRouteMatchedHttpPropertyKey, true);
                                responseMsg = requestMsg.CreateErrorResponse(
                                    HttpStatusCode.NotFound,
                                    String.Format("No HTTP resource was found that matches the request URI '{0}'.", requestMsg.RequestUri));
                            }
                            else
                            {
                                responseMsg = CreateResponseMessageFromException(exception);
                            }
                        }
                        catch (Exception exception)
                        {
                            responseMsg = CreateResponseMessageFromException(exception);
                        }

                        if (responseMsg == null)
                        {
                            //TODO: Not good, Log this
                            //TODO: derive exception from RestBus.Exceptions class
                            responseMsg = CreateResponseMessageFromException(new ApplicationException("Unable to get response"));
                        }
                    }
                    finally
                    {
                        Thread.CurrentPrincipal = originalPrincipal;
                    }
                }
            }


            //Send Response
            try
            {
                subscriber.SendResponse(restbusContext, CreateResponsePacketFromMessage(responseMsg, subscriber));
            }
            catch
            {
                //TODO: Log SendResponse error
            }
        }
Esempio n. 5
0
        protected override async Task <HttpResponseMessage> SendAsync(
            HttpRequestMessage request,
            CancellationToken cancellationToken
            )
        {
            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            if (_disposed)
            {
                return(request.CreateErrorResponse(
                           HttpStatusCode.ServiceUnavailable,
                           SRResources.HttpServerDisposed
                           ));
            }

            // The first request initializes the server
            EnsureInitialized();

            // Capture current synchronization context and add it as a parameter to the request
            SynchronizationContext context = SynchronizationContext.Current;

            if (context != null)
            {
                request.SetSynchronizationContext(context);
            }

            // Add HttpConfiguration object as a parameter to the request
            request.SetConfiguration(_configuration);

            // Ensure we have a principal, even if the host didn't give us one
            IPrincipal originalPrincipal = Thread.CurrentPrincipal;

            if (originalPrincipal == null)
            {
                Thread.CurrentPrincipal = _anonymousPrincipal;
            }

            // Ensure we have a principal on the request context (if there is a request context).
            HttpRequestContext requestContext = request.GetRequestContext();

            if (requestContext == null)
            {
                requestContext = new RequestBackedHttpRequestContext(request);

                // if the host did not set a request context we will also set it back to the request.
                request.SetRequestContext(requestContext);
            }

            try
            {
                ExceptionDispatchInfo exceptionInfo;

                try
                {
                    return(await base.SendAsync(request, cancellationToken));
                }
                catch (OperationCanceledException)
                {
                    // Propogate the canceled task without calling exception loggers or handlers.
                    throw;
                }
                catch (HttpResponseException exception)
                {
                    return(exception.Response);
                }
                catch (Exception exception)
                {
                    exceptionInfo = ExceptionDispatchInfo.Capture(exception);
                }

                Debug.Assert(exceptionInfo.SourceException != null);

                ExceptionContext exceptionContext = new ExceptionContext(
                    exceptionInfo.SourceException,
                    ExceptionCatchBlocks.HttpServer,
                    request
                    );
                await ExceptionLogger.LogAsync(exceptionContext, cancellationToken);

                HttpResponseMessage response = await ExceptionHandler.HandleAsync(
                    exceptionContext,
                    cancellationToken
                    );

                if (response == null)
                {
                    exceptionInfo.Throw();
                }

                return(response);
            }
            finally
            {
                Thread.CurrentPrincipal = originalPrincipal;
            }
        }
Esempio n. 6
0
        private Task <HttpResponseMessage> SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            IHttpRouteData routeData = request.GetRouteData();

            Contract.Assert(routeData != null);

            HttpControllerDescriptor httpControllerDescriptor = ControllerSelector.SelectController(request);

            if (httpControllerDescriptor == null)
            {
                return(TaskHelpers.FromResult(request.CreateErrorResponse(
                                                  HttpStatusCode.NotFound,
                                                  Error.Format(SRResources.ResourceNotFound, request.RequestUri),
                                                  SRResources.NoControllerSelected)));
            }

            IHttpController httpController = httpControllerDescriptor.CreateController(request);

            if (httpController == null)
            {
                return(TaskHelpers.FromResult(request.CreateErrorResponse(
                                                  HttpStatusCode.NotFound,
                                                  Error.Format(SRResources.ResourceNotFound, request.RequestUri),
                                                  SRResources.NoControllerCreated)));
            }

            HttpConfiguration controllerConfiguration = httpControllerDescriptor.Configuration;

            // Set the controller configuration on the request properties
            HttpConfiguration requestConfig = request.GetConfiguration();

            if (requestConfig == null)
            {
                request.SetConfiguration(controllerConfiguration);
            }
            else
            {
                if (requestConfig != controllerConfiguration)
                {
                    request.SetConfiguration(controllerConfiguration);
                }
            }

            HttpRequestContext requestContext = request.GetRequestContext();

            // if the host doesn't create the context we will fallback to creating it.
            if (requestContext == null)
            {
                requestContext = new RequestBackedHttpRequestContext(request)
                {
                    // we are caching controller configuration to support per controller configuration.
                    Configuration = controllerConfiguration,
                };

                // if the host did not set a request context we will also set it back to the request.
                request.SetRequestContext(requestContext);
            }

            // Create context
            HttpControllerContext controllerContext = new HttpControllerContext(requestContext, request,
                                                                                httpControllerDescriptor, httpController);

            return(httpController.ExecuteAsync(controllerContext, cancellationToken));
        }