namespace Framework.Server
{
using Framework.Config;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
internal class UtilServer
{
public static void Cors()
{
string origin = Context.Request.Headers["Origin"];
if (origin != null)
{
Context.Response.Headers.Add("Access-Control-Allow-Origin", origin); // Prevent browser error: blocked by CORS policy.
Context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
}
}
[ThreadStatic]
public static IApplicationBuilder ApplicationBuilder;
public static IWebHostEnvironment HostingEnvironment
{
get
{
IWebHostEnvironment result = null;
HttpContext context = Context;
if (context != null)
{
result = (IWebHostEnvironment)context.RequestServices.GetService(typeof(IWebHostEnvironment));
}
else
{
if (ApplicationBuilder != null)
{
result = (IWebHostEnvironment)ApplicationBuilder.ApplicationServices.GetService(typeof(IWebHostEnvironment));
}
}
return result;
}
}
///
/// Returns logger. See also file appsettings.json.
///
public static ILogger Logger(string categoryName)
{
var loggerFactory = (ILoggerFactory)Context.RequestServices.GetService(typeof(ILoggerFactory));
var result = loggerFactory.CreateLogger(categoryName);
return (ILogger)result;
}
///
/// Gets Context of web request.
///
public static HttpContext Context
{
get
{
return new HttpContextAccessor().HttpContext; // Not available during startup. See also: method ConfigureServices(); Not available for Cli.
}
}
public static ISession Session
{
get
{
return Context.Session;
}
}
///
/// Returns location of ASP.NET server wwwroot folder.
///
public static string FolderNameContentRoot()
{
return new Uri(HostingEnvironment.ContentRootPath).AbsolutePath + "/";
}
///
/// Returns client request url. For example: "http://localhost:5000/".
///
public static string RequestUrlHost()
{
HttpContext context = Context;
string result = string.Format("{0}://{1}/", context.Request.Scheme, context.Request.Host.Value);
// result = string.Format("{0}://{1}{2}", context.Request.Scheme, context.Request.Host.Value, context.Request.Path); // Returns also path. For example: "http://localhost:5000/config/data.txt"
return result;
}
///
/// Returns client request domain name. For example "localhost". Does not include http, https or port.
///
public static string RequestDomainName()
{
return Context.Request.Host.Host;
}
///
/// Returns html content type.
///
public static string ContentType(string fileName)
{
// ContentType
string fileNameExtension = UtilFramework.FileNameExtension(fileName);
string result; // https://www.sitepoint.com/web-foundations/mime-types-complete-list/
switch (fileNameExtension)
{
case ".html": result = "text/html"; break;
case ".css": result = "text/css"; break;
case ".js": result = "text/javascript"; break;
case ".map": result = "text/plain"; break;
case ".png": result = "image/png"; break;
case ".ico": result = "image/x-icon"; break;
case ".jpg": result = "image/jpeg"; break;
case ".pdf": result = "application/pdf"; break;
case ".json": result = "application/json"; break;
case ".xlsx": result = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; break;
case ".xml": result = "text/xml"; break;
default:
result = "text/plain"; break; // Type not found!
}
return result;
}
///
/// Returns true, if application runs on IIS server. Otherwise it runs from Visual Studio.
///
public static bool IsIssServer
{
get
{
string folderName = UtilFramework.FolderNameGet() + "Application.Server/";
bool result = Directory.Exists(folderName) == false;
return result;
}
}
///
/// Start one universal server for every website.
///
public static void StartUniversalServerAngular()
{
UtilFramework.NodeClose();
var configServer = ConfigServer.Load();
bool isFirst = true; // See also class CommandBuild option --first
foreach (var website in configServer.WebsiteList)
{
string folderNameAngular = UtilFramework.FolderNameParse(website.FolderNameAngular);
if (folderNameAngular != null && !website.FolderNameAngularIsDuplicate)
{
string fileNameServer = UtilFramework.FolderName + "Application.Server/Framework/Application.Website/" + website.FolderNameAngularWebsite + "server/main.js";
if (!File.Exists(fileNameServer))
{
if (isFirst == false)
{
break; // See also
}
throw new Exception(string.Format("File does not exis! Make sure cli command build --client did run. ({0})", fileNameServer));
}
isFirst = false;
ProcessStartInfo info = new ProcessStartInfo
{
WorkingDirectory = UtilFramework.FolderName + "Application.Server/Framework/Application.Website/" + website.FolderNameAngularWebsite + "server/",
FileName = "node.exe"
};
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
info.FileName = "node";
}
info.Arguments = fileNameServer;
info.UseShellExecute = true; // Open additional node window.
info.WindowStyle = ProcessWindowStyle.Minimized; // Show node window minimized.
Environment.SetEnvironmentVariable("PORT", (website.FolderNameAngularPort).ToString());
// Start node with Application.Server/Framework/Application.Website/Website01/server/main.js
Process.Start(info);
}
}
}
///
/// Used to get body of web post.
///
public static async Task StreamToString(Stream stream)
{
string result;
using (var streamReader = new StreamReader(stream))
{
result = await streamReader.ReadToEndAsync();
}
if (result == "")
{
result = null;
}
return result;
}
///
/// Returns true, if request or response path is a FileName. Otherwise path is a FolderName.
///
/// For example "/" or "/main.js"
///
public static bool NavigatePathIsFileName(string navigatePath)
{
return !string.IsNullOrEmpty(Path.GetFileName(navigatePath));
}
///
/// Post to json url.
///
public static async Task WebPost(string url, string json)
{
using HttpClient client = new HttpClient();
HttpResponseMessage response;
try
{
response = await client.PostAsync(url, new StringContent(json, Encoding.Unicode, "application/json")); // Make sure Universal server is running.
response.EnsureSuccessStatusCode();
}
catch (HttpRequestException exception)
{
throw new Exception(string.Format("Http request failed! Make sure cli build command did run. Close node.exe ({0})", url), exception);
}
string result = await response.Content.ReadAsStringAsync();
return result;
}
}
///
/// Exception for example if client send request to modify a field which IsReadOnly.
///
internal class ExceptionSecurity : Exception
{
public ExceptionSecurity(string message) : base(message)
{
}
}
}