Skip to content

Commit

Permalink
Merge branch 'feature/267' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
i4004 committed Jul 28, 2024
2 parents f237e68 + ec22576 commit f45eea8
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
namespace Simplify.Web.Tests.StaticFiles.Handlers;

[TestFixture]
public class CachedFileHandlerTests
public class ClientCachedFileHandlerTests
{
private CachedFileHandler _handler = null!;
private ClientCachedFileHandler _handler = null!;

[SetUp]
public void Initialize() => _handler = new CachedFileHandler();
public void Initialize() => _handler = new ClientCachedFileHandler();

[Test]
public void CanHandle_CanBeCached_True()
Expand Down
19 changes: 14 additions & 5 deletions src/Simplify.Web/Bootstrapper/Setup/BaseBootstrapperStaticFiles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,19 @@ public virtual void RegisterStaticFileRequestHandlingPipelineHandlers()
if (TypesToExclude.Contains(typeof(IReadOnlyList<IStaticFileRequestHandler>)))
return;

BootstrapperFactory.ContainerProvider.Register<IReadOnlyList<IStaticFileRequestHandler>>(r =>
[
new CachedFileHandler(),
new NewFileHandler(r.Resolve<IResponseWriter>(), r.Resolve<IStaticFile>())
], LifetimeType.Singleton);
BootstrapperFactory.ContainerProvider.Register(r =>
{
IList<IStaticFileRequestHandler> handlers =
[
new ClientCachedFileHandler()
];

if (r.Resolve<ISimplifyWebSettings>().StaticFilesMemoryCache)
handlers.Add(new InMemoryFilesCacheHandler(r.Resolve<IResponseWriter>(), r.Resolve<IStaticFile>()));
else
handlers.Add(new NewFileHandler(r.Resolve<IResponseWriter>(), r.Resolve<IStaticFile>()));

return (IReadOnlyList<IStaticFileRequestHandler>)handlers;
}, LifetimeType.Singleton);
}
}
8 changes: 8 additions & 0 deletions src/Simplify.Web/Settings/ISimplifyWebSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ public interface ISimplifyWebSettings
/// </value>
bool StringTableMemoryCache { get; }

/// <summary>
/// Gets the value indicating whether static files memory cache enabled or disabled.
/// </summary>
/// <value>
/// <c>true</c> if static files memory cache is enabled; otherwise, <c>false</c>.
/// </value>
bool StaticFilesMemoryCache { get; }

/// <summary>
/// Gets the value indicating whether file reader caching should be disabled.
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions src/Simplify.Web/Settings/SimplifyWebSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,14 @@ public SimplifyWebSettings(IConfiguration configuration)
/// </value>
public bool StringTableMemoryCache { get; private set; }

/// <summary>
/// Gets the value indicating whether static files memory cache enabled or disabled.
/// </summary>
/// <value>
/// <c>true</c> if static files memory cache is enabled; otherwise, <c>false</c>.
/// </value>
public bool StaticFilesMemoryCache { get; private set; }

/// <summary>
/// Gets the value indicating whether file reader caching should be disabled.
/// </summary>
Expand Down Expand Up @@ -263,6 +271,7 @@ private void LoadCacheSettings(IConfiguration config)
{
TemplatesMemoryCache = config.GetValue<bool>(nameof(TemplatesMemoryCache));
StringTableMemoryCache = config.GetValue<bool>(nameof(StringTableMemoryCache));
StaticFilesMemoryCache = config.GetValue<bool>(nameof(StaticFilesMemoryCache));
DisableFileReaderCache = config.GetValue<bool>(nameof(DisableFileReaderCache));
}

Expand Down
22 changes: 22 additions & 0 deletions src/Simplify.Web/StaticFiles/Cache/FilesInMemoryCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Collections.Concurrent;

namespace Simplify.Web.StaticFiles.Cache;

