1
1
// Copyright © myCSharp.de - all rights reserved
2
2
3
3
using Microsoft . AspNetCore . Http ;
4
+ using Microsoft . Extensions . Primitives ;
4
5
5
6
namespace MyCSharp . HttpClientHints . AspNetCore ;
6
7
@@ -9,15 +10,28 @@ namespace MyCSharp.HttpClientHints.AspNetCore;
9
10
/// </summary>
10
11
public static class HttpClientHintsHttpContextExtensions
11
12
{
13
+ /// <summary>
14
+ /// The cache key used to store the client hints in the HttpContext.Items dictionary.
15
+ /// </summary>
16
+ private const string ClientHintsCacheKey = "__HttpClientHints" ;
17
+
12
18
/// <summary>
13
19
/// Retrieves the <see cref="HttpClientHints"/> from the current HTTP context.
14
20
/// </summary>
15
21
/// <param name="context">The HTTP context containing the request headers.</param>
16
22
/// <returns>An instance of <see cref="HttpClientHints"/> populated with the relevant header values.</returns>
17
23
public static HttpClientHints GetClientHints ( this HttpContext context )
18
24
{
19
- IHeaderDictionary headers = context . Request . Headers ;
20
- return headers . GetClientHints ( ) ;
25
+ // Check if client hints are already cached for this request
26
+ if ( context . Items . TryGetValue ( ClientHintsCacheKey , out var cached ) && cached is HttpClientHints hints )
27
+ {
28
+ return hints ;
29
+ }
30
+
31
+ // Create and cache new client hints
32
+ var newHints = context . Request . Headers . GetClientHints ( ) ;
33
+ context . Items [ ClientHintsCacheKey ] = newHints ;
34
+ return newHints ;
21
35
}
22
36
23
37
/// <summary>
@@ -27,25 +41,36 @@ public static HttpClientHints GetClientHints(this HttpContext context)
27
41
/// <returns>An instance of <see cref="HttpClientHints"/> populated with the relevant header values.</returns>
28
42
public static HttpClientHints GetClientHints ( this IHeaderDictionary headers )
29
43
{
30
- // user agent
31
- string ? userAgent = headers [ "User-Agent" ] . FirstOrDefault ( ) ;
32
- string ? ua = headers [ "Sec-CH-UA" ] . FirstOrDefault ( ) ;
44
+ // User Agent
45
+ headers . TryGetValue ( "User-Agent" , out StringValues userAgentValues ) ;
46
+ string ? userAgent = userAgentValues . Count > 0 ? userAgentValues [ 0 ] : null ;
47
+
48
+ headers . TryGetValue ( "Sec-CH-UA" , out StringValues uaValues ) ;
49
+ string ? ua = uaValues . Count > 0 ? uaValues [ 0 ] : null ;
33
50
34
- // platform
35
- string ? platform = headers [ "Sec-CH-UA-Platform" ] . FirstOrDefault ( ) ;
36
- string ? platformVersion = headers [ "Sec-CH-UA-Platform-Version" ] . FirstOrDefault ( ) ;
51
+ // Platform
52
+ headers . TryGetValue ( "Sec-CH-UA-Platform" , out StringValues platformValues ) ;
53
+ string ? platform = platformValues . Count > 0 ? platformValues [ 0 ] : null ;
54
+
55
+ headers . TryGetValue ( "Sec-CH-UA-Platform-Version" , out StringValues platformVersionValues ) ;
56
+ string ? platformVersion = platformVersionValues . Count > 0 ? platformVersionValues [ 0 ] : null ;
37
57
38
- // architecture
39
- string ? architecture = headers [ "Sec-CH-UA-Arch" ] . FirstOrDefault ( ) ;
58
+ // Architecture
59
+ headers . TryGetValue ( "Sec-CH-UA-Arch" , out StringValues architectureValues ) ;
60
+ string ? architecture = architectureValues . Count > 0 ? architectureValues [ 0 ] : null ;
40
61
41
- // other
42
- string ? fullVersionList = headers [ "Sec-CH-UA-Full-Version-List" ] . FirstOrDefault ( ) ;
62
+ // Other
63
+ headers . TryGetValue ( "Sec-CH-UA-Full-Version-List" , out StringValues fullVersionListValues ) ;
64
+ string ? fullVersionList = fullVersionListValues . Count > 0 ? fullVersionListValues [ 0 ] : null ;
43
65
44
- // device
45
- string ? model = headers [ "Sec-CH-UA-Model" ] . FirstOrDefault ( ) ;
46
- bool ? mobile = HttpClientHintsInterpreter . IsMobile ( headers [ "Sec-CH-UA-Mobile" ] . FirstOrDefault ( ) ) ;
66
+ // Device
67
+ headers . TryGetValue ( "Sec-CH-UA-Model" , out StringValues modelValues ) ;
68
+ string ? model = modelValues . Count > 0 ? modelValues [ 0 ] : null ;
69
+
70
+ headers . TryGetValue ( "Sec-CH-UA-Mobile" , out StringValues mobileValues ) ;
71
+ bool ? mobile = HttpClientHintsInterpreter . IsMobile ( mobileValues . Count > 0 ? mobileValues [ 0 ] : null ) ;
47
72
48
- // return the HttpClientHints record
73
+ // Return the HttpClientHints record
49
74
return new ( userAgent , platform , platformVersion , architecture , model , fullVersionList , ua , mobile , headers ) ;
50
75
}
51
76
}
0 commit comments