/// <summary> /// Performs internal redirects on paths with missing trailings slashes /// and handles redirects to index files /// </summary> /// <returns><c>true</c>, if redirect was issued, <c>false</c> otherwise.</returns> /// <param name="path">The local path to use.</param> /// <param name="context">The request context.</param> protected virtual async Task <bool> AutoRedirect(string path, IHttpContext context) { if (!await m_vfs.FileExistsAsync(path)) { if (string.IsNullOrWhiteSpace(Path.GetExtension(path)) && !path.EndsWith("/", StringComparison.Ordinal) && !path.EndsWith(".", StringComparison.Ordinal)) { var ix = await FirstOrDefault(AutoProbeExtensions, p => m_vfs.FileExistsAsync(path + p)); if (!string.IsNullOrWhiteSpace(ix)) { context.Response.InternalRedirect(context.Request.Path + ix); return(true); } } if (await m_vfs.FolderExistsAsync(path)) { if (!context.Request.Path.EndsWith("/", StringComparison.Ordinal)) { if (!await Any(IndexDocuments, p => m_vfs.FileExistsAsync(Path.Combine(path, p)))) { if (PassThrough) { return(false); } throw new HttpException(HttpStatusCode.NotFound); } context.Response.Redirect(context.Request.Path + "/"); return(true); } var ix = await FirstOrDefault(IndexDocuments, p => m_vfs.FileExistsAsync(Path.Combine(path, p))); if (!string.IsNullOrWhiteSpace(ix)) { context.Response.InternalRedirect(context.Request.Path + ix); return(true); } } } return(false); }