/// <summary>
/// Provides static files in-memory cache.
/// </summary>
public static class FilesInMemoryCache
{
// /// <summary>
// /// Gets the static files in-memory cache data.
// /// </summary>
// /// <value>
// /// The static files in-memory cache data..
// /// </value>
// public static IDictionary<string, byte[]> Data { get; set; } = new Dictionary<string, byte[]>();

/// <summary>
/// Gets the static files in-memory cache data.
/// </summary>
public static readonly ConcurrentDictionary<string, byte[]> Items = new();
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
namespace Simplify.Web.StaticFiles.Handlers;

/// <summary>
/// Provides the cached file handler.
/// Provides the cached on client side files handler.
/// </summary>
/// <seealso cref="IStaticFileRequestHandler" />
public class CachedFileHandler : IStaticFileRequestHandler
public class ClientCachedFileHandler : IStaticFileRequestHandler
{
/// <summary>
/// Determines whether this handler can handle the file requested.
Expand Down
36 changes: 36 additions & 0 deletions src/Simplify.Web/StaticFiles/Handlers/InMemoryFilesCacheHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Simplify.Web.Http.ResponseWriting;
using Simplify.Web.StaticFiles.Cache;
using Simplify.Web.StaticFiles.Context;
using Simplify.Web.StaticFiles.IO;

namespace Simplify.Web.StaticFiles.Handlers;

/// <summary>
/// Provides the in-memory files cache.
/// </summary>
/// <seealso cref="IStaticFileRequestHandler" />
public class InMemoryFilesCacheHandler(IResponseWriter responseWriter, IStaticFile staticFile) : IStaticFileRequestHandler
{
/// <summary>
/// Determines whether this handler can handle the file requested.
/// </summary>
/// <param name="context">The context.</param>
/// <returns>
/// <c>true</c> if this handler can handle the file requested; otherwise, <c>false</c>.
/// </returns>
public bool CanHandle(IStaticFileProcessingContext context) => !context.CanBeCached;

/// <summary>
/// Executes the handler asynchronously.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="response">The response.</param>
public async Task ExecuteAsync(IStaticFileProcessingContext context, HttpResponse response)
{
response.SetNewReturningFileAttributes(context);

await responseWriter.WriteAsync(response, FilesInMemoryCache.Items.GetOrAdd(context.RelativeFilePath, staticFile.GetData));
}
}
8 changes: 1 addition & 7 deletions src/Simplify.Web/StaticFiles/Handlers/NewFileHandler.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Simplify.System;
using Simplify.Web.Http.Mime;
using Simplify.Web.Http.ResponseTime;
using Simplify.Web.Http.ResponseWriting;
using Simplify.Web.StaticFiles.Context;
using Simplify.Web.StaticFiles.IO;
Expand Down Expand Up @@ -32,9 +28,7 @@ public class NewFileHandler(IResponseWriter responseWriter, IStaticFile staticFi
/// <param name="response">The response.</param>
public async Task ExecuteAsync(IStaticFileProcessingContext context, HttpResponse response)
{
response.SetContentMimeType(context.RelativeFilePath);
response.SetLastModifiedTime(context.LastModificationTime);
response.Headers["Expires"] = new DateTimeOffset(TimeProvider.Current.Now.AddYears(1)).ToString("R");
response.SetNewReturningFileAttributes(context);

await responseWriter.WriteAsync(response, await staticFile.GetDataAsync(context.RelativeFilePath));
}
Expand Down
9 changes: 7 additions & 2 deletions src/Simplify.Web/StaticFiles/IO/IStaticFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ public interface IStaticFile
DateTime GetLastModificationTime(string relativeFilePath);

/// <summary>
/// Gets the file data.
/// Gets the file data asynchronously.
/// </summary>
/// <param name="relativeFilePath">The relative file path.</param>
/// <returns></returns>
Task<byte[]> GetDataAsync(string relativeFilePath);

/// <summary>
/// Gets the file data.
/// </summary>
/// <param name="relativeFilePath">The relative file path.</param>
byte[] GetData(string relativeFilePath);
}
8 changes: 7 additions & 1 deletion src/Simplify.Web/StaticFiles/IO/StaticFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public bool IsValidPath(string relativeFilePath)
public DateTime GetLastModificationTime(string relativeFilePath) => File.GetLastWriteTimeUtc(sitePhysicalPath + relativeFilePath).TrimMilliseconds();

/// <summary>
/// Gets the file data.
/// Gets the file data asynchronously.
/// </summary>
/// <param name="relativeFilePath">The relative file path.</param>
public async Task<byte[]> GetDataAsync(string relativeFilePath)
Expand All @@ -59,4 +59,10 @@ public async Task<byte[]> GetDataAsync(string relativeFilePath)

return result;
}

/// <summary>
/// Gets the file data.
/// </summary>
/// <param name="relativeFilePath">The relative file path.</param>
public byte[] GetData(string relativeFilePath) => File.ReadAllBytes(relativeFilePath);
}
26 changes: 26 additions & 0 deletions src/Simplify.Web/StaticFiles/StaticFileResponseExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using Microsoft.AspNetCore.Http;
using Simplify.System;
using Simplify.Web.Http.Mime;
using Simplify.Web.Http.ResponseTime;
using Simplify.Web.StaticFiles.Context;

namespace Simplify.Web.StaticFiles;

/// <summary>
/// Provides the static file response extensions.
/// </summary>
public static class StaticFileResponseExtensions
{
/// <summary>
/// Sets the new returning file attributes.
/// </summary>
/// <param name="response">The HTTP response.</param>
/// <param name="context">The static file processing context.</param>
public static void SetNewReturningFileAttributes(this HttpResponse response, IStaticFileProcessingContext context)
{
response.SetContentMimeType(context.RelativeFilePath);
response.SetLastModifiedTime(context.LastModificationTime);
response.Headers["Expires"] = new DateTimeOffset(TimeProvider.Current.Now.AddYears(1)).ToString("R");
}
}

0 comments on commit f45eea8

Please sign in to comment.