Skip to content

Instantly share code, notes, and snippets.

@BennieCopeland
Last active July 17, 2020 12:22
Show Gist options
  • Save BennieCopeland/338c9d96725fde85a7ecfb5cfdfc53bd to your computer and use it in GitHub Desktop.
Save BennieCopeland/338c9d96725fde85a7ecfb5cfdfc53bd to your computer and use it in GitHub Desktop.
Transforms an index.html file to update the base path href
public class IndexFileBasePathTransformer
{
private static readonly ReaderWriterLockSlim Rw = new ReaderWriterLockSlim();
private static string _indexHtml = "";
private static bool _transformed;
public static void Transform(string contentRootPath, string basePath, ILogger logger)
{
Rw.EnterUpgradeableReadLock();
if (!_transformed)
{
Rw.EnterWriteLock();
logger.LogInformation("Index file not transformed");
logger.LogInformation($"Base path provided is [{basePath}]");
basePath = string.IsNullOrWhiteSpace(basePath) ? "/" : $"{basePath}/";
var indexFilePath = Path.Combine(contentRootPath, "wwwroot/index.html");
// indexFilePath is not a user provided string
#pragma warning disable SCS0018
var indexHtml = File.ReadAllText(indexFilePath);
indexHtml = Regex.Replace(indexHtml, "(.*<base href=)(\".*\")(>)", $"$1\"{basePath}\"$3");
File.WriteAllText(indexFilePath, indexHtml);
#pragma warning restore SCS0018
_indexHtml = indexHtml;
_transformed = true;
Rw.ExitWriteLock();
}
else
{
logger.LogInformation("Index file transformed");
}
Rw.ExitUpgradeableReadLock();
}
public static bool IsTransformed
{
get
{
Rw.EnterReadLock();
var isTransformed = _transformed;
Rw.ExitReadLock();
return isTransformed;
}
}
public static string CachedIndex
{
get
{
Rw.EnterReadLock();
if (!_transformed)
{
throw new InvalidOperationException("Cannot get an Index that has not been transformed yet.");
}
var indexHtml = _indexHtml;
Rw.ExitReadLock();
return indexHtml;
}
}
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
app
.UseMiddleware<ApiErrorHandlingMiddleware>()
.UseDefaultFiles(new DefaultFilesOptions()
{
DefaultFileNames = new[] {"index.html"}
})
.Use(async (context, next) =>
{
if (!IndexFileBasePathTransformer.IsTransformed)
{
IndexFileBasePathTransformer.Transform(env.ContentRootPath, context.Request.PathBase, logger);
}
await next();
})
.UseStaticFiles()
.Use(async (context, next) =>
{
if (!context.Request.Path.Value.Contains("/api"))
{
await context.Response.WriteAsync(IndexFileBasePathTransformer.CachedIndex);
return;
}
await next();
})
.UseRouting()
.UseCors("default")
.UseAuthentication()
.UseAuthorization()
.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment