public static IApplicationBuilder UseAdminPage(this IApplicationBuilder app, IConfiguration configuration, ILoggerFactory loggerFactory) { var cubesConfig = configuration.GetCubesConfiguration(); var zipPath = configuration.GetCubesConfiguration().AdminPath; var logger = loggerFactory.CreateLogger <Content>(); if (!File.Exists(zipPath)) { logger.LogWarning($"Could not load 'Cubes Management' application from path: {zipPath}"); return(app); } else { logger.LogInformation("Serving 'Cubes Management' from {contentPath}, request path '{requestPath}'.", zipPath, "/admin"); } // Currently Compressed FileProvider seems to be broken! var useCompressedFileProvider = false; IFileProvider fileProvider; if (useCompressedFileProvider) { fileProvider = new CompressedFileProvider(zipPath); // Inform for changes on CompressedFileProvider var fileName = Path.GetFileName(zipPath); var debouncer = new Debouncer(); void call() => logger.LogInformation("File {cubesAdminPath} changed, 'Cubes Management' should be reloaded!", fileName); ChangeToken.OnChange( () => fileProvider.Watch(fileName), () => debouncer.Debounce(call)); } else { var tempFolder = Path.Combine(cubesConfig.TempFolder, "CubesManagement"); DeployZipOnTemp(tempFolder, zipPath); fileProvider = new PhysicalFileProvider(tempFolder); // Setup file changes mechanism for zip file var fileName = Path.GetFileName(zipPath); var pfp = new PhysicalFileProvider(Path.GetDirectoryName(zipPath)); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { pfp.UsePollingFileWatcher = true; } var debouncer = new Debouncer(); void call() { DeployZipOnTemp(tempFolder, zipPath); logger.LogInformation($"File {fileName} changed, 'Cubes Management' should be reloaded!"); } ChangeToken.OnChange( () => pfp.Watch(fileName), () => debouncer.Debounce(call)); } var options = new FileServerOptions { FileProvider = fileProvider, RequestPath = "", EnableDefaultFiles = true, }; options.DefaultFilesOptions.DefaultFileNames.Clear(); options.DefaultFilesOptions.DefaultFileNames.Add("index.html"); app.Map(new PathString("/admin"), builder => { builder.UseFileServer(options); builder.Use(async(context, next) => { await next(); var fullRequest = context.Request.PathBase.Value + context.Request.Path.Value; if (context.Response.StatusCode == 404 && !Path.HasExtension(fullRequest) && !Directory.Exists(fullRequest)) { // Fall back to SPA entry point context.Response.StatusCode = 200; if (useCompressedFileProvider) { await fileProvider.GetFileInfo("index.html") .CreateReadStream() .CopyToAsync(context.Response.Body); } else { await context.Response .WriteAsync(File.ReadAllText(fileProvider.GetFileInfo("index.html").PhysicalPath)); } } }); }); return(app); }