Permalink
Browse files

Resolve major perf issue and lazily move disk access till after catch…

… all handlers
  • Loading branch information...
mythz committed Nov 18, 2017
1 parent 2aa1f65 commit 133c258d032d0e428d58cbfdfd270b1660ce1328
@@ -81,7 +81,6 @@ public void Register(IAppHost appHost)
IVirtualFile patchFile = null;
switch (pathInfo)
{
case "/swagger-ui":
case "/swagger-ui/":
case "/swagger-ui/default.html":
indexFile = appHost.VirtualFileSources.GetFile("/swagger-ui/index.html");
@@ -117,7 +116,9 @@ public void Register(IAppHost appHost)
return html;
});
}
return pathInfo.StartsWith("/swagger-ui") ? new StaticFileHandler() : null;
return pathInfo.StartsWith("/swagger-ui/")
? new StaticFileHandler()
: null;
});
}
}
@@ -65,9 +65,7 @@ public AspNetRequest(HttpContextBase httpContext, string operationName, RequestA
}

this.PathInfo = this.OriginalPathInfo = GetPathInfo();
this.PathInfo = HostContext.AppHost.ResolvePathInfo(this, OriginalPathInfo, out bool isDirectory);
this.IsDirectory = isDirectory;
this.IsFile = !isDirectory && HostContext.VirtualFileSources.FileExists(PathInfo);
this.PathInfo = HostContext.AppHost.ResolvePathInfo(this, OriginalPathInfo);
}

public HttpRequestBase HttpRequest => request;
@@ -333,13 +331,41 @@ public IHttpFile[] Files
public Uri UrlReferrer => request.UrlReferrer;


public IVirtualFile GetFile() => HostContext.VirtualFileSources.GetFile(PathInfo);
private IVirtualFile file;
public IVirtualFile GetFile() => file ?? (file = HostContext.VirtualFileSources.GetFile(PathInfo));

public IVirtualDirectory GetDirectory() => HostContext.VirtualFileSources.GetDirectory(PathInfo);
private IVirtualDirectory dir;
public IVirtualDirectory GetDirectory() => dir ?? (dir = HostContext.VirtualFileSources.GetDirectory(PathInfo));

public bool IsDirectory { get; }
private bool? isDirectory;
public bool IsDirectory
{
get
{
if (isDirectory == null)
{
isDirectory = dir != null || HostContext.VirtualFileSources.DirectoryExists(PathInfo);
if (isDirectory == true)
isFile = false;
}
return isDirectory.Value;
}
}

public bool IsFile { get; }
private bool? isFile;
public bool IsFile
{
get
{
if (isFile == null)
{
isFile = GetFile() != null;
if (isFile == true)
isDirectory = false;
}
return isFile.Value;
}
}
}

}
@@ -37,9 +37,7 @@ public ListenerRequest(HttpListenerContext httpContext, string operationName, Re

this.RequestPreferences = new RequestPreferences(this);
this.PathInfo = this.OriginalPathInfo = GetPathInfo();
this.PathInfo = HostContext.AppHost.ResolvePathInfo(this, OriginalPathInfo, out bool isDirectory);
this.IsDirectory = isDirectory;
this.IsFile = !isDirectory && HostContext.VirtualFileSources.FileExists(PathInfo);
this.PathInfo = HostContext.AppHost.ResolvePathInfo(this, OriginalPathInfo);
}

private string GetPathInfo()
@@ -307,13 +305,41 @@ public static string NormalizePathInfo(string pathInfo, string handlerPath)
return pathInfo;
}

public IVirtualFile GetFile() => HostContext.VirtualFileSources.GetFile(PathInfo);
private IVirtualFile file;
public IVirtualFile GetFile() => file ?? (file = HostContext.VirtualFileSources.GetFile(PathInfo));

public IVirtualDirectory GetDirectory() => HostContext.VirtualFileSources.GetDirectory(PathInfo);
private IVirtualDirectory dir;
public IVirtualDirectory GetDirectory() => dir ?? (dir = HostContext.VirtualFileSources.GetDirectory(PathInfo));

public bool IsDirectory { get; }
private bool? isDirectory;
public bool IsDirectory
{
get
{
if (isDirectory == null)
{
isDirectory = dir != null || HostContext.VirtualFileSources.DirectoryExists(PathInfo);
if (isDirectory == true)
isFile = false;
}
return isDirectory.Value;
}
}

public bool IsFile { get; }
private bool? isFile;
public bool IsFile
{
get
{
if (isFile == null)
{
isFile = GetFile() != null;
if (isFile == true)
isDirectory = false;
}
return isFile.Value;
}
}
}

}
@@ -43,9 +43,7 @@ public NetCoreRequest(HttpContext context, string operationName, RequestAttribut

//Kestrel does not decode '+' into space
this.PathInfo = this.OriginalPathInfo = (pathInfo ?? request.Path.Value).Replace("+", " ");
this.PathInfo = HostContext.AppHost.ResolvePathInfo(this, PathInfo, out bool isDirectory);
this.IsDirectory = isDirectory;
this.IsFile = !isDirectory && HostContext.VirtualFileSources.FileExists(PathInfo);
this.PathInfo = HostContext.AppHost.ResolvePathInfo(this, PathInfo);
}

public T TryResolve<T>()
@@ -279,14 +277,43 @@ public Uri UrlReferrer
private string remoteIp;
public string RemoteIp =>
remoteIp ?? (remoteIp = XForwardedFor ?? (XRealIp ?? UserHostAddress));


