private static Task <bool> ValidateHttpOptions(string methods, HttpListenerContext context, IEnumerable <string> validMethods) { var currentMethod = context.RequestHeader(Headers.AccessControlRequestMethod); var currentHeader = context.RequestHeader(Headers.AccessControlRequestHeaders); if (!string.IsNullOrWhiteSpace(currentHeader)) { context.Response.Headers.Add(Headers.AccessControlAllowHeaders + currentHeader); } if (string.IsNullOrWhiteSpace(currentMethod)) { return(Task.FromResult(true)); } var currentMethods = currentMethod.ToLowerInvariant().Split(Strings.CommaSplitChar, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()); if (methods == Strings.CorsWildcard || currentMethods.All(validMethods.Contains)) { context.Response.Headers.Add(Headers.AccessControlAllowMethods + currentMethod); return(Task.FromResult(true)); } context.Response.StatusCode = (int)HttpStatusCode.BadRequest; return(Task.FromResult(false)); }
/// <summary> /// Process HttpListener Request and returns true if it was handled. /// </summary> /// <param name="context">The HttpListenerContext.</param> /// <param name="ct">The cancellation token.</param> /// <returns>True if it was handled; otherwise, false.</returns> public async Task <bool> ProcessRequest(HttpListenerContext context, CancellationToken ct) { // Iterate though the loaded modules to match up a request and possibly generate a response. foreach (var module in Modules) { var handler = GetHandler(context, module); if (handler?.ResponseHandler == null) { continue; } // Establish the callback var callback = handler.ResponseHandler; try { // Inject the Server property of the module via reflection if not already there. (mini IoC ;)) module.Server = module.Server ?? this; // Log the module and handler to be called and invoke as a callback. $"{module.Name}::{callback.GetMethodInfo().DeclaringType?.Name}.{callback.GetMethodInfo().Name}".Debug(nameof(WebServer)); // Execute the callback var handleResult = await callback(context, ct); $"Result: {handleResult}".Trace(nameof(WebServer)); // callbacks can instruct the server to stop bubbling the request through the rest of the modules by returning true; if (handleResult) { return(true); } } catch (Exception ex) { // Handle exceptions by returning a 500 (Internal Server Error) if (context.Response.StatusCode != (int)HttpStatusCode.Unauthorized) { var errorMessage = ex.ExceptionMessage($"Failing module name: {module.Name}"); // Log the exception message. ex.Log(nameof(WebServer), $"Failing module name: {module.Name}"); // Send the response over with the corresponding status code. await context.HtmlResponseAsync(WebUtility.HtmlEncode(string.Format(Responses.Response500HtmlFormat, errorMessage, ex.StackTrace)), HttpStatusCode.InternalServerError, ct); } // Finally set the handled flag to true and exit. return(true); } } return(false); }