ParadoxSaveParser/ParadoxSaveParser.WebAPI/HttpHelpers/ReturnHelper.cs

96 lines
3.3 KiB
C#

using System.IO;
using System.Net;
using System.Text.Encodings.Web;
using System.Text.Json.Serialization;
using DTLib.Extensions;
namespace ParadoxSaveParser.WebAPI.HttpHelpers;
public class ReturnHelper
{
private static readonly JsonSerializerOptions _responseJsonSerializerOptions = new()
{
WriteIndented = false,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
MaxDepth = 1024,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
};
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($"short 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);
}
public static async Task<HttpStatusCode> ResponseStream(HttpListenerContext ctx,
ContextLogger logger,
CancellationToken ct,
Stream valueStream,
HttpStatusCode statusCode = HttpStatusCode.OK,
string contentType = "application/octet-stream")
{
try
{
ctx.Response.StatusCode = (int)statusCode;
ctx.Response.ContentType = contentType;
logger.LogDebug($"stream response (type: {contentType})");
await valueStream.CopyToAsync(ctx.Response.OutputStream, ct);
return statusCode;
}
catch (Exception ex)
{
return await ResponseError(ctx, logger, ct,
new ErrorMessage(HttpStatusCode.InternalServerError,
ex.ToStringDemystified()));
}
}
}