11// Copyright © myCSharp.de - all rights reserved
22
33using Microsoft . AspNetCore . Http ;
4+ using Microsoft . Extensions . Primitives ;
45
56namespace MyCSharp . HttpClientHints . AspNetCore ;
67
@@ -9,15 +10,28 @@ namespace MyCSharp.HttpClientHints.AspNetCore;
910/// </summary>
1011public static class HttpClientHintsHttpContextExtensions
1112{
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+
1218 /// <summary>
1319 /// Retrieves the <see cref="HttpClientHints"/> from the current HTTP context.
1420 /// </summary>
1521 /// <param name="context">The HTTP context containing the request headers.</param>
1622 /// <returns>An instance of <see cref="HttpClientHints"/> populated with the relevant header values.</returns>
1723 public static HttpClientHints GetClientHints ( this HttpContext context )
1824 {
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 ;
2135 }
2236
2337 /// <summary>
@@ -27,25 +41,36 @@ public static HttpClientHints GetClientHints(this HttpContext context)
2741 /// <returns>An instance of <see cref="HttpClientHints"/> populated with the relevant header values.</returns>
2842 public static HttpClientHints GetClientHints ( this IHeaderDictionary headers )
2943 {
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 ;
3350
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 ;
3757
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 ;
4061
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 ;
4365
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 ) ;
4772
48- // return the HttpClientHints record
73+ // Return the HttpClientHints record
4974 return new ( userAgent , platform , platformVersion , architecture , model , fullVersionList , ua , mobile , headers ) ;
5075 }
5176}
0 commit comments