-
Notifications
You must be signed in to change notification settings - Fork 76
Expand file tree
/
Copy pathHttpCapabilitiesBase.cs
More file actions
116 lines (84 loc) · 3.63 KB
/
Copy pathHttpCapabilitiesBase.cs
File metadata and controls
116 lines (84 loc) · 3.63 KB
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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Globalization;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.SystemWebAdapters;
using Microsoft.AspNetCore.SystemWebAdapters.Features;
using Microsoft.Extensions.DependencyInjection;
namespace System.Web.Configuration;
public class HttpCapabilitiesBase
{
private readonly HttpContextCore _context;
private FeatureReference<IHttpBrowserCapabilityFeature> _capability;
private protected HttpCapabilitiesBase(HttpContextCore context)
{
_context = context;
_capability = FeatureReference<IHttpBrowserCapabilityFeature>.Default;
}
private IHttpBrowserCapabilityFeature Capability
{
get
{
if (_capability.Fetch(_context.Features) is { } existing)
{
return existing;
}
return _capability.Update(_context.Features, _context.RequestServices.GetRequiredService<IBrowserCapabilitiesFactory>().Create(_context.Request));
}
}
public string? Browser => Capability["browser"];
public string? Version => Capability["version"];
public int MajorVersion => GetInt("majorversion");
public double MinorVersion => GetDouble("minorversion");
public string? Platform => Capability["platform"];
public bool Crawler => GetBoolean("crawler");
public bool Cookies => GetBoolean("cookies");
public string? Type => Capability["type"];
public string? PreferredRequestEncoding => Capability["preferredRequestEncoding"];
public string? this[string key] => Capability[key];
public Version EcmaScriptVersion => GetVersion("ecmascriptversion");
public Version MSDomVersion => GetVersion("msdomversion");
public Version W3CDomVersion => GetVersion("w3cdomversion");
public bool SupportsCallback => GetBoolean("supportsCallback");
public bool IsMobileDevice => GetBoolean("isMobileDevice");
private int GetInt(string key) => int.TryParse(Capability[key], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) ? result : throw new HttpUnhandledException($"Invalid string from browser capabilities '{key}'");
private bool GetBoolean(string key) => bool.TryParse(Capability[key], out var result) && result;
private double GetDouble(string key)
{
const NumberStyles Style = NumberStyles.Float | NumberStyles.AllowDecimalPoint;
var value = Capability[key];
if (value is not null)
{
if (double.TryParse(value, Style, CultureInfo.InvariantCulture, out var result))
{
return result;
}
// Handle if there's more than one decimal i.e. .4.1 -> .4
var firstDecimal = value.IndexOf('.', StringComparison.Ordinal);
if (firstDecimal != -1)
{
var nextDecimal = value.IndexOf('.', firstDecimal + 1);
if (nextDecimal != -1)
{
if (double.TryParse(value.AsSpan()[..nextDecimal], Style, CultureInfo.InvariantCulture, out var result2))
{
return result2;
}
}
}
}
throw new HttpUnhandledException($"Invalid string from browser capabilities '{key}'");
}
private Version GetVersion(string key)
{
var result = Capability[key];
if (result is not null)
{
return new Version(result);
}
else
{
throw new ArgumentNullException(nameof(key));
}
}
}