Skip to content

Commit

Permalink
Compress the state
Browse files Browse the repository at this point in the history
  • Loading branch information
kjeske committed Nov 6, 2024
1 parent 1dedc9a commit 1572c0f
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 14 deletions.
2 changes: 1 addition & 1 deletion docs/content/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default defineConfig({
text: 'Advanced',
items: [
{ text: 'Request queuing', link: '/advanced/request-queuing' },
{ text: 'Load balancing', link: '/advanced/load-balancing' },
// { text: 'Load balancing', link: '/advanced/load-balancing' },
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/content/features/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ or by calling one of the extension methods:

## State

State of the components is serialized, encrypted and stored on the rendered page. Whenever there is call from that component to the back-end, the state is attached to the request headers.
State of the components is serialized, encoded and stored on the rendered page. Whenever there is call from that component to the back-end, the state is attached to the request headers.

## Components nesting

Expand Down
2 changes: 1 addition & 1 deletion docs/content/features/cookies.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ CookieStorage.Set("theme", "light", encrypt: false, new CookieOptions { Secure =

## Encryption

It's possible to encrypt the cookie value by setting the `encryption` parameter to `true`:
It's possible to encode the cookie value by setting the `encryption` parameter to `true`:

```c#
CookieStorage.Set("theme", "light", encryption: true);
Expand Down
4 changes: 2 additions & 2 deletions src/HydroComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ private HtmlNode GetModelScript(HtmlDocument document, string id, IPersistentSta
scriptNode.SetAttributeValue("type", "text/hydro");
scriptNode.SetAttributeValue("data-id", id);
var serializeDeclaredProperties = PropertyInjector.SerializeDeclaredProperties(GetType(), this);
var model = persistentState.Protect(serializeDeclaredProperties);
var model = persistentState.Compress(serializeDeclaredProperties);
scriptNode.AppendChild(document.CreateTextNode(model));
return scriptNode;
}
Expand Down Expand Up @@ -1008,7 +1008,7 @@ private void PopulateBaseModel(IPersistentState persistentState)
{
if (HttpContext.Items.TryGetValue(HydroConsts.ContextItems.BaseModel, out var baseModel))
{
var unprotect = persistentState.Unprotect((string)baseModel);
var unprotect = persistentState.Decompress((string)baseModel);
JsonConvert.PopulateObject(unprotect, this);
}
}
Expand Down
40 changes: 33 additions & 7 deletions src/PersistentState.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using Microsoft.AspNetCore.DataProtection;
using System.IO.Compression;
using System.Text;

namespace Hydro;

internal interface IPersistentState
{
string Protect(string value);
string Unprotect(string value);
string Compress(string value);
string Decompress(string value);
}

internal class PersistentState : IPersistentState
Expand All @@ -17,10 +19,34 @@ public PersistentState(IDataProtectionProvider provider)
_protector = provider.CreateProtector(nameof(PersistentState));
}

public string Protect(string value) =>
_protector.Protect(value);
public string Compress(string value)
{
var inputBytes = Encoding.UTF8.GetBytes(value);
using var outputStream = new MemoryStream();
using (var brotliStream = new BrotliStream(outputStream, CompressionMode.Compress))
{
brotliStream.Write(inputBytes, 0, inputBytes.Length);
}

return Convert.ToBase64String(outputStream.ToArray());
}

public string Decompress(string value)
{
try
{
using var memoryStream = new MemoryStream(Convert.FromBase64String(value));
using var outputStream = new MemoryStream();
using (var brotliStream = new BrotliStream(memoryStream, CompressionMode.Decompress))
{
brotliStream.CopyTo(outputStream);
}

public string Unprotect(string value) =>
_protector.Unprotect(value);
}
return Encoding.UTF8.GetString(outputStream.ToArray());
}
catch (FormatException)
{
return _protector.Unprotect(value);
}
}
}
4 changes: 2 additions & 2 deletions src/Services/CookieStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public T Get<T>(string key, bool encryption = false, T defaultValue = default)
if (storage != null)
{
var json = encryption
? _persistentState.Unprotect(storage)
? _persistentState.Decompress(storage)
: storage;

return JsonConvert.DeserializeObject<T>(json);
Expand Down Expand Up @@ -80,7 +80,7 @@ public void Set<T>(string key, T value, bool encryption, CookieOptions options)
{
var serializedValue = JsonConvert.SerializeObject(value, JsonSettings);
var finalValue = encryption
? _persistentState.Protect(serializedValue)
? _persistentState.Compress(serializedValue)
: serializedValue;

response.Cookies.Append(key, finalValue, options);
Expand Down

0 comments on commit 1572c0f

Please sign in to comment.