Try your search with a different keyword or use * as a wildcard.
using System.Globalization;
using System.Net;
using System.Reflection;
using System.Runtime.ExceptionServices;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Microsoft.Net.Http.Headers;
using Nop.Core;
using Nop.Core.Configuration;
using Nop.Core.Domain.Common;
using Nop.Core.Domain.Localization;
using Nop.Core.Http;
using Nop.Core.Infrastructure;
using Nop.Data;
using Nop.Data.Migrations;
using Nop.Services.Authentication;
using Nop.Services.Common;
using Nop.Services.Installation;
using Nop.Services.Localization;
using Nop.Services.Logging;
using Nop.Services.Media.RoxyFileman;
using Nop.Services.Plugins;
using Nop.Services.ScheduleTasks;
using Nop.Services.Security;
using Nop.Services.Seo;
using Nop.Web.Framework.Globalization;
using Nop.Web.Framework.Mvc.Routing;
using Nop.Web.Framework.WebOptimizer;
using QuestPDF.Drawing;
using WebMarkupMin.AspNetCore8;
using WebOptimizer;
using IPNetwork = Microsoft.AspNetCore.HttpOverrides.IPNetwork;
namespace Nop.Web.Framework.Infrastructure.Extensions;
///
/// Represents extensions of IApplicationBuilder
///
public static class ApplicationBuilderExtensions
{
///
/// Configure the application HTTP request pipeline
///
/// Builder for configuring an application's request pipeline
public static void ConfigureRequestPipeline(this IApplicationBuilder application)
{
EngineContext.Current.ConfigureRequestPipeline(application);
}
public static async Task StartEngineAsync(this IApplicationBuilder _)
{
var engine = EngineContext.Current;
//further actions are performed only when the database is installed
if (DataSettingsManager.IsDatabaseInstalled())
{
//log application start
await engine.Resolve().InformationAsync("Application started");
//install and update plugins
var pluginService = engine.Resolve();
await pluginService.InstallPluginsAsync();
await pluginService.UpdatePluginsAsync();
//update nopCommerce core and db
var migrationManager = engine.Resolve();
var assembly = Assembly.GetAssembly(typeof(ApplicationBuilderExtensions));
migrationManager.ApplyUpMigrations(assembly, MigrationProcessType.Update);
assembly = Assembly.GetAssembly(typeof(IMigrationManager));
migrationManager.ApplyUpMigrations(assembly, MigrationProcessType.Update);
var taskScheduler = engine.Resolve();
await taskScheduler.InitializeAsync();
taskScheduler.StartScheduler();
}
}
///
/// Add exception handling
///
/// Builder for configuring an application's request pipeline
public static void UseNopExceptionHandler(this IApplicationBuilder application)
{
var appSettings = EngineContext.Current.Resolve();
var webHostEnvironment = EngineContext.Current.Resolve();
var useDetailedExceptionPage = appSettings.Get().DisplayFullErrorStack || webHostEnvironment.IsDevelopment();
if (useDetailedExceptionPage)
{
//get detailed exceptions for developing and testing purposes
application.UseDeveloperExceptionPage();
}
else
{
//or use special exception handler
application.UseExceptionHandler("/Error/Error");
}
//log errors
application.UseExceptionHandler(handler =>
{
handler.Run(async context =>
{
var exception = context.Features.Get()?.Error;
if (exception == null)
return;
try
{
//check whether database is installed
if (DataSettingsManager.IsDatabaseInstalled())
{
//get current customer
var currentCustomer = await EngineContext.Current.Resolve().GetCurrentCustomerAsync();
//log error
await EngineContext.Current.Resolve().ErrorAsync(exception.Message, exception, currentCustomer);
}
}
finally
{
//rethrow the exception to show the error page
ExceptionDispatchInfo.Throw(exception);
}
});
});
}
///
/// Adds a special handler that checks for responses with the 404 status code that do not have a body
///
/// Builder for configuring an application's request pipeline
public static void UsePageNotFound(this IApplicationBuilder application)
{
application.UseStatusCodePages(async context =>
{
//handle 404 Not Found
if (context.HttpContext.Response.StatusCode == StatusCodes.Status404NotFound)
{
var webHelper = EngineContext.Current.Resolve();
if (!webHelper.IsStaticResource())
{
//get original path and query
var originalPath = context.HttpContext.Request.Path;
var originalQueryString = context.HttpContext.Request.QueryString;
if (DataSettingsManager.IsDatabaseInstalled())
{
var commonSettings = EngineContext.Current.Resolve();
if (commonSettings.Log404Errors)
{
var logger = EngineContext.Current.Resolve();
var workContext = EngineContext.Current.Resolve();
await logger.ErrorAsync($"Error 404. The requested page ({originalPath}) was not found",
customer: await workContext.GetCurrentCustomerAsync());
}
}
try
{
//get new path
var pageNotFoundPath = "/page-not-found";
//re-execute request with new path
context.HttpContext.Response.Redirect(context.HttpContext.Request.PathBase + pageNotFoundPath);
}
finally
{
//return original path to request
context.HttpContext.Request.QueryString = originalQueryString;
context.HttpContext.Request.Path = originalPath;
}
}
}
});
}
///
/// Adds a special handler that checks for responses with the 400 status code (bad request)
///
/// Builder for configuring an application's request pipeline
public static void UseBadRequestResult(this IApplicationBuilder application)
{
application.UseStatusCodePages(async context =>
{
//handle 404 (Bad request)
if (context.HttpContext.Response.StatusCode == StatusCodes.Status400BadRequest)
{
var logger = EngineContext.Current.Resolve();
var workContext = EngineContext.Current.Resolve();
await logger.ErrorAsync("Error 400. Bad request", null, customer: await workContext.GetCurrentCustomerAsync());
}
});
}
///
/// Configure middleware for dynamically compressing HTTP responses
///
/// Builder for configuring an application's request pipeline
public static void UseNopResponseCompression(this IApplicationBuilder application)
{
if (!DataSettingsManager.IsDatabaseInstalled())
return;
//whether to use compression (gzip by default)
if (EngineContext.Current.Resolve().UseResponseCompression)
application.UseResponseCompression();
}
///
/// Adds WebOptimizer to the request execution pipeline
///
/// Builder for configuring an application's request pipeline
public static void UseNopWebOptimizer(this IApplicationBuilder application)
{
var appSettings = Singleton.Instance;
var woConfig = appSettings.Get();
if (!woConfig.EnableCssBundling && !woConfig.EnableJavaScriptBundling)
return;
var fileProvider = EngineContext.Current.Resolve();
var webHostEnvironment = EngineContext.Current.Resolve();
application.UseWebOptimizer(webHostEnvironment,
[
new FileProviderOptions
{
RequestPath = new PathString("/Plugins"),
FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"Plugins"))
},
new FileProviderOptions
{
RequestPath = new PathString("/Themes"),
FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"Themes"))
}
]);
}
///
/// Configure static file serving
///
/// Builder for configuring an application's request pipeline
public static void UseNopStaticFiles(this IApplicationBuilder application)
{
var fileProvider = EngineContext.Current.Resolve();
var appSettings = EngineContext.Current.Resolve();
void staticFileResponse(StaticFileResponseContext context)
{
if (!string.IsNullOrEmpty(appSettings.Get().StaticFilesCacheControl))
context.Context.Response.Headers.Append(HeaderNames.CacheControl, appSettings.Get().StaticFilesCacheControl);
}
//add handling if sitemaps
application.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(fileProvider.GetAbsolutePath(NopSeoDefaults.SitemapXmlDirectory)),
RequestPath = new PathString($"/{NopSeoDefaults.SitemapXmlDirectory}"),
OnPrepareResponse = context =>
{
if (!DataSettingsManager.IsDatabaseInstalled() ||
!EngineContext.Current.Resolve().SitemapXmlEnabled)
{
context.Context.Response.StatusCode = StatusCodes.Status403Forbidden;
context.Context.Response.ContentLength = 0;
context.Context.Response.Body = Stream.Null;
}
}
});
//common static files
application.UseStaticFiles(new StaticFileOptions { OnPrepareResponse = staticFileResponse });
//themes static files
application.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"Themes")),
RequestPath = new PathString("/Themes"),
OnPrepareResponse = staticFileResponse
});
//plugins static files
var staticFileOptions = new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"Plugins")),
RequestPath = new PathString("/Plugins"),
OnPrepareResponse = staticFileResponse
};
//exclude files in blacklist
if (!string.IsNullOrEmpty(appSettings.Get().PluginStaticFileExtensionsBlacklist))
{
var fileExtensionContentTypeProvider = new FileExtensionContentTypeProvider();
foreach (var ext in appSettings.Get().PluginStaticFileExtensionsBlacklist
.Split(';', ',')
.Select(e => e.Trim().ToLowerInvariant())
.Select(e => $"{(e.StartsWith(".") ? string.Empty : ".")}{e}")
.Where(fileExtensionContentTypeProvider.Mappings.ContainsKey))
{
fileExtensionContentTypeProvider.Mappings.Remove(ext);
}
staticFileOptions.ContentTypeProvider = fileExtensionContentTypeProvider;
}
application.UseStaticFiles(staticFileOptions);
//add support for backups
var provider = new FileExtensionContentTypeProvider
{
Mappings = { [".bak"] = MimeTypes.ApplicationOctetStream }
};
application.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(fileProvider.GetAbsolutePath(NopCommonDefaults.DbBackupsPath)),
RequestPath = new PathString("/db_backups"),
ContentTypeProvider = provider,
OnPrepareResponse = context =>
{
if (!DataSettingsManager.IsDatabaseInstalled() ||
!EngineContext.Current.Resolve().AuthorizeAsync(StandardPermissionProvider.ManageMaintenance).Result)
{
context.Context.Response.StatusCode = StatusCodes.Status404NotFound;
context.Context.Response.ContentLength = 0;
context.Context.Response.Body = Stream.Null;
}
}
});
//add support for webmanifest files
provider.Mappings[".webmanifest"] = MimeTypes.ApplicationManifestJson;
application.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(fileProvider.GetAbsolutePath("icons")),
RequestPath = "/icons",
ContentTypeProvider = provider
});
if (DataSettingsManager.IsDatabaseInstalled())
{
application.UseStaticFiles(new StaticFileOptions
{
FileProvider = EngineContext.Current.Resolve(),
RequestPath = new PathString(NopRoxyFilemanDefaults.DefaultRootDirectory),
OnPrepareResponse = staticFileResponse
});
}
if (appSettings.Get().ServeUnknownFileTypes)
{
application.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(fileProvider.GetAbsolutePath(".well-known")),
RequestPath = new PathString("/.well-known"),
ServeUnknownFileTypes = true,
});
}
}
///
/// Configure middleware checking whether requested page is keep alive page
///
/// Builder for configuring an application's request pipeline
public static void UseKeepAlive(this IApplicationBuilder application)
{
application.UseMiddleware();
}
///
/// Configure middleware checking whether database is installed
///
/// Builder for configuring an application's request pipeline
public static void UseInstallUrl(this IApplicationBuilder application)
{
application.UseMiddleware();
}
///
/// Adds the authentication middleware, which enables authentication capabilities.
///
/// Builder for configuring an application's request pipeline
public static void UseNopAuthentication(this IApplicationBuilder application)
{
//check whether database is installed
if (!DataSettingsManager.IsDatabaseInstalled())
return;
application.UseMiddleware();
}
///
/// Configure PDF
///
public static void UseNopPdf(this IApplicationBuilder _)
{
if (!DataSettingsManager.IsDatabaseInstalled())
return;
var fileProvider = EngineContext.Current.Resolve();
var fontPaths = fileProvider.EnumerateFiles(fileProvider.MapPath("~/App_Data/Pdf/"), "*.ttf") ?? Enumerable.Empty();
//write placeholder characters instead of unavailable glyphs for both debug/release configurations
QuestPDF.Settings.CheckIfAllTextGlyphsAreAvailable = false;
foreach (var fp in fontPaths)
{
FontManager.RegisterFont(File.OpenRead(fp));
}
}
///
/// Configure the request localization feature
///
/// Builder for configuring an application's request pipeline
public static void UseNopRequestLocalization(this IApplicationBuilder application)
{
application.UseRequestLocalization(options =>
{
if (!DataSettingsManager.IsDatabaseInstalled())
return;
var languageService = EngineContext.Current.Resolve();
var localizationSettings = EngineContext.Current.Resolve();
//prepare supported cultures
var cultures = languageService
.GetAllLanguages()
.OrderBy(language => language.DisplayOrder)
.Select(language => new CultureInfo(language.LanguageCulture))
.ToList();
options.SupportedCultures = cultures;
options.SupportedUICultures = cultures;
options.DefaultRequestCulture = new RequestCulture(cultures.FirstOrDefault() ?? new CultureInfo(NopCommonDefaults.DefaultLanguageCulture));
options.ApplyCurrentCultureToResponseHeaders = true;
//configure culture providers
options.AddInitialRequestCultureProvider(new NopSeoUrlCultureProvider());
var cookieRequestCultureProvider = options.RequestCultureProviders.OfType().FirstOrDefault();
if (cookieRequestCultureProvider is not null)
cookieRequestCultureProvider.CookieName = $"{NopCookieDefaults.Prefix}{NopCookieDefaults.CultureCookie}";
if (!localizationSettings.AutomaticallyDetectLanguage)
{
var headerRequestCultureProvider = options
.RequestCultureProviders
.OfType()
.FirstOrDefault();
if (headerRequestCultureProvider is not null)
options.RequestCultureProviders.Remove(headerRequestCultureProvider);
}
});
}
///
/// Configure Endpoints routing
///
/// Builder for configuring an application's request pipeline
public static void UseNopEndpoints(this IApplicationBuilder application)
{
//Execute the endpoint selected by the routing middleware
application.UseEndpoints(endpoints =>
{
//register all routes
EngineContext.Current.Resolve().RegisterRoutes(endpoints);
});
}
///
/// Configure applying forwarded headers to their matching fields on the current request.
///
/// Builder for configuring an application's request pipeline
public static void UseNopProxy(this IApplicationBuilder application)
{
var appSettings = EngineContext.Current.Resolve();
var hostingConfig = appSettings.Get();
if (hostingConfig.UseProxy)
{
var options = new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
// IIS already serves as a reverse proxy and will add X-Forwarded headers to all requests,
// so we need to increase this limit, otherwise, passed forwarding headers will be ignored.
ForwardLimit = 2
};
if (!string.IsNullOrEmpty(hostingConfig.ForwardedForHeaderName))
options.ForwardedForHeaderName = hostingConfig.ForwardedForHeaderName;
if (!string.IsNullOrEmpty(hostingConfig.ForwardedProtoHeaderName))
options.ForwardedProtoHeaderName = hostingConfig.ForwardedProtoHeaderName;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
if (!string.IsNullOrEmpty(hostingConfig.KnownProxies))
{
foreach (var strIp in hostingConfig.KnownProxies.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList())
{
if (IPAddress.TryParse(strIp, out var ip))
options.KnownProxies.Add(ip);
}
}
if (!string.IsNullOrEmpty(hostingConfig.KnownNetworks))
{
foreach (var strIpNet in hostingConfig.KnownNetworks.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList())
{
var ipNetParts = strIpNet.Split("/");
if (ipNetParts.Length == 2)
{
if (IPAddress.TryParse(ipNetParts[0], out var ip) && int.TryParse(ipNetParts[1], out var length))
options.KnownNetworks.Add(new IPNetwork(ip, length));
}
}
}
if (options.KnownProxies.Count > 1 || options.KnownNetworks.Count > 1)
options.ForwardLimit = null; //disable the limit, because KnownProxies is configured
//configure forwarding
application.UseForwardedHeaders(options);
}
}
///
/// Configure WebMarkupMin
///
/// Builder for configuring an application's request pipeline
public static void UseNopWebMarkupMin(this IApplicationBuilder application)
{
//check whether database is installed
if (!DataSettingsManager.IsDatabaseInstalled())
return;
application.UseWebMarkupMin();
}
}