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