Merge pull request #2424 from sbwalker/dev

improve BaseUrl handling for MAUI, replace ContentUrl with FileUrl and improve file server
This commit is contained in:
Shaun Walker 2022-09-21 13:39:51 -04:00 committed by GitHub
commit dca21fbb8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 155 additions and 58 deletions

View File

@ -262,7 +262,7 @@
{
var interop = new Interop(JSRuntime);
int pos = await interop.GetCaretPosition("rawhtmleditor");
var image = "<img src=\"" + file.Url + "\" alt=\"" + ((!string.IsNullOrEmpty(file.Description)) ? file.Description : file.Name) + "\">";
var image = "<img src=\"" + file.Url + "\" alt=\"" + ((!string.IsNullOrEmpty(file.Description)) ? file.Description : file.Name) + "\" class=\"img-fluid\">";
_rawhtml = _rawhtml.Substring(0, pos) + image + _rawhtml.Substring(pos);
_rawfilemanager = false;
}

View File

@ -75,7 +75,7 @@ namespace Oqtane.Modules
var scripts = new List<object>();
foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script))
{
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + "/" + resource.Url;
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + (!resource.Url.StartsWith("/") ? "/" : "") + resource.Url;
scripts.Add(new { href = url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", es6module = resource.ES6Module });
}
if (scripts.Any())
@ -91,7 +91,7 @@ namespace Oqtane.Modules
public string ModulePath()
{
return "Modules/" + GetType().Namespace + "/";
return PageState?.Alias.BaseUrl + "/Modules/" + GetType().Namespace + "/";
}
// url methods
@ -145,14 +145,23 @@ namespace Oqtane.Modules
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters);
}
public string ContentUrl(int fileid)
public string FileUrl(string folderpath, string filename)
{
return ContentUrl(fileid, false);
return FileUrl(folderpath, filename, false);
}
public string ContentUrl(int fileid, bool asAttachment)
public string FileUrl(string folderpath, string filename, bool download)
{
return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment);
return Utilities.FileUrl(PageState.Alias, folderpath, filename, download);
}
public string FileUrl(int fileid)
{
return FileUrl(fileid, false);
}
public string FileUrl(int fileid, bool download)
{
return Utilities.FileUrl(PageState.Alias, fileid, download);
}
public string ImageUrl(int fileid, int width, int height)
@ -407,5 +416,17 @@ namespace Oqtane.Modules
await _moduleBase.Log(null, LogLevel.Critical, "", exception, message, args);
}
}
[Obsolete("ContentUrl(int fileId) is deprecated. Use FileUrl(int fileId) instead.", false)]
public string ContentUrl(int fileid)
{
return ContentUrl(fileid, false);
}
[Obsolete("ContentUrl(int fileId, bool asAttachment) is deprecated. Use FileUrl(int fileId, bool download) instead.", false)]
public string ContentUrl(int fileid, bool asAttachment)
{
return Utilities.FileUrl(PageState.Alias, fileid, asAttachment);
}
}
}

View File

@ -3,6 +3,7 @@ using Microsoft.JSInterop;
using Oqtane.Models;
using Oqtane.Shared;
using Oqtane.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@ -49,7 +50,7 @@ namespace Oqtane.Themes
public string ThemePath()
{
return "Themes/" + GetType().Namespace + "/";
return PageState?.Alias.BaseUrl + "/Themes/" + GetType().Namespace + "/";
}
// url methods
@ -94,14 +95,23 @@ namespace Oqtane.Themes
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters);
}
public string ContentUrl(int fileid)
public string FileUrl(string folderpath, string filename)
{
return Utilities.ContentUrl(PageState.Alias, fileid);
return FileUrl(folderpath, filename, false);
}
public string ContentUrl(int fileid, bool asAttachment)
public string FileUrl(string folderpath, string filename, bool download)
{
return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment);
return Utilities.FileUrl(PageState.Alias, folderpath, filename, download);
}
public string FileUrl(int fileid)
{
return FileUrl(fileid, false);
}
public string FileUrl(int fileid, bool download)
{
return Utilities.FileUrl(PageState.Alias, fileid, download);
}
public string ImageUrl(int fileid, int width, int height)
@ -118,5 +128,17 @@ namespace Oqtane.Themes
{
return Utilities.ImageUrl(PageState.Alias, fileid, width, height, mode, position, background, rotate, recreate);
}
[Obsolete("ContentUrl(int fileId) is deprecated. Use FileUrl(int fileId) instead.", false)]
public string ContentUrl(int fileid)
{
return ContentUrl(fileid, false);
}
[Obsolete("ContentUrl(int fileId, bool asAttachment) is deprecated. Use FileUrl(int fileId, bool download) instead.", false)]
public string ContentUrl(int fileid, bool asAttachment)
{
return Utilities.FileUrl(PageState.Alias, fileid, asAttachment);
}
}
}

