Skip to content

Commit

Permalink
Merge pull request #110 from fiskaltrust/fix-rest-response-property-c…
Browse files Browse the repository at this point in the history
…asing

Fix rest json de/serialization backwards compatibility
  • Loading branch information
volllly authored Oct 17, 2023
2 parents 3002d0c + c7233b0 commit 1c191b0
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 6 deletions.
69 changes: 69 additions & 0 deletions src/fiskaltrust.Launcher/Helpers/CustomDateTimeConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;

namespace fiskaltrust.Launcher.Helpers
{
sealed class CustomDateTimeConverter : JsonConverter<DateTime>
{
private readonly static JsonConverter<DateTime> DEFAULT_CONVERTER = (JsonConverter<DateTime>)JsonSerializerOptions.Default.GetConverter(typeof(DateTime));
static readonly DateTime EPOCH = new DateTime(1970, 1, 1, 0, 0, 0);
static readonly DateTimeOffset EPOCH_OFFSET = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);

static readonly Regex REGEX = new Regex("^\\\\?/Date\\(([+-]*\\d+)\\)\\\\?/$", RegexOptions.CultureInvariant);

static readonly Regex REGEX_OFFSET = new Regex("^\\\\?/Date\\(([+-]*\\d+)([+-])(\\d{2})(\\d{2})\\)\\\\?/$", RegexOptions.CultureInvariant);

public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
string formatted = reader.GetString()!;

{
Match match = REGEX_OFFSET.Match(formatted);

if (match.Success)
{
return ReadDateTimeOffset(match).DateTime;
}
}

{
Match match = REGEX.Match(formatted);

if (match.Success)
{
return ReadDateTime(match);
}
}

return DEFAULT_CONVERTER.Read(ref reader, typeToConvert, options);
}

private DateTime ReadDateTime(Match date)
{
if (!long.TryParse(date.Groups[1].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out long unixTime))
{
throw new JsonException();
}

return EPOCH.AddMilliseconds(unixTime);
}

private DateTimeOffset ReadDateTimeOffset(Match date)
{
if (!long.TryParse(date.Groups[1].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out long unixTime)
|| !int.TryParse(date.Groups[3].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int hours)
|| !int.TryParse(date.Groups[4].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int minutes))
{
throw new JsonException();
}

int sign = date.Groups[2].Value[0] == '+' ? 1 : -1;
TimeSpan utcOffset = new TimeSpan(hours * sign, minutes * sign, 0);
return EPOCH_OFFSET.AddMilliseconds(unixTime).ToOffset(utcOffset);
}

public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) => DEFAULT_CONVERTER.Write(writer, value, options);
}
}
9 changes: 4 additions & 5 deletions src/fiskaltrust.Launcher/Helpers/NumberToStringConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ namespace fiskaltrust.Launcher.Helpers
{
public class NumberToStringConverter : JsonConverter<string>
{
private readonly static JsonConverter<string> DEFAULT_CONVERTER = (JsonConverter<string>)JsonSerializerOptions.Default.GetConverter(typeof(string));

public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Number)
Expand All @@ -15,7 +17,7 @@ public class NumberToStringConverter : JsonConverter<string>
return number.ToString(CultureInfo.InvariantCulture);
}

if (reader.TryGetDouble(out var doubleNumber))
if (reader.TryGetDecimal(out var doubleNumber))
{
return doubleNumber.ToString(CultureInfo.InvariantCulture);
}
Expand All @@ -29,9 +31,6 @@ public class NumberToStringConverter : JsonConverter<string>
return null;
}

public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) => DEFAULT_CONVERTER.Write(writer, value, options);
}
}
5 changes: 5 additions & 0 deletions src/fiskaltrust.Launcher/Services/HostingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using System.Security.Cryptography.X509Certificates;
using System.Runtime.Versioning;
using Microsoft.AspNetCore.Server.HttpSys;
using System.Text.Json;

namespace fiskaltrust.Launcher.Services
{
Expand Down Expand Up @@ -133,6 +134,10 @@ private WebApplication CreateRestHost<T>(WebApplicationBuilder builder, Uri uri,
{
options.SerializerOptions.NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString;
options.SerializerOptions.Converters.Add(new NumberToStringConverter());
options.SerializerOptions.Converters.Add(new CustomDateTimeConverter());
options.SerializerOptions.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
options.SerializerOptions.PropertyNamingPolicy = null;
options.SerializerOptions.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull;
});

builder.WebHost.ConfigureBinding(uri, listenOptions => ConfigureTls(listenOptions), isHttps: !string.IsNullOrEmpty(_launcherConfiguration.TlsCertificatePath) || !string.IsNullOrEmpty(_launcherConfiguration.TlsCertificateBase64), allowSynchronousIO: true, useHttpSys: _launcherConfiguration.UseHttpSysBinding!.Value);
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "2.0.0-rc.9",
"version": "2.0.0-rc.10",
"releaseBranches": [
"^refs/tags/v\\d+(?:\\.\\d+)*(?:-.*)?$"
]
Expand Down

0 comments on commit 1c191b0

Please sign in to comment.