Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,42 @@ public static partial class HostingEnvironment
public static string ApplicationID { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public static bool IsHosted { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public static string SiteName { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public static System.Web.Hosting.VirtualPathProvider VirtualPathProvider { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public static void RegisterVirtualPathProvider(System.Web.Hosting.VirtualPathProvider provider) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
}
public abstract partial class VirtualDirectory : System.Web.Hosting.VirtualFileBase
{
protected VirtualDirectory(string virtualPath) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public abstract System.Collections.IEnumerable Children { get; }
public abstract System.Collections.IEnumerable Directories { get; }
public abstract System.Collections.IEnumerable Files { get; }
public override bool IsDirectory { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
}
public abstract partial class VirtualFile : System.Web.Hosting.VirtualFileBase
{
protected VirtualFile(string virtualPath) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public override bool IsDirectory { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public abstract System.IO.Stream Open();
}
public abstract partial class VirtualFileBase
{
internal VirtualFileBase() { }
public abstract bool IsDirectory { get; }
public virtual string Name { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public string VirtualPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
}
public abstract partial class VirtualPathProvider
{
protected VirtualPathProvider() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
protected internal System.Web.Hosting.VirtualPathProvider Previous { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public virtual string CombineVirtualPaths(string basePath, string relativePath) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual bool DirectoryExists(string virtualDir) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual bool FileExists(string virtualPath) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual System.Web.Caching.CacheDependency GetCacheDependency(string virtualPath, System.Collections.IEnumerable virtualPathDependencies, System.DateTime utcStart) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual System.Web.Hosting.VirtualDirectory GetDirectory(string virtualDir) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual System.Web.Hosting.VirtualFile GetFile(string virtualPath) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
public virtual string GetFileHash(string virtualPath, System.Collections.IEnumerable virtualPathDependencies) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
protected virtual void Initialize() { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
}
}
namespace System.Web.Security
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.Caching.CacheItemUpdateReason))]
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.Configuration.HttpCapabilitiesBase))]
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.Hosting.HostingEnvironment))]
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.Hosting.VirtualDirectory))]
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.Hosting.VirtualFile))]
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.Hosting.VirtualFileBase))]
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.Hosting.VirtualPathProvider))]
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.Security.MachineKey))]
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.SessionState.HttpSessionState))]
[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Web.SessionState.SessionStateBehavior))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,13 @@ public static class HostingEnvironment
public static bool IsHosted => HostingEnvironmentAccessor.TryGet(out var current) && current.Options.IsHosted;

public static string SiteName => HostingEnvironmentAccessor.Current.Options.SiteName;

public static VirtualPathProvider? VirtualPathProvider => HostingEnvironmentAccessor.Current.Options.VirtualPathProvider;

