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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Hosting;
namespace System.Web.WebPages
{
/// <summary>
/// Extension methods used to determine what browser a visitor wants to be seen as using.
/// </summary>
public static class BrowserHelpers
{
/// <summary>
/// Stock IE6 user agent string
/// </summary>
private const string DesktopUserAgent = "Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)";
/// <summary>
/// Stock Windows Mobile 6.0 user agent string
/// </summary>
private const string MobileUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 8.12; MSIEMobile 6.0)";
private static readonly object _browserOverrideKey = new object();
private static readonly object _userAgentKey = new object();
/// <summary>
/// Clears the set browser for the request. After clearing the browser the overridden browser will be the browser for the request.
/// </summary>
public static void ClearOverriddenBrowser(this HttpContextBase httpContext)
{
SetOverriddenBrowser(httpContext, userAgent: null);
}
// Default implementation to generate an HttpBrowserCapabilities object using the current HttpCapabilitiesProvider
private static HttpBrowserCapabilitiesBase CreateOverriddenBrowser(string userAgent)
{
HttpBrowserCapabilities overriddenBrowser = new HttpContext(new UserAgentWorkerRequest(userAgent)).Request.Browser;
return new HttpBrowserCapabilitiesWrapper(overriddenBrowser);
}
/// <summary>
/// Gets the overridden browser for the request based on the overridden user agent.
/// If no overridden user agent is set, returns the browser for the request.
/// </summary>
public static HttpBrowserCapabilitiesBase GetOverriddenBrowser(this HttpContextBase httpContext)
{
return GetOverriddenBrowser(httpContext, CreateOverriddenBrowser);
}
internal static HttpBrowserCapabilitiesBase GetOverriddenBrowser(this HttpContextBase httpContext, Func<string, HttpBrowserCapabilitiesBase> createBrowser)
{
HttpBrowserCapabilitiesBase overriddenBrowser = (HttpBrowserCapabilitiesBase)httpContext.Items[_browserOverrideKey];
if (overriddenBrowser == null)
{
string overriddenUserAgent = GetOverriddenUserAgent(httpContext);
if (!String.Equals(overriddenUserAgent, httpContext.Request.UserAgent))
{
overriddenBrowser = createBrowser(overriddenUserAgent);
}
else
{
overriddenBrowser = httpContext.Request.Browser;
}
httpContext.Items[_browserOverrideKey] = overriddenBrowser;
}
return overriddenBrowser;
}
/// <summary>
/// Gets the overridden user agent for the request. If no overridden user agent is set, returns the user agent for the request.
/// </summary>
public static string GetOverriddenUserAgent(this HttpContextBase httpContext)
{
return (string)httpContext.Items[_userAgentKey] ??
BrowserOverrideStores.Current.GetOverriddenUserAgent(httpContext) ??
httpContext.Request.UserAgent;
}
/// <summary>
/// Gets a string that varies based upon the type of the browser. Can be used to override
/// System.Web.HttpApplication.GetVaryByCustomString to differentiate cache keys based on
/// the overridden browser.
/// </summary>
public static string GetVaryByCustomStringForOverriddenBrowser(this HttpContext httpContext)
{
return GetVaryByCustomStringForOverriddenBrowser(new HttpContextWrapper(httpContext));
}
/// <summary>
/// Gets a string that varies based upon the type of the browser. Can be used to override
/// System.Web.HttpApplication.GetVaryByCustomString to differentiate cache keys based on
/// the overridden browser.
/// </summary>
public static string GetVaryByCustomStringForOverriddenBrowser(this HttpContextBase httpContext)
{
return GetVaryByCustomStringForOverriddenBrowser(httpContext, userAgent => CreateOverriddenBrowser(userAgent));
}
internal static string GetVaryByCustomStringForOverriddenBrowser(this HttpContextBase httpContext, Func<string, HttpBrowserCapabilitiesBase> generateBrowser)
{
return GetOverriddenBrowser(httpContext, generateBrowser).Type;
}
/// <summary>
/// Sets the overridden user agent for the request using a BrowserOverride.
/// </summary>
public static void SetOverriddenBrowser(this HttpContextBase httpContext, BrowserOverride browserOverride)
{
string userAgent = null;
switch (browserOverride)
{
case BrowserOverride.Desktop:
// bug:262389 override only if the request was not made from a browser or the browser is not of a desktop device
if (httpContext.Request.Browser == null || httpContext.Request.Browser.IsMobileDevice)
{
userAgent = DesktopUserAgent;
}
break;
case BrowserOverride.Mobile:
if (httpContext.Request.Browser == null || !httpContext.Request.Browser.IsMobileDevice)
{
userAgent = MobileUserAgent;
}
break;
}
if (userAgent != null)
{
SetOverriddenBrowser(httpContext, userAgent);
}
else
{
ClearOverriddenBrowser(httpContext);
}
}
/// <summary>
/// Sets the overridden user agent for the request using a string
/// </summary>
public static void SetOverriddenBrowser(this HttpContextBase httpContext, string userAgent)
{
// Set the overridden user agent and clear the overridden browser
// so that it can be generated from the new overridden user agent.
httpContext.Items[_userAgentKey] = userAgent;
httpContext.Items[_browserOverrideKey] = null;
BrowserOverrideStores.Current.SetOverriddenUserAgent(httpContext, userAgent);
}
private sealed class UserAgentWorkerRequest : SimpleWorkerRequest
{
private readonly string _userAgent;
public UserAgentWorkerRequest(string userAgent)
: base(String.Empty, String.Empty, output: null)
{
_userAgent = userAgent;
}
public override string GetKnownRequestHeader(int index)
{
return index == HeaderUserAgent ? _userAgent : null;
}
}
}
}
|