This repository has been archived by the owner on Nov 22, 2018. It is now read-only.
/
StaticFileMiddleware.cs
97 lines (87 loc) · 4.07 KB
/
StaticFileMiddleware.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// 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.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.StaticFiles
{
/// <summary>
/// Enables serving static files for a given request path
/// </summary>
public class StaticFileMiddleware
{
private readonly StaticFileOptions _options;
private readonly PathString _matchUrl;
private readonly RequestDelegate _next;
private readonly ILogger _logger;
/// <summary>
/// Creates a new instance of the StaticFileMiddleware.
/// </summary>
/// <param name="next">The next middleware in the pipeline.</param>
/// <param name="options">The configuration options.</param>
/// <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)
{
throw new ArgumentException(Resources.Args_NoContentTypeProvider);
}
options.ResolveFileProvider(hostingEnv);
_next = next;
_options = options;
_matchUrl = options.RequestPath;
_logger = loggerFactory.CreateLogger<StaticFileMiddleware>();
}
/// <summary>
/// Processes a request to determine if it matches a known file, and if so, serves it.
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public Task Invoke(HttpContext context)
{
var fileContext = new StaticFileContext(context, _options, _matchUrl, _logger);
if (fileContext.ValidateMethod()
&& fileContext.ValidatePath()
&& fileContext.LookupContentType()
&& fileContext.LookupFileInfo())
{
fileContext.ComprehendRequestHeaders();
switch (fileContext.GetPreconditionState())
{
case StaticFileContext.PreconditionState.Unspecified:
case StaticFileContext.PreconditionState.ShouldProcess:
if (fileContext.IsHeadMethod)
{
return fileContext.SendStatusAsync(Constants.Status200Ok);
}
if (fileContext.IsRangeRequest)
{
return fileContext.SendRangeAsync();
}
if (_logger.IsEnabled(LogLevel.Verbose))
{
_logger.LogVerbose(string.Format("Copying file {0} to the response body", fileContext.SubPath));
}
return fileContext.SendAsync();
case StaticFileContext.PreconditionState.NotModified:
if (_logger.IsEnabled(LogLevel.Verbose))
{
_logger.LogVerbose(string.Format("{0} not modified", fileContext.SubPath));
}
return fileContext.SendStatusAsync(Constants.Status304NotModified);
case StaticFileContext.PreconditionState.PreconditionFailed:
return fileContext.SendStatusAsync(Constants.Status412PreconditionFailed);
default:
var exception = new NotImplementedException(fileContext.GetPreconditionState().ToString());
_logger.LogError("No precondition state specified", exception);
throw exception;
}
}
return _next(context);
}
}
}