public IVirtualFile GetFile() => HostContext.VirtualFileSources.GetFile(PathInfo);
private IVirtualFile file;
public IVirtualFile GetFile() => file ?? (file = HostContext.VirtualFileSources.GetFile(PathInfo));

public IVirtualDirectory GetDirectory() => HostContext.VirtualFileSources.GetDirectory(PathInfo);
private IVirtualDirectory dir;
public IVirtualDirectory GetDirectory() => dir ?? (dir = HostContext.VirtualFileSources.GetDirectory(PathInfo));

public bool IsDirectory { get; }
private bool? isDirectory;
public bool IsDirectory
{
get
{
if (isDirectory == null)
{
isDirectory = dir != null || HostContext.VirtualFileSources.DirectoryExists(PathInfo);
if (isDirectory == true)
isFile = false;
}
return isDirectory.Value;
}
}

public bool IsFile { get; }
private bool? isFile;
public bool IsFile
{
get
{
if (isFile == null)
{
isFile = GetFile() != null;
if (isFile == true)
isDirectory = false;
}
return isFile.Value;
}
}
}
}

@@ -253,12 +253,6 @@ public static IHttpHandler GetHandlerForPathInfo(IHttpRequest httpReq, string fi
var appHost = HostContext.AppHost;

var pathInfo = httpReq.PathInfo;
var isFile = httpReq.IsFile();
var isDirectory = httpReq.IsDirectory();

if (!isFile && !isDirectory && Env.IsMono)
isDirectory = StaticFileHandler.MonoDirectoryExists(filePath, filePath.Substring(0, filePath.Length - pathInfo.Length));

var httpMethod = httpReq.Verb;

var pathParts = pathInfo.TrimStart('/').Split('/');
@@ -268,16 +262,22 @@ public static IHttpHandler GetHandlerForPathInfo(IHttpRequest httpReq, string fi
if (restPath != null)
return new RestHandler { RestPath = restPath, RequestName = restPath.RequestType.GetOperationName(), ResponseContentType = contentType };

var catchAllHandler = GetCatchAllHandlerIfAny(httpMethod, pathInfo, filePath);
if (catchAllHandler != null)
return catchAllHandler;

var isFile = httpReq.IsFile();
var isDirectory = httpReq.IsDirectory();

if (!isFile && !isDirectory && Env.IsMono)
isDirectory = StaticFileHandler.MonoDirectoryExists(filePath, filePath.Substring(0, filePath.Length - pathInfo.Length));

if (isFile || isDirectory)
{
//If pathInfo is for Directory try again with redirect including '/' suffix
if (appHost.Config.RedirectDirectoriesToTrailingSlashes && isDirectory && !httpReq.OriginalPathInfo.EndsWith("/"))
return new RedirectHttpHandler { RelativeUrl = pathInfo + "/" };

var catchAllHandler = GetCatchAllHandlerIfAny(httpMethod, pathInfo, filePath);
if (catchAllHandler != null)
return catchAllHandler;

if (isDirectory)
return StaticFilesHandler;

@@ -286,9 +286,6 @@ public static IHttpHandler GetHandlerForPathInfo(IHttpRequest httpReq, string fi
: ForbiddenHttpHandler;
}

var handler = GetCatchAllHandlerIfAny(httpMethod, pathInfo, filePath);
if (handler != null) return handler;

if (appHost.Config.FallbackRestPath != null)
{
restPath = appHost.Config.FallbackRestPath(httpReq);
@@ -980,14 +980,9 @@ public virtual string MapProjectPath(string relativePath)
return relativePath.MapProjectPath();
}

public virtual string ResolvePathInfo(IRequest request, string originalPathInfo, out bool isDirectory)
public virtual string ResolvePathInfo(IRequest request, string originalPathInfo)
{
var pathInfo = NormalizePathInfo(originalPathInfo, Config.HandlerFactoryPath);
isDirectory = VirtualFileSources.DirectoryExists(pathInfo);

if (!isDirectory && pathInfo.Length > 1 && pathInfo[pathInfo.Length - 1] == '/')
pathInfo = pathInfo.TrimEnd('/');

var pathInfo = NormalizePathInfo(originalPathInfo, Config.HandlerFactoryPath);
return pathInfo;
}

@@ -124,6 +124,11 @@ protected virtual IHttpHandler RequestHandler(string httpMethod, string pathInfo
{
if (page.File.Name.StartsWith("_"))
return new ForbiddenHttpHandler();

//If it's a dir index page and doesn't have a trailing '/' let it pass through to RedirectDirectoriesToTrailingSlashes
if (pathInfo[pathInfo.Length - 1] != '/' && pathInfo.Substring(1) == page.File.Directory?.VirtualPath)
return null;

return new TemplatePageHandler(page);
}

@@ -64,8 +64,8 @@ public override void Configure(Container container)
});
}

public override string ResolvePathInfo(IRequest request, string originalPathInfo, out bool isDirectory) =>
base.ResolvePathInfo(request, originalPathInfo.Replace("/testsite", "/TestSite"), out isDirectory);
public override string ResolvePathInfo(IRequest request, string originalPathInfo) =>
base.ResolvePathInfo(request, originalPathInfo.Replace("/testsite", "/TestSite"));

// public override RouteAttribute[] GetRouteAttributes(Type requestType)
// {

0 comments on commit 133c258

Please sign in to comment.