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); var interop = new Interop(JSRuntime);
int pos = await interop.GetCaretPosition("rawhtmleditor"); 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); _rawhtml = _rawhtml.Substring(0, pos) + image + _rawhtml.Substring(pos);
_rawfilemanager = false; _rawfilemanager = false;
} }

View File

@ -75,7 +75,7 @@ namespace Oqtane.Modules
var scripts = new List<object>(); var scripts = new List<object>();
foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script)) 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 }); scripts.Add(new { href = url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", es6module = resource.ES6Module });
} }
if (scripts.Any()) if (scripts.Any())
@ -91,7 +91,7 @@ namespace Oqtane.Modules
public string ModulePath() public string ModulePath()
{ {
return "Modules/" + GetType().Namespace + "/"; return PageState?.Alias.BaseUrl + "/Modules/" + GetType().Namespace + "/";
} }
// url methods // url methods
@ -145,14 +145,23 @@ namespace Oqtane.Modules
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters); 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) 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); 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.Models;
using Oqtane.Shared; using Oqtane.Shared;
using Oqtane.UI; using Oqtane.UI;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -49,7 +50,7 @@ namespace Oqtane.Themes
public string ThemePath() public string ThemePath()
{ {
return "Themes/" + GetType().Namespace + "/"; return PageState?.Alias.BaseUrl + "/Themes/" + GetType().Namespace + "/";
} }
// url methods // url methods
@ -94,14 +95,23 @@ namespace Oqtane.Themes
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters); 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) 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); 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)) foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
{ {
var prefix = "app-stylesheet-" + resource.Level.ToString().ToLower(); 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 }); 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()) if (links.Any())

View File

@ -42,6 +42,13 @@ namespace Oqtane.Pages
var folderpath = ""; var folderpath = "";
var filename = ""; var filename = "";
bool download = false;
if (path.Contains("?download"))
{
download = true;
path = path.Substring(0, path.IndexOf("?download"));
}
var segments = path.Split('/'); var segments = path.Split('/');
if (segments.Length > 0) 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 (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); var filepath = _files.GetFilePath(file);
if (System.IO.File.Exists(filepath)) 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 else
{ {
@ -91,7 +114,7 @@ namespace Oqtane.Pages
} }
// broken link // 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)); return PhysicalFile(errorPath, MimeUtilities.GetMimeType(errorPath));
} }
} }

View File

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

View File

@ -16,17 +16,12 @@ namespace Oqtane.Shared
public const string ContainerComponent = "Oqtane.UI.ContainerBuilder, Oqtane.Client"; public const string ContainerComponent = "Oqtane.UI.ContainerBuilder, Oqtane.Client";
public const string DefaultTheme = "Oqtane.Themes.OqtaneTheme.Default, 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 DefaultContainer = "Oqtane.Themes.OqtaneTheme.Container, Oqtane.Client";
public const string DefaultAdminContainer = "Oqtane.Themes.AdminContainer, Oqtane.Client"; public const string DefaultAdminContainer = "Oqtane.Themes.AdminContainer, Oqtane.Client";
public const string ActionToken = "{Action}"; public const string ActionToken = "{Action}";
public const string DefaultAction = "Index"; public const string DefaultAction = "Index";
[Obsolete("Use PaneNames.Admin")]
public const string AdminPane = PaneNames.Admin;
public static readonly string[] ReservedRoutes = { "api", "pages", "files" }; public static readonly string[] ReservedRoutes = { "api", "pages", "files" };
public const string ModuleDelimiter = "*"; public const string ModuleDelimiter = "*";
public const string UrlParametersDelimiter = "!"; public const string UrlParametersDelimiter = "!";
@ -42,29 +37,13 @@ namespace Oqtane.Shared
public const string DefaultSiteTemplate = "Oqtane.SiteTemplates.DefaultSiteTemplate, Oqtane.Server"; 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 string ImageUrl = "/api/file/image/";
public const int UserFolderCapacity = 20; // megabytes public const int UserFolderCapacity = 20; // megabytes
public const string PackagesFolder = "Packages"; 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"; 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 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 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$"; 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 HttpContextSiteSettingsKey = "SiteSettings";
public static readonly string MauiUserAgent = "MAUI"; 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); 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) 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 : ""; 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) 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; mode = string.IsNullOrEmpty(mode) ? "crop" : mode;
position = string.IsNullOrEmpty(position) ? "center" : position; position = string.IsNullOrEmpty(position) ? "center" : position;
background = string.IsNullOrEmpty(background) ? "000000" : background; 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) public static string TenantUrl(Alias alias, string url)
{ {
url = (!url.StartsWith("/")) ? "/" + url : url; url = (!url.StartsWith("/")) ? "/" + url : url;
url = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path + 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) public static string FormatContent(string content, Alias alias, string operation)
{ {
var aliasUrl = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path : "";
switch (operation) switch (operation)
{ {
case "save": 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(UrlCombine("Content", "Tenants", alias.TenantId.ToString(), "Sites", alias.SiteId.ToString()), "[siteroot]");
content = content.Replace(alias.Path + Constants.ContentUrl, Constants.ContentUrl); content = content.Replace(alias.Path + Constants.ContentUrl, Constants.ContentUrl);
break; break;
case "render": 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("[siteroot]", UrlCombine("Content", "Tenants", alias.TenantId.ToString(), "Sites", alias.SiteId.ToString()));
content = content.Replace(Constants.ContentUrl, alias.Path + Constants.ContentUrl); content = content.Replace(Constants.ContentUrl, alias.Path + Constants.ContentUrl);
break; break;
@ -491,5 +501,19 @@ namespace Oqtane.Shared
return (localDateTime?.Date, localTime); 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}";
}
} }
} }