Parse Path and PathBase from Virtual Directory. (#457)

This commit is contained in:
Justin Kotalik 2017-10-25 12:35:13 -07:00 committed by GitHub
parent bd62aa88d7
commit 94c895a1bd
5 changed files with 44 additions and 21 deletions

View File

@ -75,8 +75,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
public unsafe static extern bool http_set_managed_context(IntPtr pHttpContext, IntPtr pvManagedContext);
[DllImport(AspNetCoreModuleDll)]
[return: MarshalAs(UnmanagedType.BStr)]
public unsafe static extern string http_get_application_full_path();
public unsafe static extern int http_get_application_paths([MarshalAs(UnmanagedType.BStr)] out string fullPath, [MarshalAs(UnmanagedType.BStr)] out string virtualPath);
[DllImport(AspNetCoreModuleDll)]
public unsafe static extern bool http_shutdown();

View File

@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
_pipeFactory = pipeFactory;
_pHttpContext = pHttpContext;
NativeMethods.http_set_managed_context(pHttpContext, (IntPtr)_thisHandle);
NativeMethods.http_set_managed_context(_pHttpContext, (IntPtr)_thisHandle);
unsafe
{
Method = GetVerb();
@ -80,27 +80,17 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
var originalPath = RequestUriBuilder.DecodeAndUnescapePath(GetRawUrlInBytes());
// TODO: Read this from IIS config
// See https://github.com/aspnet/IISIntegration/issues/427
var prefix = "/";
if (KnownMethod == HttpApiTypes.HTTP_VERB.HttpVerbOPTIONS && string.Equals(RawTarget, "*", StringComparison.Ordinal))
{
PathBase = string.Empty;
Path = string.Empty;
}
// These paths are both unescaped already.
else if (originalPath.Length == prefix.Length - 1)
{
// They matched exactly except for the trailing slash.
PathBase = originalPath;
Path = string.Empty;
}
else
{
// url: /base/path, prefix: /base/, base: /base, path: /path
// url: /, prefix: /, base: , path: /
PathBase = originalPath.Substring(0, prefix.Length - 1);
Path = originalPath.Substring(prefix.Length - 1);
// Path and pathbase are unescaped by RequestUriBuilder
// The UsePathBase middleware will modify the pathbase and path correctly
PathBase = string.Empty;
Path = originalPath;
}
var cookedUrl = GetCookedUrl();

View File

@ -9,7 +9,6 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Server.IISIntegration
{
@ -38,7 +37,6 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
_iisContextFactory = new IISContextFactory<TContext>(_pipeFactory, application);
// Start the server by registering the callback
// TODO the context may change here for shutdown.
NativeMethods.register_callbacks(_requestHandler, _shutdownHandler, _onAsyncCompletion, (IntPtr)_httpServerHandle, (IntPtr)_httpServerHandle);
return Task.CompletedTask;

View File

@ -0,0 +1,28 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
namespace Microsoft.AspNetCore.Server.IISIntegration
{
internal class IISServerSetupFilter : IStartupFilter
{
private string _virtualPath;
public IISServerSetupFilter(string virtualPath)
{
_virtualPath = virtualPath;
}
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return app =>
{
app.UsePathBase(_virtualPath);
next(app);
};
}
}
}

View File

@ -45,11 +45,19 @@ namespace Microsoft.AspNetCore.Hosting
hostBuilder.UseSetting(nameof(UseIISIntegration), "true");
hostBuilder.CaptureStartupErrors(true);
var applicationPath = NativeMethods.http_get_application_full_path();
hostBuilder.UseContentRoot(applicationPath);
// TODO consider adding a configuration load where all variables needed are loaded from ANCM in one call.
var hResult = NativeMethods.http_get_application_paths(out var fullPath, out var virtualPath);
var exception = Marshal.GetExceptionForHR(hResult);
if (exception != null)
{
throw exception;
}
hostBuilder.UseContentRoot(fullPath);
return hostBuilder.ConfigureServices(services =>
{
services.AddSingleton<IServer, IISHttpServer>();
services.AddSingleton<IStartupFilter>(new IISServerSetupFilter(virtualPath));
services.AddAuthenticationCore();
});
}