adding some logging statements
This commit is contained in:
parent
3343bb4d23
commit
e94e3dc44e
|
|
@ -1,13 +1,18 @@
|
||||||
using Microsoft.AspNet.Builder;
|
using Microsoft.AspNet.Builder;
|
||||||
using Microsoft.AspNet.FileSystems;
|
using Microsoft.AspNet.FileSystems;
|
||||||
using Microsoft.AspNet.StaticFiles;
|
using Microsoft.AspNet.StaticFiles;
|
||||||
|
using Microsoft.Framework.Logging;
|
||||||
|
using Microsoft.Framework.Logging.Console;
|
||||||
|
|
||||||
namespace StaticFilesSample
|
namespace StaticFilesSample
|
||||||
{
|
{
|
||||||
public class Startup
|
public class Startup
|
||||||
{
|
{
|
||||||
public void Configure(IApplicationBuilder app)
|
public void Configure(IApplicationBuilder app, ILoggerFactory factory)
|
||||||
{
|
{
|
||||||
|
// Displays all log levels
|
||||||
|
factory.AddConsole(LogLevel.Verbose);
|
||||||
|
|
||||||
app.UseFileServer(new FileServerOptions()
|
app.UseFileServer(new FileServerOptions()
|
||||||
{
|
{
|
||||||
EnableDirectoryBrowsing = true,
|
EnableDirectoryBrowsing = true,
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<DevelopmentServerPort>16758</DevelopmentServerPort>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,11 @@
|
||||||
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.Urls http://localhost:12345/"
|
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.Urls http://localhost:12345/"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"Kestrel": "1.0.0-*",
|
||||||
"Microsoft.AspNet.Server.IIS": "1.0.0-*",
|
"Microsoft.AspNet.Server.IIS": "1.0.0-*",
|
||||||
"Microsoft.AspNet.Server.WebListener": "1.0.0-*",
|
"Microsoft.AspNet.Server.WebListener": "1.0.0-*",
|
||||||
"Kestrel": "1.0.0-*",
|
"Microsoft.AspNet.StaticFiles": "1.0.0-*",
|
||||||
"Microsoft.AspNet.StaticFiles": "1.0.0-*"
|
"Microsoft.Framework.Logging.Console": "1.0.0-*"
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
"aspnet50": { },
|
"aspnet50": { },
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Builder;
|
using Microsoft.AspNet.Builder;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.HttpFeature;
|
using Microsoft.AspNet.HttpFeature;
|
||||||
|
using Microsoft.Framework.Logging;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.StaticFiles
|
namespace Microsoft.AspNet.StaticFiles
|
||||||
{
|
{
|
||||||
|
|
@ -20,14 +21,17 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
public class SendFileMiddleware
|
public class SendFileMiddleware
|
||||||
{
|
{
|
||||||
private readonly RequestDelegate _next;
|
private readonly RequestDelegate _next;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the SendFileMiddleware.
|
/// Creates a new instance of the SendFileMiddleware.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="next">The next middleware in the pipeline.</param>
|
/// <param name="next">The next middleware in the pipeline.</param>
|
||||||
public SendFileMiddleware([NotNull] RequestDelegate next)
|
/// <param name="loggerFactory">An <see cref="ILoggerFactory"/> instance used to create loggers.</param>
|
||||||
|
public SendFileMiddleware([NotNull] RequestDelegate next, [NotNull] ILoggerFactory loggerFactory)
|
||||||
{
|
{
|
||||||
_next = next;
|
_next = next;
|
||||||
|
_logger = loggerFactory.Create<SendFileMiddleware>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Invoke(HttpContext context)
|
public Task Invoke(HttpContext context)
|
||||||
|
|
@ -35,7 +39,7 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
// Check if there is a SendFile feature already present
|
// Check if there is a SendFile feature already present
|
||||||
if (context.GetFeature<IHttpSendFileFeature>() == null)
|
if (context.GetFeature<IHttpSendFileFeature>() == null)
|
||||||
{
|
{
|
||||||
context.SetFeature<IHttpSendFileFeature>(new SendFileWrapper(context.Response.Body));
|
context.SetFeature<IHttpSendFileFeature>(new SendFileWrapper(context.Response.Body, _logger));
|
||||||
}
|
}
|
||||||
|
|
||||||
return _next(context);
|
return _next(context);
|
||||||
|
|
@ -44,10 +48,12 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
private class SendFileWrapper : IHttpSendFileFeature
|
private class SendFileWrapper : IHttpSendFileFeature
|
||||||
{
|
{
|
||||||
private readonly Stream _output;
|
private readonly Stream _output;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
internal SendFileWrapper(Stream output)
|
internal SendFileWrapper(Stream output, ILogger logger)
|
||||||
{
|
{
|
||||||
_output = output;
|
_output = output;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not safe for overlapped writes.
|
// Not safe for overlapped writes.
|
||||||
|
|
@ -86,6 +92,10 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fileStream.Seek(offset, SeekOrigin.Begin);
|
fileStream.Seek(offset, SeekOrigin.Begin);
|
||||||
|
if (_logger.IsEnabled(LogLevel.Verbose))
|
||||||
|
{
|
||||||
|
_logger.WriteVerbose(string.Format("Copying bytes {0}-{1} of file {2} to response body", offset, length != null ? (offset + length).ToString() : "*", fileName));
|
||||||
|
}
|
||||||
await StreamCopyOperation.CopyToAsync(fileStream, _output, length, cancel);
|
await StreamCopyOperation.CopyToAsync(fileStream, _output, length, cancel);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ using Microsoft.AspNet.FileSystems;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.HttpFeature;
|
using Microsoft.AspNet.HttpFeature;
|
||||||
using Microsoft.AspNet.StaticFiles.Infrastructure;
|
using Microsoft.AspNet.StaticFiles.Infrastructure;
|
||||||
|
using Microsoft.Framework.Logging;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.StaticFiles
|
namespace Microsoft.AspNet.StaticFiles
|
||||||
{
|
{
|
||||||
|
|
@ -21,6 +22,7 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
private readonly PathString _matchUrl;
|
private readonly PathString _matchUrl;
|
||||||
private readonly HttpRequest _request;
|
private readonly HttpRequest _request;
|
||||||
private readonly HttpResponse _response;
|
private readonly HttpResponse _response;
|
||||||
|
private readonly ILogger _logger;
|
||||||
private string _method;
|
private string _method;
|
||||||
private bool _isGet;
|
private bool _isGet;
|
||||||
private bool _isHead;
|
private bool _isHead;
|
||||||
|
|
@ -40,13 +42,14 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
|
|
||||||
private IList<Tuple<long, long>> _ranges;
|
private IList<Tuple<long, long>> _ranges;
|
||||||
|
|
||||||
public StaticFileContext(HttpContext context, StaticFileOptions options, PathString matchUrl)
|
public StaticFileContext(HttpContext context, StaticFileOptions options, PathString matchUrl, ILogger logger)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_options = options;
|
_options = options;
|
||||||
_matchUrl = matchUrl;
|
_matchUrl = matchUrl;
|
||||||
_request = context.Request;
|
_request = context.Request;
|
||||||
_response = context.Response;
|
_response = context.Response;
|
||||||
|
_logger = logger;
|
||||||
|
|
||||||
_method = null;
|
_method = null;
|
||||||
_isGet = false;
|
_isGet = false;
|
||||||
|
|
@ -83,6 +86,11 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
{
|
{
|
||||||
get { return _ranges != null; }
|
get { return _ranges != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string SubPath
|
||||||
|
{
|
||||||
|
get { return _subPath.Value; }
|
||||||
|
}
|
||||||
|
|
||||||
public bool ValidateMethod()
|
public bool ValidateMethod()
|
||||||
{
|
{
|
||||||
|
|
@ -220,6 +228,7 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
if (ranges.Count > 1)
|
if (ranges.Count > 1)
|
||||||
{
|
{
|
||||||
// multiple range headers not yet supported
|
// multiple range headers not yet supported
|
||||||
|
_logger.WriteWarning("Multiple range headers not yet supported, {0} ranges in header", ranges.Count.ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -308,6 +317,10 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
{
|
{
|
||||||
ApplyResponseHeaders(statusCode);
|
ApplyResponseHeaders(statusCode);
|
||||||
|
|
||||||
|
if (_logger.IsEnabled(LogLevel.Verbose))
|
||||||
|
{
|
||||||
|
_logger.WriteVerbose(string.Format("Handled. Status code: {0} File: {1}", statusCode, SubPath));
|
||||||
|
}
|
||||||
return Constants.CompletedTask;
|
return Constants.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -350,6 +363,7 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
// the current length of the selected resource. e.g. */length
|
// the current length of the selected resource. e.g. */length
|
||||||
_response.Headers[Constants.ContentRange] = "bytes */" + _length.ToString(CultureInfo.InvariantCulture);
|
_response.Headers[Constants.ContentRange] = "bytes */" + _length.ToString(CultureInfo.InvariantCulture);
|
||||||
ApplyResponseHeaders(Constants.Status416RangeNotSatisfiable);
|
ApplyResponseHeaders(Constants.Status416RangeNotSatisfiable);
|
||||||
|
_logger.WriteWarning("Range not satisfiable for {0}", SubPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -365,6 +379,10 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
var sendFile = _context.GetFeature<IHttpSendFileFeature>();
|
var sendFile = _context.GetFeature<IHttpSendFileFeature>();
|
||||||
if (sendFile != null && !string.IsNullOrEmpty(physicalPath))
|
if (sendFile != null && !string.IsNullOrEmpty(physicalPath))
|
||||||
{
|
{
|
||||||
|
if (_logger.IsEnabled(LogLevel.Verbose))
|
||||||
|
{
|
||||||
|
_logger.WriteVerbose(string.Format("Sending {0} of file {1}", _response.Headers[Constants.ContentRange], physicalPath));
|
||||||
|
}
|
||||||
await sendFile.SendFileAsync(physicalPath, start, length, _context.RequestAborted);
|
await sendFile.SendFileAsync(physicalPath, start, length, _context.RequestAborted);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -373,6 +391,10 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
readStream.Seek(start, SeekOrigin.Begin); // TODO: What if !CanSeek?
|
readStream.Seek(start, SeekOrigin.Begin); // TODO: What if !CanSeek?
|
||||||
|
if (_logger.IsEnabled(LogLevel.Verbose))
|
||||||
|
{
|
||||||
|
_logger.WriteVerbose(string.Format("Copying {0} of file {1} to the response body", _response.Headers[Constants.ContentRange], SubPath));
|
||||||
|
}
|
||||||
await StreamCopyOperation.CopyToAsync(readStream, _response.Body, length, _context.RequestAborted);
|
await StreamCopyOperation.CopyToAsync(readStream, _response.Body, length, _context.RequestAborted);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using Microsoft.AspNet.Builder;
|
||||||
using Microsoft.AspNet.FileSystems;
|
using Microsoft.AspNet.FileSystems;
|
||||||
using Microsoft.AspNet.Hosting;
|
using Microsoft.AspNet.Hosting;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.Framework.Logging;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.StaticFiles
|
namespace Microsoft.AspNet.StaticFiles
|
||||||
{
|
{
|
||||||
|
|
@ -18,13 +19,15 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
private readonly StaticFileOptions _options;
|
private readonly StaticFileOptions _options;
|
||||||
private readonly PathString _matchUrl;
|
private readonly PathString _matchUrl;
|
||||||
private readonly RequestDelegate _next;
|
private readonly RequestDelegate _next;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the StaticFileMiddleware.
|
/// Creates a new instance of the StaticFileMiddleware.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="next">The next middleware in the pipeline.</param>
|
/// <param name="next">The next middleware in the pipeline.</param>
|
||||||
/// <param name="options">The configuration options.</param>
|
/// <param name="options">The configuration options.</param>
|
||||||
public StaticFileMiddleware([NotNull] RequestDelegate next, [NotNull] IHostingEnvironment hostingEnv, [NotNull] StaticFileOptions options)
|
/// <param name="loggerFactory">An <see cref="ILoggerFactory"/> instance used to create loggers.</param>
|
||||||
|
public StaticFileMiddleware([NotNull] RequestDelegate next, [NotNull] IHostingEnvironment hostingEnv, [NotNull] StaticFileOptions options, [NotNull] ILoggerFactory loggerFactory)
|
||||||
{
|
{
|
||||||
if (options.ContentTypeProvider == null)
|
if (options.ContentTypeProvider == null)
|
||||||
{
|
{
|
||||||
|
|
@ -35,6 +38,7 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
_next = next;
|
_next = next;
|
||||||
_options = options;
|
_options = options;
|
||||||
_matchUrl = options.RequestPath;
|
_matchUrl = options.RequestPath;
|
||||||
|
_logger = loggerFactory.Create<StaticFileMiddleware>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -44,7 +48,7 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task Invoke(HttpContext context)
|
public Task Invoke(HttpContext context)
|
||||||
{
|
{
|
||||||
var fileContext = new StaticFileContext(context, _options, _matchUrl);
|
var fileContext = new StaticFileContext(context, _options, _matchUrl, _logger);
|
||||||
if (fileContext.ValidateMethod()
|
if (fileContext.ValidateMethod()
|
||||||
&& fileContext.ValidatePath()
|
&& fileContext.ValidatePath()
|
||||||
&& fileContext.LookupContentType()
|
&& fileContext.LookupContentType()
|
||||||
|
|
@ -64,16 +68,26 @@ namespace Microsoft.AspNet.StaticFiles
|
||||||
{
|
{
|
||||||
return fileContext.SendRangeAsync();
|
return fileContext.SendRangeAsync();
|
||||||
}
|
}
|
||||||
|
if (_logger.IsEnabled(LogLevel.Verbose))
|
||||||
|
{
|
||||||
|
_logger.WriteVerbose(string.Format("Copying file {0} to the response body", fileContext.SubPath));
|
||||||
|
}
|
||||||
return fileContext.SendAsync();
|
return fileContext.SendAsync();
|
||||||
|
|
||||||
case StaticFileContext.PreconditionState.NotModified:
|
case StaticFileContext.PreconditionState.NotModified:
|
||||||
|
if (_logger.IsEnabled(LogLevel.Verbose))
|
||||||
|
{
|
||||||
|
_logger.WriteVerbose(string.Format("{0} not modified", fileContext.SubPath));
|
||||||
|
}
|
||||||
return fileContext.SendStatusAsync(Constants.Status304NotModified);
|
return fileContext.SendStatusAsync(Constants.Status304NotModified);
|
||||||
|
|
||||||
case StaticFileContext.PreconditionState.PreconditionFailed:
|
case StaticFileContext.PreconditionState.PreconditionFailed:
|
||||||
return fileContext.SendStatusAsync(Constants.Status412PreconditionFailed);
|
return fileContext.SendStatusAsync(Constants.Status412PreconditionFailed);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException(fileContext.GetPreconditionState().ToString());
|
var exception = new NotImplementedException(fileContext.GetPreconditionState().ToString());
|
||||||
|
_logger.WriteError("No precondition state specified", exception);
|
||||||
|
throw exception;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@
|
||||||
"Microsoft.AspNet.Hosting": { "version": "1.0.0-*", "type": "build" },
|
"Microsoft.AspNet.Hosting": { "version": "1.0.0-*", "type": "build" },
|
||||||
"Microsoft.AspNet.Http": "1.0.0-*",
|
"Microsoft.AspNet.Http": "1.0.0-*",
|
||||||
"Microsoft.AspNet.Http.Extensions": "1.0.0-*",
|
"Microsoft.AspNet.Http.Extensions": "1.0.0-*",
|
||||||
"Microsoft.AspNet.HttpFeature": { "version": "1.0.0-*", "type": "build" }
|
"Microsoft.AspNet.HttpFeature": { "version": "1.0.0-*", "type": "build" },
|
||||||
|
"Microsoft.Framework.Logging": "1.0.0-*"
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
"aspnet50": { },
|
"aspnet50": { },
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue