From 2a06304a2ce802e53bfd4e2b14f7485675777bba Mon Sep 17 00:00:00 2001 From: sbwalker Date: Tue, 28 Jan 2025 12:47:23 -0500 Subject: [PATCH] add caching support for folders --- Oqtane.Client/Modules/Admin/Files/Edit.razor | 29 ++++++++++++------- .../Resources/Modules/Admin/Files/Edit.resx | 8 ++++- .../Tenant/06000201_AddFolderCacheControl.cs | 28 ++++++++++++++++++ Oqtane.Server/Pages/Files.cshtml.cs | 4 +++ Oqtane.Shared/Models/Folder.cs | 5 ++++ 5 files changed, 63 insertions(+), 11 deletions(-) create mode 100644 Oqtane.Server/Migrations/Tenant/06000201_AddFolderCacheControl.cs diff --git a/Oqtane.Client/Modules/Admin/Files/Edit.razor b/Oqtane.Client/Modules/Admin/Files/Edit.razor index 3ad60467..81262d50 100644 --- a/Oqtane.Client/Modules/Admin/Files/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Files/Edit.razor @@ -49,18 +49,24 @@ } -
- -
- -
-
+
+ +
+ +
+
+
+ +
+ +
+
@if (PageState.QueryString.ContainsKey("id")) { @@ -100,8 +106,9 @@ private int _parentId = -1; private string _name; private string _type = FolderTypes.Private; - private string _imagesizes = string.Empty; private string _capacity = "0"; + private string _cachecontrol = string.Empty; + private string _imagesizes = string.Empty; private bool _isSystem; private List _permissions = null; private string _createdBy; @@ -132,8 +139,9 @@ _parentId = folder.ParentId ?? -1; _name = folder.Name; _type = folder.Type; - _imagesizes = folder.ImageSizes; _capacity = folder.Capacity.ToString(); + _cachecontrol = folder.CacheControl; + _imagesizes = folder.ImageSizes; _isSystem = folder.IsSystem; _permissions = folder.PermissionList; _createdBy = folder.CreatedBy; @@ -193,7 +201,7 @@ { folder.ParentId = _parentId; } - + // check for duplicate folder names if (_folders.Any(item => item.ParentId == folder.ParentId && item.Name == _name && item.FolderId != _folderId)) { @@ -204,8 +212,9 @@ folder.SiteId = PageState.Site.SiteId; folder.Name = _name; folder.Type = _type; - folder.ImageSizes = _imagesizes; folder.Capacity = int.Parse(_capacity); + folder.CacheControl = _cachecontrol; + folder.ImageSizes = _imagesizes; folder.IsSystem = _isSystem; folder.PermissionList = _permissionGrid.GetPermissionList(); diff --git a/Oqtane.Client/Resources/Modules/Admin/Files/Edit.resx b/Oqtane.Client/Resources/Modules/Admin/Files/Edit.resx index 4fa73338..1371214d 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Files/Edit.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Files/Edit.resx @@ -175,7 +175,7 @@ Capacity: - Enter a list of image sizes which can be generated dynamically from uploaded images (ie. 200x200,400x400). Use * to indicate the folder supports all image sizes. + Optionally enter a list of image sizes which can be generated dynamically from uploaded images (ie. 200x200,400x400). Use * to indicate the folder supports all image sizes. Image Sizes: @@ -198,4 +198,10 @@ Settings + + Caching: + + + Optionally provide a Cache-Control directive for this folder. For example 'public, max-age=604800' indicates that files in this folder should be cached for 1 week. + \ No newline at end of file diff --git a/Oqtane.Server/Migrations/Tenant/06000201_AddFolderCacheControl.cs b/Oqtane.Server/Migrations/Tenant/06000201_AddFolderCacheControl.cs new file mode 100644 index 00000000..7e566bea --- /dev/null +++ b/Oqtane.Server/Migrations/Tenant/06000201_AddFolderCacheControl.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Oqtane.Databases.Interfaces; +using Oqtane.Migrations.EntityBuilders; +using Oqtane.Repository; + +namespace Oqtane.Migrations.Tenant +{ + [DbContext(typeof(TenantDBContext))] + [Migration("Tenant.06.00.02.01")] + public class AddFolderCacheControl : MultiDatabaseMigration + { + public AddFolderCacheControl(IDatabase database) : base(database) + { + } + + protected override void Up(MigrationBuilder migrationBuilder) + { + var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder, ActiveDatabase); + folderEntityBuilder.AddStringColumn("CacheControl", 50, true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + // not implemented + } + } +} diff --git a/Oqtane.Server/Pages/Files.cshtml.cs b/Oqtane.Server/Pages/Files.cshtml.cs index 8af671ae..a2bb860b 100644 --- a/Oqtane.Server/Pages/Files.cshtml.cs +++ b/Oqtane.Server/Pages/Files.cshtml.cs @@ -257,6 +257,10 @@ namespace Oqtane.Pages } else { + if (!string.IsNullOrEmpty(file.Folder.CacheControl)) + { + HttpContext.Response.Headers.Append(HeaderNames.CacheControl, value: file.Folder.CacheControl); + } HttpContext.Response.Headers.Append(HeaderNames.ETag, etag); return PhysicalFile(filepath, MimeUtilities.GetMimeType(downloadName)); } diff --git a/Oqtane.Shared/Models/Folder.cs b/Oqtane.Shared/Models/Folder.cs index ef20d937..da875219 100644 --- a/Oqtane.Shared/Models/Folder.cs +++ b/Oqtane.Shared/Models/Folder.cs @@ -62,6 +62,11 @@ namespace Oqtane.Models /// public bool IsSystem { get; set; } + /// + /// An HTTP Caching Cache-Control directive + /// + public string CacheControl { get; set; } + /// /// Deprecated /// Note that this property still exists in the database because columns cannot be dropped in SQLite