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); public unsafe static extern bool http_set_managed_context(IntPtr pHttpContext, IntPtr pvManagedContext);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
[return: MarshalAs(UnmanagedType.BStr)] public unsafe static extern int http_get_application_paths([MarshalAs(UnmanagedType.BStr)] out string fullPath, [MarshalAs(UnmanagedType.BStr)] out string virtualPath);
public unsafe static extern string http_get_application_full_path();
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public unsafe static extern bool http_shutdown(); public unsafe static extern bool http_shutdown();

View File

@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
_pipeFactory = pipeFactory; _pipeFactory = pipeFactory;
_pHttpContext = pHttpContext; _pHttpContext = pHttpContext;
NativeMethods.http_set_managed_context(pHttpContext, (IntPtr)_thisHandle); NativeMethods.http_set_managed_context(_pHttpContext, (IntPtr)_thisHandle);
unsafe unsafe
{ {
Method = GetVerb(); Method = GetVerb();
@ -80,27 +80,17 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
var originalPath = RequestUriBuilder.DecodeAndUnescapePath(GetRawUrlInBytes()); 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)) if (KnownMethod == HttpApiTypes.HTTP_VERB.HttpVerbOPTIONS && string.Equals(RawTarget, "*", StringComparison.Ordinal))
{ {
PathBase = string.Empty; PathBase = string.Empty;
Path = 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 else
{ {
// url: /base/path, prefix: /base/, base: /base, path: /path // Path and pathbase are unescaped by RequestUriBuilder
// url: /, prefix: /, base: , path: / // The UsePathBase middleware will modify the pathbase and path correctly
PathBase = originalPath.Substring(0, prefix.Length - 1); PathBase = string.Empty;
Path = originalPath.Substring(prefix.Length - 1); Path = originalPath;
} }
var cookedUrl = GetCookedUrl(); var cookedUrl = GetCookedUrl();

View File

@ -9,7 +9,6 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Server.IISIntegration namespace Microsoft.AspNetCore.Server.IISIntegration
{ {
@ -38,7 +37,6 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
_iisContextFactory = new IISContextFactory<TContext>(_pipeFactory, application); _iisContextFactory = new IISContextFactory<TContext>(_pipeFactory, application);
// Start the server by registering the callback // 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); NativeMethods.register_callbacks(_requestHandler, _shutdownHandler, _onAsyncCompletion, (IntPtr)_httpServerHandle, (IntPtr)_httpServerHandle);
return Task.CompletedTask; 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.UseSetting(nameof(UseIISIntegration), "true");
hostBuilder.CaptureStartupErrors(true); hostBuilder.CaptureStartupErrors(true);
var applicationPath = NativeMethods.http_get_application_full_path(); // TODO consider adding a configuration load where all variables needed are loaded from ANCM in one call.
hostBuilder.UseContentRoot(applicationPath); 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 => return hostBuilder.ConfigureServices(services =>
{ {
services.AddSingleton<IServer, IISHttpServer>(); services.AddSingleton<IServer, IISHttpServer>();
services.AddSingleton<IStartupFilter>(new IISServerSetupFilter(virtualPath));
services.AddAuthenticationCore(); services.AddAuthenticationCore();
}); });
} }