// 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,
@"
| {1} | {2} | {4} |
",
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(@"
| {0}/ |
|
{1} |
",
HtmlEncode(subdir.Name),
HtmlEncode(subdir.LastModified.ToString(CultureInfo.CurrentCulture)));
}
foreach (var file in contents.Where(info => !info.IsDirectory))
{
builder.AppendFormat(@"
| {0} |
{1} |
{2} |
",
HtmlEncode(file.Name),
HtmlEncode(file.Length.ToString("n0", CultureInfo.CurrentCulture)),
HtmlEncode(file.LastModified.ToString(CultureInfo.CurrentCulture)));
}
builder.Append(@"
");
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);
}
}
}