in CachingProxy/src/CacheFileProvider.cs [7:64]
public class CacheFileProvider(string cacheDirectory) : IFileProvider
{
private static readonly string ourGzippedContentSuffix = "-gzip-Ege4dHyCEA7IM";
private readonly PhysicalFileProvider myPhysicalFileProvider = new(cacheDirectory);
public IFileInfo GetFileInfo(string subpath)
{
var withGzipSuffix = myPhysicalFileProvider.GetFileInfo(ManglePath(subpath, ourGzippedContentSuffix));
if (withGzipSuffix.Exists)
return withGzipSuffix;
var withoutGzipSuffix = myPhysicalFileProvider.GetFileInfo(ManglePath(subpath, ""));
return withoutGzipSuffix;
}
public IDirectoryContents GetDirectoryContents(string subpath)
{
return myPhysicalFileProvider.GetDirectoryContents(ManglePath(subpath, ""));
}
public string? GetFutureCacheFileLocation(string subpath, string? contentEncoding)
{
var fileInfo = myPhysicalFileProvider.GetFileInfo(ManglePath(subpath, GetContentEncodingCacheFileSuffix(contentEncoding)));
return fileInfo.PhysicalPath;
}
public string? GetContentEncoding(IFileInfo fileInfo)
{
return fileInfo.PhysicalPath?.EndsWith(ourGzippedContentSuffix) ?? false ? "gzip" : null;
}
public IChangeToken Watch(string filter)
{
throw new NotSupportedException();
}
/// <summary>
/// Change sub-path upon converting to a local file system path to handle hierarchy-conflicts like
/// caching both a/a.jar and a/b/c/c.jar
/// </summary>
private static string ManglePath(string subpath, string contentEncodingSuffix)
{
var trimmed = subpath.Replace('\\', '/').TrimEnd('/');
var lastSeparator = trimmed.LastIndexOf('/');
return lastSeparator < 0
? $"cache-{trimmed}"
: $"{trimmed[..(lastSeparator + 1)]}cache-{trimmed[(lastSeparator + 1)..]}{contentEncodingSuffix}";
}
private static string GetContentEncodingCacheFileSuffix(string? contentEncoding) =>
contentEncoding switch
{
null => "",
"gzip" => ourGzippedContentSuffix,
_ => throw new ArgumentException($"Unsupported Content-Encoding: {contentEncoding}")
};
}