Files
2025-05-18 13:04:45 +08:00

77 lines
1.9 KiB
C#

// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Linq;
using System.Net.Mime;
using EpicGames.AspNet;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
namespace Jupiter.Controllers
{
public class FormatResolver
{
private readonly IOptionsMonitor<MvcOptions> _mvcOptions;
private readonly string[] _validContentTypes = {
MediaTypeNames.Application.Octet,
MediaTypeNames.Application.Json,
CustomMediaTypeNames.UnrealCompactBinary,
CustomMediaTypeNames.JupiterInlinedPayload,
CustomMediaTypeNames.UnrealCompressedBuffer,
CustomMediaTypeNames.UnrealCompactBinaryPackage
};
public FormatResolver(IOptionsMonitor<MvcOptions> mvcOptions)
{
_mvcOptions = mvcOptions;
}
public string GetResponseType(HttpRequest request, string? format, string defaultContentType)
{
// if format specifier is used it takes precedence over the accept header
if (format != null)
{
string? typeMapping = _mvcOptions.CurrentValue.FormatterMappings.GetMediaTypeMappingForFormat(format);
if (typeMapping == null)
{
throw new Exception($"No mapping defined from format {format} to mime type");
}
return typeMapping;
}
StringValues acceptHeader = request.Headers["Accept"];
if (acceptHeader.Count == 0)
{
// no accept header specified, return default type
return defaultContentType;
}
// */* means to accept anything, so we use the default content type
if (acceptHeader == "*/*")
{
return defaultContentType;
}
foreach (string? header in acceptHeader)
{
if (header == null)
{
continue;
}
if (_validContentTypes.Contains(header, StringComparer.OrdinalIgnoreCase))
{
return header;
}
}
throw new Exception($"Unable to determine response type for header: {acceptHeader}");
}
}
}