refactored responses

This commit is contained in:
2025-04-06 15:37:32 +05:00
parent 3c1d195849
commit d70b605127
17 changed files with 415 additions and 263 deletions
@@ -0,0 +1,17 @@
using System.Net;
using System.Text.Json.Serialization;
namespace ParadoxSaveParser.WebAPI.HttpHelpers;
public record ErrorMessage
{
public ErrorMessage(HttpStatusCode statusCode, string message)
{
StatusCode = statusCode;
Message = message;
}
[JsonIgnore] public HttpStatusCode StatusCode { get; }
[JsonPropertyName("errorMessage")] public string Message { get; }
}
@@ -0,0 +1,17 @@
using System.Linq;
using System.Net;
namespace ParadoxSaveParser.WebAPI.HttpHelpers;
public class RequestHelper
{
internal static ValueOrError<string> GetQueryValue(HttpListenerContext ctx, string paramName)
{
string[]? values = ctx.Request.QueryString.GetValues(paramName);
string? value = values?.FirstOrDefault();
if (string.IsNullOrEmpty(value))
return new ErrorMessage(HttpStatusCode.BadRequest,
$"No request parameter '{paramName}' provided");
return value;
}
}
@@ -0,0 +1,70 @@
using System.Net;
using System.Text.Encodings.Web;
using DTLib.Extensions;
namespace ParadoxSaveParser.WebAPI.HttpHelpers;
public class ReturnHelper
{
private static readonly JsonSerializerOptions _responseJsonSerializerOptions = new()
{
WriteIndented = false,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
MaxDepth = 1024
};
private static async Task ResponseShort(HttpListenerContext ctx,
ContextLogger logger,
CancellationToken ct,
byte[] value,
HttpStatusCode statusCode,
string contentType)
{
ctx.Response.StatusCode = (int)statusCode;
ctx.Response.ContentType = contentType;
logger.LogDebug($"response (length: {value.Length} type: {contentType})");
if (value.Length > 4000)
{
logger.LogWarn($"response (length: {value.Length} type: {contentType})\n"
+ $"Content is too big for {nameof(ResponseShort)}."
+ $"You should send stream instead of byte array.");
}
await ctx.Response.OutputStream.WriteAsync(value, ct);
}
public static async Task<HttpStatusCode> ResponseString(
HttpListenerContext ctx,
ContextLogger logger,
CancellationToken ct,
string value,
HttpStatusCode statusCode = HttpStatusCode.OK,
string contentType = "text/plain")
{
await ResponseShort(ctx, logger, ct, value.ToBytes(), statusCode, contentType);
logger.LogDebug(value);
return statusCode;
}
public static async Task<HttpStatusCode> ResponseJson(
HttpListenerContext ctx,
ContextLogger logger,
CancellationToken ct,
object value,
HttpStatusCode statusCode = HttpStatusCode.OK)
{
string json = JsonSerializer.Serialize(
value,
value.GetType(),
_responseJsonSerializerOptions);
return await ResponseString(ctx, logger, ct, json, statusCode, "application/json");
}
public static async Task<HttpStatusCode> ResponseError(
HttpListenerContext ctx,
ContextLogger logger,
CancellationToken ct,
ErrorMessage error)
{
return await ResponseJson(ctx, logger, ct, error, error.StatusCode);
}
}
@@ -0,0 +1,19 @@
namespace ParadoxSaveParser.WebAPI.HttpHelpers;
public class ValueOrError<T>
{
public readonly ErrorMessage? Error;
public readonly T? Value;
private ValueOrError(T? value, ErrorMessage? error)
{
Value = value;
Error = error;
}
public bool HasError => Error is not null;
public static implicit operator ValueOrError<T>(T v) => new(v, null);
public static implicit operator ValueOrError<T>(ErrorMessage e) => new(default, e);
}