Be more defensive in HtmlDirectoryFormatter (#9755)
Fixes aspnet/AspNetCore-Internal#2245 Our tests were flaking out due to this possible race where the directory browser middleware enumerates the directory but a file is deleted while we're formatting the response. This change just catches the FNF/DNF exceptions and suppresses the file from the directory listing
This commit is contained in:
parent
49ae712294
commit
fe3dfe627b
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
|
@ -33,7 +34,7 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
throw new ArgumentNullException(nameof(encoder));
|
||||
}
|
||||
_htmlEncoder = encoder;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates an HTML view for a directory.
|
||||
|
|
@ -81,8 +82,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
margin-top: 5px;
|
||||
margin-bottom: 0px;}
|
||||
#index {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
margin: 0 0 20px; }
|
||||
#index th {
|
||||
vertical-align: bottom;
|
||||
|
|
@ -132,27 +133,66 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
|
||||
foreach (var subdir in contents.Where(info => info.IsDirectory))
|
||||
{
|
||||
builder.AppendFormat(@"
|
||||
// Collect directory metadata in a try...catch in case the file is deleted while we're getting the data.
|
||||
// The metadata is retrieved prior to calling AppendFormat so if it throws, we won't have written a row
|
||||
// to the table.
|
||||
try
|
||||
{
|
||||
builder.AppendFormat(@"
|
||||
<tr class=""directory"">
|
||||
<td class=""name""><a href=""./{0}/"">{0}/</a></td>
|
||||
<td></td>
|
||||
<td class=""modified"">{1}</td>
|
||||
</tr>",
|
||||
HtmlEncode(subdir.Name),
|
||||
HtmlEncode(subdir.LastModified.ToString(CultureInfo.CurrentCulture)));
|
||||
HtmlEncode(subdir.Name),
|
||||
HtmlEncode(subdir.LastModified.ToString(CultureInfo.CurrentCulture)));
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
// The physical DirectoryInfo class doesn't appear to throw for either
|
||||
// of Name or LastWriteTimeUtc (which backs LastModified in the physical provider)
|
||||
// if the directory doesn't exist. However, we don't know what other providers might do.
|
||||
|
||||
// Just skip this directory. It was deleted while we were enumerating.
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
// The physical DirectoryInfo class doesn't appear to throw for either
|
||||
// of Name or LastWriteTimeUtc (which backs LastModified in the physical provider)
|
||||
// if the directory doesn't exist. However, we don't know what other providers might do.
|
||||
|
||||
// Just skip this directory. It was deleted while we were enumerating.
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var file in contents.Where(info => !info.IsDirectory))
|
||||
{
|
||||
builder.AppendFormat(@"
|
||||
// Collect file metadata in a try...catch in case the file is deleted while we're getting the data.
|
||||
// The metadata is retrieved prior to calling AppendFormat so if it throws, we won't have written a row
|
||||
// to the table.
|
||||
try
|
||||
{
|
||||
builder.AppendFormat(@"
|
||||
<tr class=""file"">
|
||||
<td class=""name""><a href=""./{0}"">{0}</a></td>
|
||||
<td class=""length"">{1}</td>
|
||||
<td class=""modified"">{2}</td>
|
||||
</tr>",
|
||||
HtmlEncode(file.Name),
|
||||
HtmlEncode(file.Length.ToString("n0", CultureInfo.CurrentCulture)),
|
||||
HtmlEncode(file.LastModified.ToString(CultureInfo.CurrentCulture)));
|
||||
HtmlEncode(file.Name),
|
||||
HtmlEncode(file.Length.ToString("n0", CultureInfo.CurrentCulture)),
|
||||
HtmlEncode(file.LastModified.ToString(CultureInfo.CurrentCulture)));
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
// There doesn't appear to be a case where DirectoryNotFound is thrown in the physical provider,
|
||||
// but we don't know what other providers might do.
|
||||
|
||||
// Just skip this file. It was deleted while we were enumerating.
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
// Just skip this file. It was deleted while we were enumerating.
|
||||
}
|
||||
}
|
||||
|
||||
builder.Append(@"
|
||||
|
|
|
|||
Loading…
Reference in New Issue