View File

@ -36,7 +36,7 @@
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
{
var prefix = "app-stylesheet-" + resource.Level.ToString().ToLower();
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + "/" + resource.Url;
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + (!resource.Url.StartsWith("/") ? "/" : "") + resource.Url;
links.Add(new { id = prefix + "-" + batch + "-" + (links.Count + 1).ToString("00"), rel = "stylesheet", href = url, type = "text/css", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", insertbefore = prefix });
}
if (links.Any())

View File

@ -42,6 +42,13 @@ namespace Oqtane.Pages
var folderpath = "";
var filename = "";
bool download = false;
if (path.Contains("?download"))
{
download = true;
path = path.Substring(0, path.IndexOf("?download"));
}
var segments = path.Split('/');
if (segments.Length > 0)
{
@ -52,15 +59,31 @@ namespace Oqtane.Pages
}
}
var file = _files.GetFile(_alias.SiteId, folderpath, filename);
Models.File file;
if (folderpath == "id" && int.TryParse(filename, out int fileid))
{
file = _files.GetFile(fileid, false);
}
else
{
file = _files.GetFile(_alias.SiteId, folderpath, filename);
}
if (file != null)
{
if (_userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
if (file.Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
{
var filepath = _files.GetFilePath(file);
if (System.IO.File.Exists(filepath))
{
return PhysicalFile(filepath, file.GetMimeType());
if (download)
{
return PhysicalFile(filepath, file.GetMimeType(), file.Name);
}
else
{
return PhysicalFile(filepath, file.GetMimeType());
}
}
else
{
@ -91,7 +114,7 @@ namespace Oqtane.Pages
}
// broken link
string errorPath = Path.Combine(Utilities.PathCombine(_environment.ContentRootPath, "wwwroot\\images"), "error.png");
string errorPath = Path.Combine(Utilities.PathCombine(_environment.ContentRootPath, "wwwroot/images"), "error.png");
return PhysicalFile(errorPath, MimeUtilities.GetMimeType(errorPath));
}
}

View File

@ -126,7 +126,7 @@ namespace Oqtane.Pages
}
if (site.FaviconFileId != null)
{
FavIcon = Utilities.ContentUrl(alias, site.FaviconFileId.Value);
FavIcon = Utilities.FileUrl(alias, site.FaviconFileId.Value);
}
if (site.PwaIsEnabled && site.PwaAppIconFileId != null && site.PwaSplashIconFileId != null)
{
@ -384,11 +384,11 @@ namespace Oqtane.Pages
"\"background_color\": \"#fff\", " +
"\"description\": \"" + site.Name + "\", " +
"\"icons\": [{ " +
"\"src\": \"" + route.RootUrl + Utilities.ContentUrl(alias, site.PwaAppIconFileId.Value) + "\", " +
"\"src\": \"" + route.RootUrl + Utilities.FileUrl(alias, site.PwaAppIconFileId.Value) + "\", " +
"\"sizes\": \"192x192\", " +
"\"type\": \"image/png\" " +
"}, { " +
"\"src\": \"" + route.RootUrl + Utilities.ContentUrl(alias, site.PwaSplashIconFileId.Value) + "\", " +
"\"src\": \"" + route.RootUrl + Utilities.FileUrl(alias, site.PwaSplashIconFileId.Value) + "\", " +
"\"sizes\": \"512x512\", " +
"\"type\": \"image/png\" " +
"}] " +

View File

@ -16,17 +16,12 @@ namespace Oqtane.Shared
public const string ContainerComponent = "Oqtane.UI.ContainerBuilder, Oqtane.Client";
public const string DefaultTheme = "Oqtane.Themes.OqtaneTheme.Default, Oqtane.Client";
[Obsolete("DefaultLayout is deprecated")]
public const string DefaultLayout = "";
public const string DefaultContainer = "Oqtane.Themes.OqtaneTheme.Container, Oqtane.Client";
public const string DefaultAdminContainer = "Oqtane.Themes.AdminContainer, Oqtane.Client";
public const string ActionToken = "{Action}";
public const string DefaultAction = "Index";
[Obsolete("Use PaneNames.Admin")]
public const string AdminPane = PaneNames.Admin;
public static readonly string[] ReservedRoutes = { "api", "pages", "files" };
public const string ModuleDelimiter = "*";
public const string UrlParametersDelimiter = "!";
@ -42,29 +37,13 @@ namespace Oqtane.Shared
public const string DefaultSiteTemplate = "Oqtane.SiteTemplates.DefaultSiteTemplate, Oqtane.Server";
public const string ContentUrl = "/api/file/download/";
public const string FileUrl = "/files/";
public const string ImageUrl = "/api/file/image/";
public const int UserFolderCapacity = 20; // megabytes
public const string PackagesFolder = "Packages";
[Obsolete("Use UserNames.Host instead.")]
public const string HostUser = UserNames.Host;
[Obsolete("Use TenantNames.Master instead")]
public const string MasterTenant = TenantNames.Master;
public const string DefaultSite = "Default Site";
const string RoleObsoleteMessage = "Use the corresponding member from Oqtane.Shared.RoleNames";
[Obsolete(RoleObsoleteMessage)]
public const string AllUsersRole = RoleNames.Everyone;
[Obsolete(RoleObsoleteMessage)]
public const string HostRole = RoleNames.Host;
[Obsolete(RoleObsoleteMessage)]
public const string AdminRole = RoleNames.Admin;
[Obsolete(RoleObsoleteMessage)]
public const string RegisteredRole = RoleNames.Registered;
public const string ImageFiles = "jpg,jpeg,jpe,gif,bmp,png,ico,webp";
public const string UploadableFiles = ImageFiles + ",mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg,csv,json,xml,xslt,rss,html,htm,css";
public const string ReservedDevices = "CON,NUL,PRN,COM0,COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8,COM9,LPT0,LPT1,LPT2,LPT3,LPT4,LPT5,LPT6,LPT7,LPT8,LPT9,CONIN$,CONOUT$";
@ -93,5 +72,33 @@ namespace Oqtane.Shared
public static readonly string HttpContextSiteSettingsKey = "SiteSettings";
public static readonly string MauiUserAgent = "MAUI";
// Obsolete constants
const string RoleObsoleteMessage = "Use the corresponding member from Oqtane.Shared.RoleNames";
[Obsolete(RoleObsoleteMessage)]
public const string AllUsersRole = RoleNames.Everyone;
[Obsolete(RoleObsoleteMessage)]
public const string HostRole = RoleNames.Host;
[Obsolete(RoleObsoleteMessage)]
public const string AdminRole = RoleNames.Admin;
[Obsolete(RoleObsoleteMessage)]
public const string RegisteredRole = RoleNames.Registered;
[Obsolete("DefaultLayout is deprecated")]
public const string DefaultLayout = "";
[Obsolete("Use PaneNames.Admin")]
public const string AdminPane = PaneNames.Admin;
[Obsolete("Use UserNames.Host instead.")]
public const string HostUser = UserNames.Host;
[Obsolete("Use TenantNames.Master instead")]
public const string MasterTenant = TenantNames.Master;
// [Obsolete("Use FileUrl instead")]
public const string ContentUrl = "/api/file/download/";
}
}

View File

@ -98,23 +98,28 @@ namespace Oqtane.Shared
return NavigateUrl(alias, path, parameters);
}
public static string ContentUrl(Alias alias, int fileId)
{
return ContentUrl(alias, fileId, false);
}
public static string ContentUrl(Alias alias, int fileId, bool asAttachment)
{
var aliasUrl = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path : "";
var method = asAttachment ? "/attach" : "";
return $"{alias.BaseUrl}{aliasUrl}{Constants.ContentUrl}{fileId}{method}";
}
public static string FileUrl(Alias alias, string folderpath, string filename)
{
return FileUrl(alias, folderpath, filename, false);
}
public static string FileUrl(Alias alias, string folderpath, string filename, bool download)
{
var aliasUrl = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path : "";
return $"{alias.BaseUrl}{aliasUrl}/files/{folderpath.Replace("\\", "/")}{filename}";
var querystring = (download) ? "?download" : "";
return $"{alias?.BaseUrl}{aliasUrl}{Constants.FileUrl}{folderpath.Replace("\\", "/")}{filename}{querystring}";
}
public static string FileUrl(Alias alias, int fileid)
{
return FileUrl(alias, fileid, false);
}
public static string FileUrl(Alias alias, int fileid, bool download)
{
var aliasUrl = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path : "";
var querystring = (download) ? "?download" : "";
return $"{alias?.BaseUrl}{aliasUrl}{Constants.FileUrl}id/{fileid}{querystring}";
}
public static string ImageUrl(Alias alias, int fileId, int width, int height, string mode)
@ -128,25 +133,30 @@ namespace Oqtane.Shared
mode = string.IsNullOrEmpty(mode) ? "crop" : mode;
position = string.IsNullOrEmpty(position) ? "center" : position;
background = string.IsNullOrEmpty(background) ? "000000" : background;
return $"{alias.BaseUrl}{url}{Constants.ImageUrl}{fileId}/{width}/{height}/{mode}/{position}/{background}/{rotate}/{recreate}";
return $"{alias?.BaseUrl}{url}{Constants.ImageUrl}{fileId}/{width}/{height}/{mode}/{position}/{background}/{rotate}/{recreate}";
}
public static string TenantUrl(Alias alias, string url)
{
url = (!url.StartsWith("/")) ? "/" + url : url;
url = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path + url : url;
return $"{alias.BaseUrl}{url}";
return $"{alias?.BaseUrl}{url}";
}
public static string FormatContent(string content, Alias alias, string operation)
{
var aliasUrl = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path : "";
switch (operation)
{
case "save":
content = content.Replace(alias?.BaseUrl + aliasUrl + Constants.FileUrl, Constants.FileUrl);
// legacy
content = content.Replace(UrlCombine("Content", "Tenants", alias.TenantId.ToString(), "Sites", alias.SiteId.ToString()), "[siteroot]");
content = content.Replace(alias.Path + Constants.ContentUrl, Constants.ContentUrl);
break;
case "render":
content = content.Replace(Constants.FileUrl, alias?.BaseUrl + aliasUrl + Constants.FileUrl);
// legacy
content = content.Replace("[siteroot]", UrlCombine("Content", "Tenants", alias.TenantId.ToString(), "Sites", alias.SiteId.ToString()));
content = content.Replace(Constants.ContentUrl, alias.Path + Constants.ContentUrl);
break;
@ -491,5 +501,19 @@ namespace Oqtane.Shared
return (localDateTime?.Date, localTime);
}
[Obsolete("ContentUrl(Alias alias, int fileId) is deprecated. Use FileUrl(Alias alias, int fileId) instead.", false)]
public static string ContentUrl(Alias alias, int fileId)
{
return ContentUrl(alias, fileId, false);
}
[Obsolete("ContentUrl(Alias alias, int fileId, bool asAttachment) is deprecated. Use FileUrl(Alias alias, int fileId, bool download) instead.", false)]
public static string ContentUrl(Alias alias, int fileId, bool asAttachment)
{
var aliasUrl = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path : "";
var method = asAttachment ? "/attach" : "";
return $"{alias?.BaseUrl}{aliasUrl}{Constants.ContentUrl}{fileId}{method}";
}
}
}