optimize client assembly download service, add support for site level scripts

This commit is contained in:
sbwalker
2023-05-25 12:32:21 -04:00
parent 98c2f012ee
commit 95ba87945b
11 changed files with 268 additions and 162 deletions

View File

@ -36,9 +36,10 @@ namespace Oqtane.Pages
private readonly IVisitorRepository _visitors;
private readonly IAliasRepository _aliases;
private readonly ISettingRepository _settings;
private readonly ServerStateManager _serverState;
private readonly ILogManager _logger;
public HostModel(IConfigManager configuration, ITenantManager tenantManager, ILocalizationManager localizationManager, ILanguageRepository languages, IAntiforgery antiforgery, IJwtManager jwtManager, ISiteRepository sites, IPageRepository pages, IUrlMappingRepository urlMappings, IVisitorRepository visitors, IAliasRepository aliases, ISettingRepository settings, ILogManager logger)
public HostModel(IConfigManager configuration, ITenantManager tenantManager, ILocalizationManager localizationManager, ILanguageRepository languages, IAntiforgery antiforgery, IJwtManager jwtManager, ISiteRepository sites, IPageRepository pages, IUrlMappingRepository urlMappings, IVisitorRepository visitors, IAliasRepository aliases, ISettingRepository settings, ServerStateManager serverState, ILogManager logger)
{
_configuration = configuration;
_tenantManager = tenantManager;
@ -52,6 +53,7 @@ namespace Oqtane.Pages
_visitors = visitors;
_aliases = aliases;
_settings = settings;
_serverState = serverState;
_logger = logger;
}
@ -117,33 +119,11 @@ namespace Oqtane.Pages
{
Runtime = site.Runtime;
}
if (!string.IsNullOrEmpty(site.RenderMode))
if (!string.IsNullOrEmpty(site.RenderMode))
{
RenderMode = site.RenderMode;
}
if (Runtime == "Server")
{
ReconnectScript = CreateReconnectScript();
}
if (site.PwaIsEnabled && site.PwaAppIconFileId != null && site.PwaSplashIconFileId != null)
{
PWAScript = CreatePWAScript(alias, site, route);
}
// site level scripts
HeadResources += ParseScripts(site.HeadContent);
BodyResources += ParseScripts(site.BodyContent);
// get jwt token for downstream APIs
if (User.Identity.IsAuthenticated)
{
var sitesettings = HttpContext.GetSiteSettings();
var secret = sitesettings.GetValue("JwtOptions:Secret", "");
if (!string.IsNullOrEmpty(secret))
{
AuthorizationToken = _jwtManager.GenerateToken(alias, (ClaimsIdentity)User.Identity, secret, sitesettings.GetValue("JwtOptions:Issuer", ""), sitesettings.GetValue("JwtOptions:Audience", ""), int.Parse(sitesettings.GetValue("JwtOptions:Lifetime", "20")));
}
}
if (site.VisitorTracking)
{
TrackVisitor(site.SiteId);
@ -172,11 +152,33 @@ namespace Oqtane.Pages
}
}
// include global resources
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
foreach (Assembly assembly in assemblies)
// get jwt token for downstream APIs
if (User.Identity.IsAuthenticated)
{
ProcessHostResources(assembly, alias);
var sitesettings = HttpContext.GetSiteSettings();
var secret = sitesettings.GetValue("JwtOptions:Secret", "");
if (!string.IsNullOrEmpty(secret))
{
AuthorizationToken = _jwtManager.GenerateToken(alias, (ClaimsIdentity)User.Identity, secret, sitesettings.GetValue("JwtOptions:Issuer", ""), sitesettings.GetValue("JwtOptions:Audience", ""), int.Parse(sitesettings.GetValue("JwtOptions:Lifetime", "20")));
}
}
// inject scripts
if (Runtime == "Server")
{
ReconnectScript = CreateReconnectScript();
}
if (site.PwaIsEnabled && site.PwaAppIconFileId != null && site.PwaSplashIconFileId != null)
{
PWAScript = CreatePWAScript(alias, site, route);
}
HeadResources += ParseScripts(site.HeadContent);
BodyResources += ParseScripts(site.BodyContent);
_sites.InitializeSite(site.SiteId); // populates server state
var scripts = _serverState.GetServerState(site.SiteId).Scripts;
foreach (var script in scripts)
{
AddScript(script, alias);
}
// set culture if not specified
@ -409,20 +411,6 @@ namespace Oqtane.Pages
"</script>";
}
private void ProcessHostResources(Assembly assembly, Alias alias)
{
var types = assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IHostResources)));
foreach (var type in types)
{
var obj = Activator.CreateInstance(type) as IHostResources;
foreach (var resource in obj.Resources)
{
resource.Level = ResourceLevel.App;
ProcessResource(resource, 0, alias);
}
}
}
private string ParseScripts(string headcontent)
{
// iterate scripts
@ -439,60 +427,39 @@ namespace Oqtane.Pages
return scripts;
}
private void ProcessResource(Resource resource, int count, Alias alias)
private void AddScript(Resource resource, Alias alias)
{
var url = (resource.Url.Contains("://")) ? resource.Url : alias.BaseUrl + resource.Url;
switch (resource.ResourceType)
var script = CreateScript(resource, alias);
if (resource.Location == Shared.ResourceLocation.Head)
{
case ResourceType.Stylesheet:
if (!HeadResources.Contains(url, StringComparison.OrdinalIgnoreCase))
{
string id = "";
if (resource.Level == ResourceLevel.Page)
{
id = "id=\"app-stylesheet-" + resource.Level.ToString().ToLower() + "-" + DateTime.UtcNow.ToString("yyyyMMddHHmmssfff") + "-" + count.ToString("00") + "\" ";
}
HeadResources += "<link " + id + "rel=\"stylesheet\" href=\"" + url + "\"" + CrossOrigin(resource.CrossOrigin) + Integrity(resource.Integrity) + " type=\"text/css\"/>" + Environment.NewLine;
}
break;
case ResourceType.Script:
if (resource.Location == Shared.ResourceLocation.Body)
{
if (!BodyResources.Contains(url, StringComparison.OrdinalIgnoreCase))
{
BodyResources += "<script src=\"" + url + "\"" + CrossOrigin(resource.CrossOrigin) + Integrity(resource.Integrity) + "></script>" + Environment.NewLine;
}
}
else
{
if (!HeadResources.Contains(resource.Url, StringComparison.OrdinalIgnoreCase))
{
HeadResources += "<script src=\"" + url + "\"" + CrossOrigin(resource.CrossOrigin) + Integrity(resource.Integrity) + "></script>" + Environment.NewLine;
}
}
break;
}
}
private string CrossOrigin(string crossorigin)
{
if (!string.IsNullOrEmpty(crossorigin))
{
return " crossorigin=\"" + crossorigin + "\"";
if (!HeadResources.Contains(script))
{
HeadResources += script + Environment.NewLine;
}
}
else
{
return "";
if (!BodyResources.Contains(script))
{
BodyResources += script + Environment.NewLine;
}
}
}
private string Integrity(string integrity)
private string CreateScript(Resource resource, Alias alias)
{
if (!string.IsNullOrEmpty(integrity))
if (!string.IsNullOrEmpty(resource.Url))
{
return " integrity=\"" + integrity + "\"";
var url = (resource.Url.Contains("://")) ? resource.Url : alias.BaseUrl + resource.Url;
return "<script src=\"" + url + "\"" +
((!string.IsNullOrEmpty(resource.CrossOrigin)) ? " crossorigin=\"" + resource.CrossOrigin + "\"" : "") +
((!string.IsNullOrEmpty(resource.Integrity)) ? " integrity=\"" + resource.Integrity + "\"" : "") +
"></script>";
}
else
{
return "";
// inline script
return "<script>" + resource.Content + "</script>";
}
}