-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCaseInsensitiveStaticFileMiddleware.cs
147 lines (134 loc) · 6.3 KB
/
CaseInsensitiveStaticFileMiddleware.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Web;
namespace CaseInsensitiveStaticFile
{
public class CaseInsensitiveStaticFileMiddleware
{
private readonly RequestDelegate _next;
private readonly Dictionary<string, string> StaticFileProvider;
private readonly bool Debug;
public CaseInsensitiveStaticFileMiddleware(RequestDelegate next, Dictionary<string, string> staticFileProvider, bool debug = false)
{
_next = next;
StaticFileProvider = staticFileProvider;
Debug = debug;
foreach (var provider in StaticFileProvider)
{
if (!Directory.Exists(provider.Value))
throw new DirectoryNotFoundException($"StaticFile provider: '{provider.Value}' not exists.");
}
}
public async Task InvokeAsync(HttpContext context)
{
if (StaticFileProvider == null || StaticFileProvider.Count == 0 ||
context.Request.Path.ToString() == "/" || RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
await _next(context);
else
{
var askingPath = HttpUtility.UrlDecode(context.Request.Path.ToString().ToLower());
var segs = askingPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
string localPath = string.Empty;
string redirectPath = string.Empty;
string requestFile = string.Empty;
string resultFile = string.Empty;
string resultFolder = string.Empty;
KeyValuePair<string, string> provider = new KeyValuePair<string, string>();
Console.WriteLine($"Asking path: {askingPath}");
if (segs.Length == 1)
{
if (StaticFileProvider.ContainsKey("/"))
{
requestFile = segs[0];
localPath = StaticFileProvider["/"];
resultFile = Array.Find(Directory.GetFiles(localPath), x => Path.GetFileName(x).ToLower() == requestFile);
if (string.IsNullOrEmpty(resultFile))
{
resultFolder = Array.Find(Directory.GetDirectories(localPath), x => Path.GetFileName(x).ToLower() == requestFile);
if (string.IsNullOrEmpty(resultFolder))
await _next(context);
else
{
redirectPath = $"/{Path.GetFileName(resultFolder)}";
context.Response.Redirect(redirectPath);
return;
}
}
else
{
redirectPath = $"/{Path.GetFileName(resultFile)}";
if (redirectPath != askingPath)
context.Response.Redirect(redirectPath);
else
await _next(context);
}
}
else
await _next(context);
}
else
{
for (int i = 0; i < segs.Length; i++)
{
var seg = segs[i];
if (i == 0)
{
provider = StaticFileProvider.FirstOrDefault(x => x.Key.ToLower() == $"/{seg}");
if (string.IsNullOrEmpty(provider.Key))
break;
else
localPath = provider.Value;
}
else if (i == segs.Length - 1)
{
resultFile = Array.Find(Directory.GetFiles(localPath), x => Path.GetFileName(x).ToLower() == seg);
if (string.IsNullOrEmpty(resultFile))
{
resultFolder = Array.Find(Directory.GetDirectories(localPath), x => Path.GetFileName(x).ToLower() == requestFile);
if (string.IsNullOrEmpty(resultFolder))
break;
else
{
redirectPath = $"{provider.Key}/{resultFolder.Replace(provider.Value, "").TrimStart(Path.DirectorySeparatorChar)}";
context.Response.Redirect(redirectPath);
return;
}
}
else
{
redirectPath = $"{provider.Key}/{resultFile.Replace(provider.Value, "").TrimStart(Path.DirectorySeparatorChar)}";
if (redirectPath != askingPath)
{
context.Response.Redirect(redirectPath);
return;
}
}
}
else
{
resultFolder = Array.Find(Directory.GetDirectories(localPath), x => Path.GetFileName(x).ToLower() == seg);
if (string.IsNullOrEmpty(resultFolder))
break;
else
localPath = resultFolder;
}
}
await _next(context);
}
}
}
}
public static class StaticFileMiddlewareExtensions
{
public static IApplicationBuilder UseCaseInsensitiveStaticFile(this IApplicationBuilder builder, Dictionary<string, string> staticFileProvider, bool debug = false)
{
return builder.UseMiddleware<CaseInsensitiveStaticFileMiddleware>(staticFileProvider, debug);
}
}
}