public static async Task <HttpContext> ActionHandler(HttpContext context, Func <Task> next) { CultureInfo newCulture = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone(); newCulture.DateTimeFormat.ShortDatePattern = "dd-MMM-yyyy"; newCulture.NumberFormat.CurrencyDecimalSeparator = "."; newCulture.NumberFormat.NumberDecimalSeparator = "."; newCulture.DateTimeFormat.LongDatePattern = "dd-MMM-yyyy"; newCulture.DateTimeFormat.DateSeparator = "-"; Thread.CurrentThread.CurrentCulture = newCulture; Thread.CurrentThread.CurrentUICulture = newCulture; var origin = context.Request.Headers.ContainsKey(Origin) ? context.Request.Headers[Origin].First() : ""; //var origin = context.Request.Headers.ContainsKey(Origin) ? context.Request.Headers[Origin] : ""; var request = context.Request; var response = context.Response; var path = request.Path.Value.ToLower(); var queryString = request.QueryString.Value; var pathAndQuery = path + queryString; var activeAction = new ActiveAction() { startDate = DateTime.Now, pathAndQuery = pathAndQuery, guid = Guid.NewGuid().ToString() }; // HangPreventorManager.AddAction(activeAction); response.Headers.Append("Cache-Control", "No-Cache"); //System.Threading.Thread.Sleep(1000); var requestContentStr = ""; using (var reader = new StreamReader(request.Body)) { requestContentStr = await reader.ReadToEndAsync(); } activeAction.AddEvent("Request body read"); try { #region Cors Support if (request.Headers != null && 1 == 2) { var isCorsRequest = request.Headers.ContainsKey(Origin); var isPreflightRequest = String.Equals(request.Method, OptionsMethod, StringComparison.InvariantCultureIgnoreCase); if (isCorsRequest) { if (isPreflightRequest) { response.StatusCode = 200; if (!String.IsNullOrEmpty(origin) && !response.Headers.ContainsKey(AccessControlAllowOrigin)) { response.Headers.Append(AccessControlAllowOrigin, origin); } ; //var accessControlRequestMethod = request.Headers.ContainsKey(AccessControlRequestMethod) ? request.Headers[AccessControlRequestMethod] : ""; //request.Headers[AccessControlRequestMethod].FirstOrDefault(); var accessControlRequestMethod = request.Headers.ContainsKey(AccessControlRequestMethod) ? request.Headers[AccessControlRequestMethod].FirstOrDefault() : ""; if (accessControlRequestMethod != null) { response.Headers.Append(AccessControlAllowMethods, accessControlRequestMethod); } var requestedHeaders = string.Join(", ", request.Headers[AccessControlRequestHeaders]); if (!string.IsNullOrEmpty(requestedHeaders)) { response.Headers.Append(AccessControlAllowHeaders, requestedHeaders); } response.Headers.Append(AccessControlAllowCredentials, "true"); return(context); } if (!String.IsNullOrEmpty(origin) && !response.Headers.ContainsKey(AccessControlAllowOrigin)) { response.Headers.Append(AccessControlAllowOrigin, origin); } response.Headers.Append(AccessControlAllowHeaders, "*"); response.Headers.Append(AccessControlAllowCredentials, "true"); } } #endregion var primaryAccept = "*/*"; if (request.Headers.ContainsKey("Accept")) { //var acceptedHeaders = request.Headers.ContainsKey("Accept") ? new List<string>().ToArray() : request.Headers["Accept"].ToList(.Split(','); var acceptedHeaders = request.Headers["Accept"].First().Split(','); //request.Headers.Accept.ToList().Select(a => a.ToString()); primaryAccept = acceptedHeaders.FirstOrDefault(); foreach (var accept in acceptedHeaders) { if (accept.ToLower().Contains("json")) { primaryAccept = accept; break; } } } activeAction.AddEvent("Request body read"); pathAndQuery = WebUtility.UrlDecode(pathAndQuery); //var isMvcRequest = pathAndQuery == "/" || pathAndQuery.StartsWith("/ui/") || pathAndQuery.StartsWith("ui/"); //var requestContentStr = StreamToString(request.Body); try { var routeRestult = await RouteRequest(response, pathAndQuery, request.Method, requestContentStr, primaryAccept, null, null, request, activeAction); activeAction.AddEvent("Route Request Success End"); if (routeRestult == false) { await next(); activeAction.AddEvent("Successful"); return(context); } } catch (Exception routeException) { activeAction.AddEvent("Fail: " + routeException.Message); response.StatusCode = 200; if (!String.IsNullOrEmpty(origin)) { response.Headers.Append(AccessControlAllowOrigin, origin); } response.Headers.Append("Content-Type", "application/json"); await response.WriteAsync($"{{\"ex\":\"Route Exception : {routeException.Message} \"}}"); return(context); } return(context); } catch (Exception ex) { var errorBody = requestContentStr; context.Response.StatusCode = 200; if (!String.IsNullOrEmpty(origin)) { context.Response.Headers.Append(AccessControlAllowOrigin, origin); } //response.Headers.Append("Content-Type", "application/json"); await context.Response.WriteAsync($"{{\"ex\":\"ActionDelegator Exception: {ex.Message} \"}}" + ": Body: " + errorBody); return(context); } }
public static async Task <bool> RouteRequest(HttpResponse httpResponse, string requestPath, string requestMethod, string requestContentStr, string accepts, string user, string token, HttpRequest request = null, ActiveAction action = null) { if (accepts == null) { accepts = "*/*"; } if (requestPath.StartsWith("/")) { requestPath = requestPath.Substring(1); } var path = requestPath; var query = ""; if (path.Contains("?")) { path = requestPath.Substring(0, requestPath.IndexOf("?")); query = requestPath.Substring(requestPath.IndexOf("?")); } ; //check for any pre-defined routes ActionRoute route = null; if (routes.ContainsKey(path)) { route = routes[path]; requestPath = route.replacement + query; } else { //default to files if no function path if (!requestPath.StartsWith("s/") && !requestPath.StartsWith("q/") && !requestPath.StartsWith("ui/") && !requestPath.StartsWith("f/") && !requestPath.StartsWith("c/")) { if (requestPath.Contains(".")) { requestPath = "f/" + requestPath; } else { requestPath = "f/index.html"; } } } var isFileRequest = requestPath.StartsWith("f/"); var function = requestPath.Substring(0, requestPath.IndexOf("/")); var serviceName = requestPath.Substring(function.Length + 1); var parameters = ""; if (serviceName.Contains("?")) { var questionIndex = serviceName.IndexOf("?"); parameters = serviceName.Substring(questionIndex + 1); serviceName = serviceName.Substring(0, questionIndex); } if (isFileRequest == false && user == null && route?.anonymous == false) { var reqPath = request.Path.ToUriComponent(); if (reqPath.Contains("?")) { reqPath = reqPath.Substring(0, reqPath.IndexOf("?")); } var redirectResponse = new HttpResponseMessage(HttpStatusCode.OK) { StatusCode = HttpStatusCode.Moved }; var redirPath = "http://" + request.Host.Value + "/login?r=" + reqPath; httpResponse.Redirect(redirPath); return(true); } var routeRequest = new RouteRequest(); routeRequest.contentStr = requestContentStr; routeRequest.fullUrl = requestPath; routeRequest.parameters = parameters; routeRequest.hostName = ""; routeRequest.user = user; routeRequest.function = function; routeRequest.service = serviceName; routeRequest.httpRequest = request; routeRequest.action = action; routeRequest.token = token; var result = await RouteManager.Process(function, serviceName, routeRequest); action.AddEvent("Route Processed"); if (result == null) { result = ""; } //if (result != null) //if (result.GetType() != typeof(RequestError)) //{ var resultStr = ""; if (routeRequest.responseContentType != "") { accepts = routeRequest.responseContentType; } if (requestPath.Contains("plugins/cordova")) { accepts = "application/javascript"; } var returnType = ""; if (result is CommandResponse) { var commandResponse = ((CommandResponse)result); httpResponse.StatusCode = commandResponse.Status; if (!String.IsNullOrEmpty(request?.ContentType)) { accepts = request.ContentType; } if (request.Headers.ContainsKey("Accept")) { var firstHeader = request.Headers["Accept"].FirstOrDefault(); if (firstHeader == null) { firstHeader = ""; } if (firstHeader.Split(',')[0] != "*/*") { returnType = request.Headers["Accept"].First().Split(',')[0]; } if (accepts != "*/*") { returnType = accepts; } } if (commandResponse.ContentType != "") { returnType = commandResponse.ContentType; } if (returnType == "") { returnType = "application/json"; } httpResponse.Headers.Append("Content-Type", returnType); foreach (var header in commandResponse.Headers) { httpResponse.Headers.Append(header.Key, header.Value); } if (commandResponse.Bytes != null) { var bytes = commandResponse.Bytes.ToArray(); await httpResponse.Body.WriteAsync(bytes, 0, bytes.Length); } else if (!String.IsNullOrWhiteSpace(commandResponse.Content)) { await httpResponse.WriteAsync(commandResponse.Content); } else if (commandResponse.value is MemoryStream) { var bytes = ((MemoryStream)commandResponse.value).ToArray(); await httpResponse.Body.WriteAsync(bytes, 0, bytes.Length); } else { await httpResponse.WriteAsync(commandResponse.value == null? "" : commandResponse.value.ToString()); } return(true); } //else if (result is IEntity) resultStr = ((IEntity)result).ToJson(); else { try { resultStr = JsonManager.Serialize(result); } catch (Exception ex) { var resultType = result == null ? "null" : result.GetType().ToString(); resultStr = $"Error with serialization of type {resultType}. {ex.Message} "; } } if (request.Headers.ContainsKey("Accept")) { var firstHeader = request.Headers["Accept"].FirstOrDefault(); if (firstHeader == null) { firstHeader = ""; } if (firstHeader.Split(',')[0] != "*/*") { returnType = request.Headers["Accept"].First().Split(',')[0]; } if (accepts != "*/*") { returnType = accepts; } } if (returnType == "") { returnType = "application/json"; } var writeStart = DateTime.Now; resultStr = resultStr == null ? "" : resultStr; httpResponse.StatusCode = 200; httpResponse.Headers.Append("Content-Type", returnType); await httpResponse.WriteAsync(resultStr); //log the write time TotalWriteMs += (DateTime.Now - writeStart).TotalMilliseconds; TotalBytesSent += resultStr.Length * 2; TotalRequests++; // if (TotalRequests >= 1000) { TotalWriteMs = 0; TotalBytesSent = 0; TotalRequests = 0; } //response.Content.Headers.ContentType = new MediaTypeHeaderValue(returnType); return(true); //} //return false; }