-
Notifications
You must be signed in to change notification settings - Fork 37
/
PipelineHandler.cs
129 lines (108 loc) · 5.21 KB
/
PipelineHandler.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
namespace SassAndCoffee.AspNet {
using System;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Configuration;
using System.Web.UI;
using SassAndCoffee.Core;
public class PipelineHandler : IHttpHandler {
public const string CacheProfileName = "SassAndCoffeeCacheSettings";
private IContentPipeline _pipeline;
private OutputCacheProfile _cacheProfile;
public bool IsReusable { get { return true; } }
public PipelineHandler(IContentPipeline pipeline) {
_pipeline = pipeline;
var settings = WebConfigurationManager.GetWebApplicationSection(
"system.web/caching/outputCacheSettings") as OutputCacheSettingsSection;
_cacheProfile = settings.OutputCacheProfiles[CacheProfileName] ?? CreateDefaultCacheProfile();
}
public void ProcessRequest(HttpContext context) {
var request = context.Request;
var response = context.Response;
var result = _pipeline.ProcessRequest(request.PhysicalPath);
if (result == null) {
response.StatusCode = (int)HttpStatusCode.NotFound;
return;
}
if (_cacheProfile.Enabled) {
SetCachePolicy(response, _cacheProfile.Location);
response.Cache.SetMaxAge(TimeSpan.FromSeconds(_cacheProfile.Duration));
response.Cache.SetExpires(DateTime.UtcNow.AddSeconds(_cacheProfile.Duration));
if (_cacheProfile.NoStore)
response.Cache.SetNoStore();
// No SQL dependency, VaryByControl, or VaryByCustom support for now
SetVaryBy(_cacheProfile.VaryByContentEncoding, encoding => response.Cache.VaryByContentEncodings[encoding] = true);
if (_cacheProfile.VaryByHeader == "*") {
response.Cache.VaryByHeaders.VaryByUnspecifiedParameters();
} else {
SetVaryBy(_cacheProfile.VaryByHeader, header => response.Cache.VaryByHeaders[header] = true);
}
if (_cacheProfile.VaryByParam != "*") {
response.Cache.SetOmitVaryStar(true);
if (string.IsNullOrWhiteSpace(_cacheProfile.VaryByParam)
|| _cacheProfile.VaryByParam == "none") {
response.Cache.VaryByParams.IgnoreParams = true;
} else {
SetVaryBy(_cacheProfile.VaryByParam, param => response.Cache.VaryByParams[param] = true);
}
}
if (result.CacheInvalidationFileList.Any()) {
response.AddFileDependencies(result.CacheInvalidationFileList.ToArray());
response.Cache.SetLastModifiedFromFileDependencies();
response.Cache.SetETagFromFileDependencies();
}
} else {
response.Cache.SetCacheability(HttpCacheability.NoCache);
}
response.ContentEncoding = Encoding.UTF8;
response.ContentType = result.MimeType;
response.Write(result.Content);
}
private void SetVaryBy(string list, Action<string> action) {
if (string.IsNullOrWhiteSpace(list))
return;
var trimmedItems = list
.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim());
foreach (var item in trimmedItems) {
action(item);
}
}
private static void SetCachePolicy(HttpResponse response, OutputCacheLocation outputCacheLocation) {
switch (outputCacheLocation) {
case OutputCacheLocation.Any:
response.Cache.SetCacheability(HttpCacheability.Public);
break;
case OutputCacheLocation.Client:
response.Cache.SetCacheability(HttpCacheability.Private);
response.Cache.SetNoServerCaching();
break;
case OutputCacheLocation.Downstream:
response.Cache.SetCacheability(HttpCacheability.Public);
response.Cache.SetNoServerCaching();
break;
case OutputCacheLocation.None:
response.Cache.SetCacheability(HttpCacheability.NoCache);
response.Cache.SetNoServerCaching();
break;
case OutputCacheLocation.Server:
response.Cache.SetCacheability(HttpCacheability.Server);
break;
case OutputCacheLocation.ServerAndClient:
response.Cache.SetCacheability(HttpCacheability.ServerAndPrivate);
break;
}
}
private static OutputCacheProfile CreateDefaultCacheProfile() {
return new OutputCacheProfile(CacheProfileName) {
Duration = 3600, // one hour
Location = OutputCacheLocation.Any,
VaryByHeader = "Accept-Encoding",
VaryByParam = "none",
Enabled = true,
};
}
}
}