public async Task ProcessRequest_With503Fallback_Returns503() { var handler = new FallbackResponseHandler(FallbackResponse.Http503ServiceUnavailable); var context = new MockHttpContext(); await handler.ProcessRequest(context); Assert.AreEqual(503, context.Response.StatusCode); Assert.AreEqual(HttpStatusCodes.GetStatusDescription(503), context.Response.StatusDescription); }
public async Task ProcessRequest_With404Fallback_Returns404() { var handler = new FallbackResponseHandler(FallbackResponse.Http404NotFound); var context = new MockHttpContext(); await handler.ProcessRequest(context); Assert.AreEqual(404, context.Response.StatusCode); Assert.AreEqual(HttpStatusCodes.GetStatusDescription(404), context.Response.StatusDescription); }
/// <summary> /// Processes an incoming HTTP request. /// </summary> /// <param name="context">The <see cref="IStumpsHttpContext" /> representing both the incoming request and the response.</param> /// <returns> /// A member of the <see cref="ProcessHandlerResult" /> enumeration. /// </returns> /// <exception cref="ArgumentNullException"><paramref name="context"/> is <c>null</c>.</exception> public async Task <ProcessHandlerResult> ProcessRequest(IStumpsHttpContext context) { context = context ?? throw new ArgumentNullException(nameof(context)); var remoteUrl = BuildRemoteUrlFromContext(context); // Create a new HTTP web request var remoteWebRequest = (HttpWebRequest)WebRequest.Create(remoteUrl); remoteWebRequest.AllowAutoRedirect = false; // Populate the headers for the new HTTP request from the incoming HTTP request PopulateRemoteHeadersFromContext(context, remoteWebRequest); // Populate the HTTP body for the request var webResponseResult = await PopulateRemoteBodyFromContext(context, remoteWebRequest); var continueProcess = webResponseResult.Success; // Execute the remote web request if (continueProcess) { await ExecuteRemoteWebRequest(remoteWebRequest, webResponseResult); } if (!continueProcess) { // Return a response to the client that the service is unavailable at this time. context.Response.StatusCode = HttpStatusCodes.HttpServiceUnavailable; context.Response.StatusDescription = HttpStatusCodes.GetStatusDescription(HttpStatusCodes.HttpServiceUnavailable); } else if (webResponseResult.Response != null) { // Write the headers and the body of the response from the remote HTTP request // to the incoming HTTP context. WriteContextHeadersFromResponse(context, webResponseResult.Response); await WriteContextBodyFromRemoteResponse(context, webResponseResult.Response); context.Response.StatusCode = (int)webResponseResult.Response.StatusCode; context.Response.StatusDescription = webResponseResult.Response.StatusDescription; var disposable = webResponseResult.Response as IDisposable; disposable.Dispose(); } if (context.Response is StumpsHttpResponse stumpsResponse) { stumpsResponse.Origin = HttpResponseOrigin.RemoteServer; } this.ContextProcessed?.Invoke(this, new StumpsContextEventArgs(context)); return(await Task.FromResult <ProcessHandlerResult>(ProcessHandlerResult.Continue)); }
/// <summary> /// Initializes a new instance of the <see cref="FallbackResponseHandler"/> class. /// </summary> /// <param name="response">The default response.</param> /// <exception cref="ArgumentOutOfRangeException"><paramref name="response"/> is <c>null</c>.</exception> public FallbackResponseHandler(FallbackResponse response) { if (!Enum.IsDefined(typeof(FallbackResponse), response)) { throw new ArgumentOutOfRangeException(nameof(response)); } // Fallback to 503 Service Unavailable when undefined response = response == FallbackResponse.Undefined ? FallbackResponse.Http503ServiceUnavailable : response; _statusCode = (int)response; _statusCodeDescription = HttpStatusCodes.GetStatusDescription(_statusCode); _origin = response == FallbackResponse.Http404NotFound ? HttpResponseOrigin.NotFoundResponse : HttpResponseOrigin.ServiceUnavailable; }