/// <summary> /// Handles the Http Connecting client and processes the HttpResponse /// </summary> private static void ProcessRequest(HttpClient Client) { // Update connection count Interlocked.Increment(ref SessionRequests); // Make sure request method is supported if (!AcceptableMethods.Contains(Client.Request.HttpMethod)) { Client.Response.StatusCode = (int)HttpStatusCode.MethodNotAllowed; Client.Response.Send(); return; } // Process Request try { // Get our requested document string Document = Client.Request.Url.AbsolutePath.ToLower().TrimStart(new char[] { '/' }); ; if (Document.StartsWith("asp")) { // Get our requested document's Controller ASPController Controller = GetASPController(Client, Path.GetFileName(Document)); if (Controller != null) // The controller will take over from here and process the response Controller.HandleRequest(); else // Send a 404 if we dont have a controller for this request Client.Response.StatusCode = (int)HttpStatusCode.NotFound; } else if (!Program.Config.BF2S_Enabled) // If we dont have BF2S enabled, deny page access { // Set service is unavialable Client.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable; Client.Response.Send(); } else // Bf2sClone { // Remove bf2stats folder and trim out the forward slashes Document = Document.Replace("bf2stats", "").Trim(new char[] { '/' }); if (String.IsNullOrWhiteSpace(Document)) Document = "index"; // If the document has an extension, we are loading a resource (js, css, jpg) instead of a page if (Path.HasExtension(Document)) { // First we get the relative path with no empty entries. Path.Combine also checks for invalid characters string RelaPath = Path.Combine(Document.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries)); string FullPath = Path.Combine(Program.RootPath, "Web", "Bf2Stats", "Resources", RelaPath); if (File.Exists(FullPath)) { // Set the content type based from our extension string Ext = Path.GetExtension(RelaPath).TrimStart('.'); if (MIMETypes.ContainsKey(Ext)) Client.Response.ContentType = MIMETypes[Ext]; // Send response Client.Response.Send(File.ReadAllBytes(FullPath)); } else { // Resource doesn't exist Client.Response.StatusCode = (int)HttpStatusCode.NotFound; } } else { // Convert our document path into an MvC route MvcRoute Route = new MvcRoute(Document); // Try and fetch the controller, and handle the request Controller Cont = GetBf2StatsController(Route.Controller, Client); if (Cont != null) { // We let the Controller handle the request from here Cont.HandleRequest(Route); } // Check the Razor engine to see if we have this template compiled... else if (Engine.Razor.IsTemplateCached(Route.Controller + ".cshtml", ModelType)) { // Custom made template with No Controller Client.Response.ContentType = "text/html"; Client.Response.ResponseBody.Append( Engine.Razor.Run(Route.Controller + ".cshtml", ModelType, new IndexModel(Client)) ); } else { // Show 404 Client.Response.StatusCode = (int)HttpStatusCode.NotFound; } } } } catch (DbConnectException e) { string message = e.InnerException?.Message ?? e.Message; Program.ErrorLog.Write("WARNING: [HttpServer.ProcessRequest] Unable to connect to database: " + message); // Set service is unavialable Client.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable; Client.Response.Send(); } catch (Exception e) { Program.ErrorLog.Write("ERROR: [HttpServer.ProcessRequest] " + e.Message); ExceptionHandler.GenerateExceptionLog(e); if (!Client.ResponseSent) { // Internal service error Client.Response.StatusCode = (int)HttpStatusCode.InternalServerError; Client.Response.Send(); } } finally { // Make sure a response is sent to prevent client hang if (!Client.ResponseSent) Client.Response.Send(); // Open a connection ConnectionPool.Release(); // Fire this last! RequestRecieved(); } }
/// <summary> /// Handles the Http Connecting client and processes the HttpResponse /// </summary> private static void ProcessRequest(HttpClient Client) { // Update connection count Interlocked.Increment(ref SessionRequests); // Make sure request method is supported if (!AcceptableMethods.Contains(Client.Request.HttpMethod)) { Client.Response.StatusCode = (int)HttpStatusCode.MethodNotAllowed; Client.Response.Send(); return; } // Process Request try { // Get our requested document string Document = Client.Request.Url.AbsolutePath.ToLower().TrimStart(new char[] { '/' });; if (Document.StartsWith("asp")) { // Get our requested document's Controller ASPController Controller = GetASPController(Client, Path.GetFileName(Document)); if (Controller != null) { // The controller will take over from here and process the response Controller.HandleRequest(); } else { // Send a 404 if we dont have a controller for this request Client.Response.StatusCode = (int)HttpStatusCode.NotFound; } } else if (!Program.Config.BF2S_Enabled) // If we dont have BF2S enabled, deny page access { // Set service is unavialable Client.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable; Client.Response.Send(); } else // Bf2sClone { // Remove bf2stats folder and trim out the forward slashes Document = Document.Replace("bf2stats", "").Trim(new char[] { '/' }); if (String.IsNullOrWhiteSpace(Document)) { Document = "index"; } // If the document has an extension, we are loading a resource (js, css, jpg) instead of a page if (Path.HasExtension(Document)) { // First we get the relative path with no empty entries. Path.Combine also checks for invalid characters string RelaPath = Path.Combine(Document.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries)); string FullPath = Path.Combine(Program.RootPath, "Web", "Bf2Stats", "Resources", RelaPath); if (File.Exists(FullPath)) { // Set the content type based from our extension string Ext = Path.GetExtension(RelaPath).TrimStart('.'); if (MIMETypes.ContainsKey(Ext)) { Client.Response.ContentType = MIMETypes[Ext]; } // Send response Client.Response.Send(File.ReadAllBytes(FullPath)); } else { // Resource doesn't exist Client.Response.StatusCode = (int)HttpStatusCode.NotFound; } } else { // Convert our document path into an MvC route MvcRoute Route = new MvcRoute(Document); // Try and fetch the controller, and handle the request Controller Cont = GetBf2StatsController(Route.Controller, Client); if (Cont != null) { // We let the Controller handle the request from here Cont.HandleRequest(Route); } // Check the Razor engine to see if we have this template compiled... else if (Engine.Razor.IsTemplateCached(Route.Controller + ".cshtml", ModelType)) { // Custom made template with No Controller Client.Response.ContentType = "text/html"; Client.Response.ResponseBody.Append( Engine.Razor.Run(Route.Controller + ".cshtml", ModelType, new IndexModel(Client)) ); } else { // Show 404 Client.Response.StatusCode = (int)HttpStatusCode.NotFound; } } } } catch (DbConnectException e) { string message = e.InnerException?.Message ?? e.Message; Program.ErrorLog.Write("WARNING: [HttpServer.ProcessRequest] Unable to connect to database: " + message); // Set service is unavialable Client.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable; Client.Response.Send(); } catch (Exception e) { Program.ErrorLog.Write("ERROR: [HttpServer.ProcessRequest] " + e.Message); ExceptionHandler.GenerateExceptionLog(e); if (!Client.ResponseSent) { // Internal service error Client.Response.StatusCode = (int)HttpStatusCode.InternalServerError; Client.Response.Send(); } } finally { // Make sure a response is sent to prevent client hang if (!Client.ResponseSent) { Client.Response.Send(); } // Open a connection ConnectionPool.Release(); // Fire this last! RequestRecieved(); } }