// 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 System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Text.Encodings.Web; using System.Threading.Tasks; using Microsoft.AspNet.FileProviders; using Microsoft.AspNet.Http; using Microsoft.Extensions.WebEncoders; namespace Microsoft.AspNet.StaticFiles { /// /// Generates an HTML view for a directory. /// public class HtmlDirectoryFormatter : IDirectoryFormatter { private const string TextHtmlUtf8 = "text/html; charset=utf-8"; private static HtmlEncoder _htmlEncoder; /// /// Generates an HTML view for a directory. /// public virtual Task GenerateContentAsync(HttpContext context, IEnumerable contents) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (contents == null) { throw new ArgumentNullException(nameof(contents)); } if (_htmlEncoder == null) { _htmlEncoder = context.ApplicationServices.GetHtmlEncoder(); } context.Response.ContentType = TextHtmlUtf8; if (Helpers.IsHeadMethod(context.Request.Method)) { // HEAD, no response body return Constants.CompletedTask; } PathString requestPath = context.Request.PathBase + context.Request.Path; var builder = new StringBuilder(); builder.AppendFormat( @" ", CultureInfo.CurrentUICulture.TwoLetterISOLanguageName); builder.AppendFormat(@" {0} {1}", HtmlEncode(Resources.HtmlDir_IndexOf), HtmlEncode(requestPath.Value)); builder.Append(@"
"); builder.AppendFormat(@"

{0} /", HtmlEncode(Resources.HtmlDir_IndexOf)); string cumulativePath = "/"; foreach (var segment in requestPath.Value.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries)) { cumulativePath = cumulativePath + segment + "/"; builder.AppendFormat(@"{1}/", HtmlEncode(cumulativePath), HtmlEncode(segment)); } builder.AppendFormat(CultureInfo.CurrentUICulture, @"

", HtmlEncode(Resources.HtmlDir_TableSummary), HtmlEncode(Resources.HtmlDir_Name), HtmlEncode(Resources.HtmlDir_Size), HtmlEncode(Resources.HtmlDir_Modified), HtmlEncode(Resources.HtmlDir_LastModified)); foreach (var subdir in contents.Where(info => info.IsDirectory)) { builder.AppendFormat(@" ", HtmlEncode(subdir.Name), HtmlEncode(subdir.LastModified.ToString(CultureInfo.CurrentCulture))); } foreach (var file in contents.Where(info => !info.IsDirectory)) { builder.AppendFormat(@" ", HtmlEncode(file.Name), HtmlEncode(file.Length.ToString("n0", CultureInfo.CurrentCulture)), HtmlEncode(file.LastModified.ToString(CultureInfo.CurrentCulture))); } builder.Append(@"
{1}{2}{4}
{0}/ {1}
{0} {1} {2}
"); string data = builder.ToString(); byte[] bytes = Encoding.UTF8.GetBytes(data); context.Response.ContentLength = bytes.Length; return context.Response.Body.WriteAsync(bytes, 0, bytes.Length); } private static string HtmlEncode(string body) { return _htmlEncoder.Encode(body); } } }