diff --git a/samples/StaticFileSample/Startup.cs b/samples/StaticFileSample/Startup.cs
index a6337fe7d6..ba73533790 100644
--- a/samples/StaticFileSample/Startup.cs
+++ b/samples/StaticFileSample/Startup.cs
@@ -1,13 +1,18 @@
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.FileSystems;
using Microsoft.AspNet.StaticFiles;
+using Microsoft.Framework.Logging;
+using Microsoft.Framework.Logging.Console;
namespace StaticFilesSample
{
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()
{
EnableDirectoryBrowsing = true,
diff --git a/samples/StaticFileSample/StaticFileSample.kproj b/samples/StaticFileSample/StaticFileSample.kproj
index 2ebbf8a0b5..c83664fd1b 100644
--- a/samples/StaticFileSample/StaticFileSample.kproj
+++ b/samples/StaticFileSample/StaticFileSample.kproj
@@ -12,6 +12,7 @@
2.0
+ 16758
diff --git a/samples/StaticFileSample/project.json b/samples/StaticFileSample/project.json
index 0b07dc6047..a0f2cf42d2 100644
--- a/samples/StaticFileSample/project.json
+++ b/samples/StaticFileSample/project.json
@@ -3,10 +3,11 @@
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.Urls http://localhost:12345/"
},
"dependencies": {
+ "Kestrel": "1.0.0-*",
"Microsoft.AspNet.Server.IIS": "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": {
"aspnet50": { },
diff --git a/src/Microsoft.AspNet.StaticFiles/SendFileMiddleware.cs b/src/Microsoft.AspNet.StaticFiles/SendFileMiddleware.cs
index 8351dcd3a3..3bc14fa70a 100644
--- a/src/Microsoft.AspNet.StaticFiles/SendFileMiddleware.cs
+++ b/src/Microsoft.AspNet.StaticFiles/SendFileMiddleware.cs
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.HttpFeature;
+using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.StaticFiles
{
@@ -20,14 +21,17 @@ namespace Microsoft.AspNet.StaticFiles
public class SendFileMiddleware
{
private readonly RequestDelegate _next;
+ private readonly ILogger _logger;
///
/// Creates a new instance of the SendFileMiddleware.
///
/// The next middleware in the pipeline.
- public SendFileMiddleware([NotNull] RequestDelegate next)
+ /// An instance used to create loggers.
+ public SendFileMiddleware([NotNull] RequestDelegate next, [NotNull] ILoggerFactory loggerFactory)
{
_next = next;
+ _logger = loggerFactory.Create();
}
public Task Invoke(HttpContext context)
@@ -35,7 +39,7 @@ namespace Microsoft.AspNet.StaticFiles
// Check if there is a SendFile feature already present
if (context.GetFeature() == null)
{
- context.SetFeature(new SendFileWrapper(context.Response.Body));
+ context.SetFeature(new SendFileWrapper(context.Response.Body, _logger));
}
return _next(context);
@@ -44,10 +48,12 @@ namespace Microsoft.AspNet.StaticFiles
private class SendFileWrapper : IHttpSendFileFeature
{
private readonly Stream _output;
+ private readonly ILogger _logger;
- internal SendFileWrapper(Stream output)
+ internal SendFileWrapper(Stream output, ILogger logger)
{
_output = output;
+ _logger = logger;
}
// Not safe for overlapped writes.
@@ -86,6 +92,10 @@ namespace Microsoft.AspNet.StaticFiles
try
{
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);
}
finally
diff --git a/src/Microsoft.AspNet.StaticFiles/StaticFileContext.cs b/src/Microsoft.AspNet.StaticFiles/StaticFileContext.cs
index 06b6311338..1028a8fb59 100644
--- a/src/Microsoft.AspNet.StaticFiles/StaticFileContext.cs
+++ b/src/Microsoft.AspNet.StaticFiles/StaticFileContext.cs
@@ -11,6 +11,7 @@ using Microsoft.AspNet.FileSystems;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.StaticFiles.Infrastructure;
+using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.StaticFiles
{
@@ -21,6 +22,7 @@ namespace Microsoft.AspNet.StaticFiles
private readonly PathString _matchUrl;
private readonly HttpRequest _request;
private readonly HttpResponse _response;
+ private readonly ILogger _logger;
private string _method;
private bool _isGet;
private bool _isHead;
@@ -40,13 +42,14 @@ namespace Microsoft.AspNet.StaticFiles
private IList> _ranges;
- public StaticFileContext(HttpContext context, StaticFileOptions options, PathString matchUrl)
+ public StaticFileContext(HttpContext context, StaticFileOptions options, PathString matchUrl, ILogger logger)
{
_context = context;
_options = options;
_matchUrl = matchUrl;
_request = context.Request;
_response = context.Response;
+ _logger = logger;
_method = null;
_isGet = false;
@@ -83,6 +86,11 @@ namespace Microsoft.AspNet.StaticFiles
{
get { return _ranges != null; }
}
+
+ public string SubPath
+ {
+ get { return _subPath.Value; }
+ }
public bool ValidateMethod()
{
@@ -220,6 +228,7 @@ namespace Microsoft.AspNet.StaticFiles
if (ranges.Count > 1)
{
// multiple range headers not yet supported
+ _logger.WriteWarning("Multiple range headers not yet supported, {0} ranges in header", ranges.Count.ToString());
return;
}
@@ -308,6 +317,10 @@ namespace Microsoft.AspNet.StaticFiles
{
ApplyResponseHeaders(statusCode);
+ if (_logger.IsEnabled(LogLevel.Verbose))
+ {
+ _logger.WriteVerbose(string.Format("Handled. Status code: {0} File: {1}", statusCode, SubPath));
+ }
return Constants.CompletedTask;
}
@@ -350,6 +363,7 @@ namespace Microsoft.AspNet.StaticFiles
// the current length of the selected resource. e.g. */length
_response.Headers[Constants.ContentRange] = "bytes */" + _length.ToString(CultureInfo.InvariantCulture);
ApplyResponseHeaders(Constants.Status416RangeNotSatisfiable);
+ _logger.WriteWarning("Range not satisfiable for {0}", SubPath);
return;
}
@@ -365,6 +379,10 @@ namespace Microsoft.AspNet.StaticFiles
var sendFile = _context.GetFeature();
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);
return;
}
@@ -373,6 +391,10 @@ namespace Microsoft.AspNet.StaticFiles
try
{
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);
}
finally
diff --git a/src/Microsoft.AspNet.StaticFiles/StaticFileMiddleware.cs b/src/Microsoft.AspNet.StaticFiles/StaticFileMiddleware.cs
index a630f367f2..a9c09d84b3 100644
--- a/src/Microsoft.AspNet.StaticFiles/StaticFileMiddleware.cs
+++ b/src/Microsoft.AspNet.StaticFiles/StaticFileMiddleware.cs
@@ -7,6 +7,7 @@ using Microsoft.AspNet.Builder;
using Microsoft.AspNet.FileSystems;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
+using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.StaticFiles
{
@@ -18,13 +19,15 @@ namespace Microsoft.AspNet.StaticFiles
private readonly StaticFileOptions _options;
private readonly PathString _matchUrl;
private readonly RequestDelegate _next;
+ private readonly ILogger _logger;
///
/// Creates a new instance of the StaticFileMiddleware.
///
/// The next middleware in the pipeline.
/// The configuration options.
- public StaticFileMiddleware([NotNull] RequestDelegate next, [NotNull] IHostingEnvironment hostingEnv, [NotNull] StaticFileOptions options)
+ /// An instance used to create loggers.
+ public StaticFileMiddleware([NotNull] RequestDelegate next, [NotNull] IHostingEnvironment hostingEnv, [NotNull] StaticFileOptions options, [NotNull] ILoggerFactory loggerFactory)
{
if (options.ContentTypeProvider == null)
{
@@ -35,6 +38,7 @@ namespace Microsoft.AspNet.StaticFiles
_next = next;
_options = options;
_matchUrl = options.RequestPath;
+ _logger = loggerFactory.Create();
}
///
@@ -44,7 +48,7 @@ namespace Microsoft.AspNet.StaticFiles
///
public Task Invoke(HttpContext context)
{
- var fileContext = new StaticFileContext(context, _options, _matchUrl);
+ var fileContext = new StaticFileContext(context, _options, _matchUrl, _logger);
if (fileContext.ValidateMethod()
&& fileContext.ValidatePath()
&& fileContext.LookupContentType()
@@ -64,16 +68,26 @@ namespace Microsoft.AspNet.StaticFiles
{
return fileContext.SendRangeAsync();
}
+ if (_logger.IsEnabled(LogLevel.Verbose))
+ {
+ _logger.WriteVerbose(string.Format("Copying file {0} to the response body", fileContext.SubPath));
+ }
return fileContext.SendAsync();
case StaticFileContext.PreconditionState.NotModified:
+ if (_logger.IsEnabled(LogLevel.Verbose))
+ {
+ _logger.WriteVerbose(string.Format("{0} not modified", fileContext.SubPath));
+ }
return fileContext.SendStatusAsync(Constants.Status304NotModified);
case StaticFileContext.PreconditionState.PreconditionFailed:
return fileContext.SendStatusAsync(Constants.Status412PreconditionFailed);
default:
- throw new NotImplementedException(fileContext.GetPreconditionState().ToString());
+ var exception = new NotImplementedException(fileContext.GetPreconditionState().ToString());
+ _logger.WriteError("No precondition state specified", exception);
+ throw exception;
}
}
diff --git a/src/Microsoft.AspNet.StaticFiles/project.json b/src/Microsoft.AspNet.StaticFiles/project.json
index 32b6764bb5..aa56171bce 100644
--- a/src/Microsoft.AspNet.StaticFiles/project.json
+++ b/src/Microsoft.AspNet.StaticFiles/project.json
@@ -6,7 +6,8 @@
"Microsoft.AspNet.Hosting": { "version": "1.0.0-*", "type": "build" },
"Microsoft.AspNet.Http": "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": {
"aspnet50": { },