public static void RegisterVirtualPathProvider(VirtualPathProvider provider)
{
ArgumentNullException.ThrowIfNull(provider);

HostingEnvironmentAccessor.Current.Options.VirtualPathProvider = provider;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections;

namespace System.Web.Hosting;

public abstract class VirtualDirectory : VirtualFileBase
{
protected VirtualDirectory(string virtualPath)
: base(VirtualPathUtility.AppendTrailingSlash(virtualPath))
{
}

public override bool IsDirectory => true;

/// <summary>
/// Returns an object that enumerates all the children VirtualDirectory's of this directory.
/// </summary>
public abstract IEnumerable Directories { get; }

/// <summary>
///Returns an object that enumerates all the children VirtualFile's of this directory.
/// </summary>
public abstract IEnumerable Files { get; }

/// <summary>
/// Returns an object that enumerates all the children VirtualDirectory's and VirtualFiles of this directory.
/// </summary>
public abstract IEnumerable Children { get; }
}
18 changes: 18 additions & 0 deletions src/Microsoft.AspNetCore.SystemWebAdapters/Hosting/VirtualFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.IO;

namespace System.Web.Hosting;

public abstract class VirtualFile : VirtualFileBase
{
protected VirtualFile(string virtualPath)
: base(virtualPath)
{
}

public override bool IsDirectory => false;

public abstract Stream Open();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.Web.Hosting;

public abstract class VirtualFileBase
{
private protected VirtualFileBase(string virtualPath)
{
VirtualPath = virtualPath;
}

public virtual string Name => VirtualPathUtility.GetFileName(VirtualPath);

public string VirtualPath { get; }

public abstract bool IsDirectory { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections;
using System.Web.Caching;
using System.Web.Util;

namespace System.Web.Hosting;

public abstract class VirtualPathProvider
{
internal virtual void Initialize(VirtualPathProvider? previous)
{
Previous = previous;
Initialize();
}

protected virtual void Initialize()
{
}

protected internal VirtualPathProvider? Previous { get; private set; }

public virtual string? GetFileHash(string virtualPath, IEnumerable virtualPathDependencies)
=> Previous?.GetFileHash(virtualPath, virtualPathDependencies);

public virtual CacheDependency? GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart)
=> Previous?.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);

public virtual bool FileExists(string virtualPath) => Previous != null && Previous.FileExists(virtualPath);

public virtual bool DirectoryExists(string virtualDir) => Previous != null && Previous.DirectoryExists(virtualDir);

public virtual VirtualFile? GetFile(string virtualPath) => Previous?.GetFile(virtualPath);

internal VirtualFile? GetFileWithCheck(string virtualPath)
{
var virtualFile = GetFile(virtualPath);

if (virtualFile == null)
{
return null;
}

// Make sure the VirtualFile's path is the same as what was passed to GetFile
if (!string.Equals(virtualPath, virtualFile.VirtualPath, StringComparison.OrdinalIgnoreCase))
{
throw new HttpException($"Bad virtual path {virtualFile} in VirtuaPathBase");
}

return virtualFile;
}

public virtual VirtualDirectory? GetDirectory(string virtualDir) => Previous?.GetDirectory(virtualDir);

public virtual string CombineVirtualPaths(string basePath, string relativePath)
{
if (string.IsNullOrEmpty(basePath))
{
throw new ArgumentException($"'{nameof(basePath)}' cannot be null or empty.", nameof(basePath));
}

var baseDir = UrlPath.GetDirectory(basePath);

// By default, just combine them normally
return VirtualPathUtility.Combine(baseDir, relativePath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
#if NETCOREAPP

using System;
using System.Web.Hosting;

namespace Microsoft.AspNetCore.SystemWebAdapters;

public class SystemWebAdaptersOptions
{
private VirtualPathProvider? _virtualPathProvider;

public string ApplicationID { get; set; } = string.Empty;

public bool IsHosted { get; set; }
Expand All @@ -18,6 +21,20 @@ public class SystemWebAdaptersOptions
public string AppDomainAppVirtualPath { get; set; } = "/";

public string AppDomainAppPath { get; set; } = AppContext.BaseDirectory;

/// <summary>
/// Gets or sets the value used by <see cref="HostingEnvironment.VirtualPathProvider"/>.
/// </summary>
public VirtualPathProvider? VirtualPathProvider
{
get => _virtualPathProvider;
set
{
value?.Initialize(_virtualPathProvider);

_virtualPathProvider = value;
}
}
}

#endif
30 changes: 30 additions & 0 deletions src/Microsoft.AspNetCore.SystemWebAdapters/Utilities/UrlPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,35 @@ private static bool HasScheme(string virtualPath)
return indexOfSlash == -1 || indexOfColon < indexOfSlash;
}

internal static string GetDirectory(string path)
{
if (string.IsNullOrEmpty(path))
{
throw new ArgumentException("Path must not be empty", nameof(path));
}

if (path[0] != '/' && path[0] != AppRelativeCharacter)
{
throw new ArgumentException($"Path {path} must be rooted");
}

// If it's just "~" or "/", return it unchanged
if (path.Length == 1)
{
return path;
}

int slashIndex = path.LastIndexOf('/');

// This could happen if the input looks like "~abc"
if (slashIndex < 0)
{
throw new ArgumentException($"Path {path} must be rooted");
}

return path[..(slashIndex + 1)];
}

private static bool IsDirectorySeparatorChar(char ch) => ch == '\\' || ch == '/';

// e.g \\server\share\foo or //server/share/foo
Expand Down Expand Up @@ -532,6 +561,7 @@ internal string MakeRelative(string fromPath, string toPath)
return relativePath + queryString + toUri.Fragment;
}

[return: NotNullIfNotNull(nameof(virtualPath))]
internal static string? GetFileName(string virtualPath)
{
if (virtualPath is not null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public static class VirtualPathUtility
/// <param name="virtualPath">The virtual path. </param>
/// <exception cref="ArgumentException">
/// <paramref name="virtualPath" /> contains one or more characters that are not valid, as defined in <see cref="IO.Path.InvalidPathChars" />. </exception>

[return: NotNullIfNotNull(nameof(virtualPath))]
public static string? GetFileName(string virtualPath) => VirtualPathUtilityImpl.GetFileName(virtualPath);

/// <summary>Returns a Boolean value indicating whether the specified virtual path is absolute; that is, it starts with a literal slash mark (/).</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public string Combine(string basePath, string relativePath)
return UrlPath.GetExtension(virtualPath);
}

[return: NotNullIfNotNull(nameof(virtualPath))]
public static string? GetFileName(string virtualPath)
{
if (string.IsNullOrEmpty(virtualPath))
Expand Down