|
6 | 6 | using Uno.Foundation;
|
7 | 7 | using Windows.Web.Http;
|
8 | 8 |
|
9 |
| -namespace Uno.Web.Http |
| 9 | +namespace Uno.Web.Http; |
| 10 | + |
| 11 | +/// <summary> |
| 12 | +/// Provides read-write access to browser Cookies in WebAssembly. |
| 13 | +/// </summary> |
| 14 | +public class CookieManager |
10 | 15 | {
|
| 16 | + private const char ValueSeparator = '='; |
| 17 | + private const char AttributeSeparator = ';'; |
| 18 | + |
| 19 | + private static readonly Lazy<CookieManager> _cookieManager = new Lazy<CookieManager>(() => new CookieManager()); |
| 20 | + |
| 21 | + private CookieManager() |
| 22 | + { |
| 23 | + } |
| 24 | + |
11 | 25 | /// <summary>
|
12 |
| - /// Provides read-write access to browser Cookies in WebAssembly. |
| 26 | + /// Retrieves the default instance of CookieManager. |
13 | 27 | /// </summary>
|
14 |
| - public class CookieManager |
15 |
| - { |
16 |
| - private const char ValueSeparator = '='; |
17 |
| - private const char AttributeSeparator = ';'; |
| 28 | + /// <returns>Cookie manager instance.</returns> |
| 29 | + public static CookieManager GetDefault() => _cookieManager.Value; |
18 | 30 |
|
19 |
| - private static readonly Lazy<CookieManager> _cookieManager = new Lazy<CookieManager>(() => new CookieManager()); |
| 31 | + /// <summary> |
| 32 | + /// Sets a cookie given attributes. |
| 33 | + /// </summary> |
| 34 | + /// <param name="request">Set cookie request</param> |
| 35 | + public void SetCookie(SetCookieRequest request) |
| 36 | + { |
| 37 | + var httpCookie = new HttpCookie(request.Cookie.Name, request.Domain ?? string.Empty, request.Path ?? string.Empty) |
| 38 | + { |
| 39 | + Secure = request.Secure, |
| 40 | + Expires = request.Expires, |
| 41 | + Value = request.Cookie.Value, |
| 42 | + }; |
| 43 | + var serializedCookie = httpCookie.ToString(); |
20 | 44 |
|
21 |
| - private CookieManager() |
| 45 | + if (request.MaxAge != null) |
22 | 46 | {
|
| 47 | + serializedCookie += $"; max-age={request.MaxAge.Value.ToString(CultureInfo.InvariantCulture)}"; |
23 | 48 | }
|
24 |
| - |
25 |
| - /// <summary> |
26 |
| - /// Retrieves the default instance of CookieManager. |
27 |
| - /// </summary> |
28 |
| - /// <returns>Cookie manager instance.</returns> |
29 |
| - public static CookieManager GetDefault() => _cookieManager.Value; |
30 |
| - |
31 |
| - /// <summary> |
32 |
| - /// Sets a cookie given attributes. |
33 |
| - /// </summary> |
34 |
| - /// <param name="request">Set cookie request</param> |
35 |
| - public void SetCookie(SetCookieRequest request) |
| 49 | + if (request.SameSite != null) |
36 | 50 | {
|
37 |
| - var httpCookie = new HttpCookie(request.Cookie.Name, request.Domain ?? string.Empty, request.Path ?? string.Empty) |
38 |
| - { |
39 |
| - Secure = request.Secure, |
40 |
| - Expires = request.Expires, |
41 |
| - Value = request.Cookie.Value, |
42 |
| - }; |
43 |
| - var serializedCookie = httpCookie.ToString(); |
44 |
| - |
45 |
| - if (request.MaxAge != null) |
46 |
| - { |
47 |
| - serializedCookie += $"; max-age={request.MaxAge.Value.ToString(CultureInfo.InvariantCulture)}"; |
48 |
| - } |
49 |
| - if (request.SameSite != null) |
50 |
| - { |
51 |
| - serializedCookie += $"; samesite={request.SameSite.Value.ToString("g").ToLowerInvariant()}"; |
52 |
| - } |
53 |
| - |
54 |
| - var escapedCookie = WebAssemblyRuntime.EscapeJs(serializedCookie); |
55 |
| - var jsInvoke = $"document.cookie = '{escapedCookie}'"; |
56 |
| - WebAssemblyRuntime.InvokeJS(jsInvoke); |
| 51 | + serializedCookie += $"; samesite={request.SameSite.Value.ToString("g").ToLowerInvariant()}"; |
57 | 52 | }
|
58 | 53 |
|
59 |
| - /// <summary> |
60 |
| - /// Deletes a cookies by name. |
61 |
| - /// </summary> |
62 |
| - /// <param name="name">Name of the cookie.</param> |
63 |
| - /// <param name="domain">Domain of the cookie (optional).</param> |
64 |
| - /// <param name="path">Path of the cookie (optional).</param> |
65 |
| - public void DeleteCookie(string name, string? domain = null, string? path = null) |
| 54 | + var escapedCookie = WebAssemblyRuntime.EscapeJs(serializedCookie); |
| 55 | + var jsInvoke = $"document.cookie = '{escapedCookie}'"; |
| 56 | + WebAssemblyRuntime.InvokeJS(jsInvoke); |
| 57 | + } |
| 58 | + |
| 59 | + /// <summary> |
| 60 | + /// Deletes a cookies by name. |
| 61 | + /// </summary> |
| 62 | + /// <param name="name">Name of the cookie.</param> |
| 63 | + /// <param name="domain">Domain of the cookie (optional).</param> |
| 64 | + /// <param name="path">Path of the cookie (optional).</param> |
| 65 | + public void DeleteCookie(string name, string? domain = null, string? path = null) |
| 66 | + { |
| 67 | + var setCookieRequest = new SetCookieRequest(new Cookie(name, string.Empty)) |
66 | 68 | {
|
67 |
| - var setCookieRequest = new SetCookieRequest(new Cookie(name, string.Empty)) |
68 |
| - { |
69 |
| - Expires = DateTimeOffset.MinValue, |
70 |
| - Path = path, |
71 |
| - Domain = domain |
72 |
| - }; |
| 69 | + Expires = DateTimeOffset.MinValue, |
| 70 | + Path = path, |
| 71 | + Domain = domain |
| 72 | + }; |
73 | 73 |
|
74 |
| - SetCookie(setCookieRequest); |
75 |
| - } |
| 74 | + SetCookie(setCookieRequest); |
| 75 | + } |
76 | 76 |
|
77 |
| - /// <summary> |
78 |
| - /// Retrieves a cookie by name. |
79 |
| - /// </summary> |
80 |
| - /// <param name="name">Cookie name.</param> |
81 |
| - /// <returns>Cookie or null if not found.</returns> |
82 |
| - public Cookie? FindCookie(string name) => GetCookies().FirstOrDefault(c => c.Name == name); |
83 |
| - |
84 |
| - /// <summary> |
85 |
| - /// Gets array of currently active cookies. |
86 |
| - /// </summary> |
87 |
| - /// <returns>Active cookies.</returns> |
88 |
| - public Cookie[] GetCookies() |
| 77 | + /// <summary> |
| 78 | + /// Retrieves a cookie by name. |
| 79 | + /// </summary> |
| 80 | + /// <param name="name">Cookie name.</param> |
| 81 | + /// <returns>Cookie or null if not found.</returns> |
| 82 | + public Cookie? FindCookie(string name) => GetCookies().FirstOrDefault(c => c.Name == name); |
| 83 | + |
| 84 | + /// <summary> |
| 85 | + /// Gets array of currently active cookies. |
| 86 | + /// </summary> |
| 87 | + /// <returns>Active cookies.</returns> |
| 88 | + public Cookie[] GetCookies() |
| 89 | + { |
| 90 | + Cookie? ParseCookie(string cookieString) |
89 | 91 | {
|
90 |
| - Cookie? ParseCookie(string cookieString) |
| 92 | + cookieString = cookieString.Trim(); |
| 93 | + var valueSeparatorIndex = cookieString.IndexOf(ValueSeparator); |
| 94 | + if (valueSeparatorIndex == -1) |
91 | 95 | {
|
92 |
| - cookieString = cookieString.Trim(); |
93 |
| - var valueSeparatorIndex = cookieString.IndexOf(ValueSeparator); |
94 |
| - if (valueSeparatorIndex == -1) |
95 |
| - { |
96 |
| - return null; |
97 |
| - } |
98 |
| - |
99 |
| - var name = cookieString.Substring(0, valueSeparatorIndex); |
100 |
| - var valueStartIndex = valueSeparatorIndex + 1; |
101 |
| - var value = cookieString.Substring(valueStartIndex, cookieString.Length - valueStartIndex); |
102 |
| - return new Cookie(name, value); |
| 96 | + return null; |
103 | 97 | }
|
104 | 98 |
|
105 |
| - var cookies = WebAssemblyRuntime.InvokeJS("document.cookie"); |
106 |
| - if (string.IsNullOrWhiteSpace(cookies)) |
107 |
| - { |
108 |
| - return Array.Empty<Cookie>(); |
109 |
| - } |
| 99 | + var name = cookieString.Substring(0, valueSeparatorIndex); |
| 100 | + var valueStartIndex = valueSeparatorIndex + 1; |
| 101 | + var value = cookieString.Substring(valueStartIndex, cookieString.Length - valueStartIndex); |
| 102 | + return new Cookie(name, value); |
| 103 | + } |
110 | 104 |
|
111 |
| - var cookieStrings = cookies.Split(new char[] { AttributeSeparator }, StringSplitOptions.RemoveEmptyEntries); |
112 |
| - return cookieStrings |
113 |
| - .Select(part => ParseCookie(part)) |
114 |
| - .Where(cookie => cookie != null) |
115 |
| - .OfType<Cookie>() |
116 |
| - .ToArray(); |
| 105 | + var cookies = WebAssemblyRuntime.InvokeJS("document.cookie"); |
| 106 | + if (string.IsNullOrWhiteSpace(cookies)) |
| 107 | + { |
| 108 | + return Array.Empty<Cookie>(); |
117 | 109 | }
|
| 110 | + |
| 111 | + var cookieStrings = cookies.Split(new char[] { AttributeSeparator }, StringSplitOptions.RemoveEmptyEntries); |
| 112 | + return cookieStrings |
| 113 | + .Select(part => ParseCookie(part)) |
| 114 | + .Where(cookie => cookie != null) |
| 115 | + .OfType<Cookie>() |
| 116 | + .ToArray(); |
118 | 117 | }
|
119 | 118 | }
|
0 commit comments