private async Task RouteRequest(HttpListenerContext httpContext) { // Auto-Redirect HTTP to HTTPS if 'HttpsState' is 'Forced'. if (Context.Https == HttpsStates.Forced && !string.Equals("https", httpContext.Request.Url.Scheme, StringComparison.OrdinalIgnoreCase)) { RedirectToSecure(httpContext); return; } var path = httpContext.Request.Url.AbsolutePath.TrimEnd('/'); var root = Context.ListenerPath.TrimEnd('/'); if (path.StartsWith(root)) { path = path.Substring(root.Length); } if (path.Length == 0) { path = "/"; } HttpHandlerResult result = null; var tokenSource = new CancellationTokenSource(); try { result = await GetRouteResult(httpContext, path, tokenSource.Token) ?? HttpHandlerResult.NotFound().SetText($"No content found matching path '{path}'!"); await result.ApplyAsync(httpContext, tokenSource.Token); } catch (Exception) { tokenSource.Cancel(); throw; } finally { try { result?.Dispose(); } catch {} tokenSource.Dispose(); } }
private HttpHandlerResult ProcessContent(HttpListenerContext context, string localPath, ContentDirectory directory) { if (Path.DirectorySeparatorChar != '/') { localPath = localPath.Replace('/', Path.DirectorySeparatorChar); } var localFilename = Path.Combine(directory.DirectoryPath, localPath); // Ensure requested content is within the specified directory // IE, prevent relative path hacking var fullRootPath = Path.GetFullPath(directory.DirectoryPath); var fullLocalFilename = Path.GetFullPath(localFilename); if (!fullLocalFilename.StartsWith(fullRootPath)) { return(HttpHandlerResult.NotFound() .SetText($"Requested file is outisde of the content directory! [{fullLocalFilename}]")); } var localFile = new FileInfo(fullLocalFilename); // Ensure file exists if (!localFile.Exists) { return(HttpHandlerResult.NotFound() .SetText($"File not found! [{fullLocalFilename}]")); } // HTTP Caching - Last-Modified var ifModifiedSince = context.Request.Headers.Get("If-Modified-Since"); if (DateTime.TryParse(ifModifiedSince, out var ifModifiedSinceValue)) { if (localFile.LastWriteTime.TrimMilliseconds() <= ifModifiedSinceValue) { return(HttpHandlerResult.Status(HttpStatusCode.NotModified)); } } return(HttpHandlerResult.File(Context, fullLocalFilename) .SetHeader("Last-Modified", localFile.LastWriteTimeUtc.ToString("r"))); }