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); } }
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 )); }
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; } }
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 } }
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; } }
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)); }