86 lines
3.1 KiB
C#
86 lines
3.1 KiB
C#
|
|
using System;
|
|||
|
|
using System.Reflection;
|
|||
|
|
using HarmonyLib;
|
|||
|
|
using Minio.DataModel;
|
|||
|
|
using Minio.Exceptions;
|
|||
|
|
|
|||
|
|
namespace Hopetry.Provider
|
|||
|
|
{
|
|||
|
|
public class PartSizeOverride
|
|||
|
|
{
|
|||
|
|
private static Harmony _harmony;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 使用Harmony动态替换MinIO的分片计算逻辑
|
|||
|
|
/// </summary>
|
|||
|
|
public static void OverrideMinioCalculator()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
// 初始化Harmony实例
|
|||
|
|
_harmony = new Harmony("com.hopetry.minio.patch");
|
|||
|
|
|
|||
|
|
// 获取原始方法和自定义方法
|
|||
|
|
var originalMethod = typeof(Minio.Helper.Utils).GetMethod(
|
|||
|
|
"CalculateMultiPartSize",
|
|||
|
|
BindingFlags.Static | BindingFlags.Public,
|
|||
|
|
null,
|
|||
|
|
new[] { typeof(long), typeof(bool) },
|
|||
|
|
null);
|
|||
|
|
|
|||
|
|
var customMethod = typeof(PartSizeOverride).GetMethod(
|
|||
|
|
"CustomCalculateMultiPartSize",
|
|||
|
|
BindingFlags.Static | BindingFlags.NonPublic);
|
|||
|
|
|
|||
|
|
if (originalMethod == null || customMethod == null)
|
|||
|
|
throw new InvalidOperationException("Method not found");
|
|||
|
|
|
|||
|
|
// 应用Harmony补丁(替换原始方法)
|
|||
|
|
_harmony.Patch(originalMethod,
|
|||
|
|
new HarmonyMethod(customMethod));
|
|||
|
|
|
|||
|
|
Console.WriteLine("Method override successful");
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Console.WriteLine($"Override failed: {ex.Message}");
|
|||
|
|
throw;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 自定义分片计算逻辑(需严格匹配原始方法签名)
|
|||
|
|
/// </summary>
|
|||
|
|
private static bool CustomCalculateMultiPartSize(ref MultiPartInfo __result, long size, bool copy)
|
|||
|
|
{
|
|||
|
|
// 原计算逻辑保持不变
|
|||
|
|
long MaxParts = 10000;
|
|||
|
|
long MinimumPartSize = 5 * 1024L * 1024L;
|
|||
|
|
long MinimumPUTPartSize = 16 * 1024L * 1024L;
|
|||
|
|
long MaximumStreamObjectSize = MaxParts * MinimumPartSize;
|
|||
|
|
long MaxMultipartPutObjectSize = 1024L * 1024L * 1024L * 1024L * 5;
|
|||
|
|
if (size == -1) size = MaximumStreamObjectSize;
|
|||
|
|
long MinimumCOPYPartSize = 512 * 1024L * 1024L;
|
|||
|
|
|
|||
|
|
if (size > MaxMultipartPutObjectSize)
|
|||
|
|
throw new EntityTooLargeException(
|
|||
|
|
$"Your proposed upload size {size} exceeds the maximum allowed object size {MaxMultipartPutObjectSize}");
|
|||
|
|
|
|||
|
|
var partSize = (double)Math.Ceiling((decimal)size / MaxParts);
|
|||
|
|
var minPartSize = copy ? MinimumCOPYPartSize : MinimumPartSize;
|
|||
|
|
partSize = (double)Math.Ceiling((decimal)partSize / minPartSize) * minPartSize;
|
|||
|
|
var partCount = Math.Ceiling(size / partSize);
|
|||
|
|
var lastPartSize = size - ((partCount - 1) * partSize);
|
|||
|
|
|
|||
|
|
__result = new MultiPartInfo
|
|||
|
|
{
|
|||
|
|
PartSize = partSize,
|
|||
|
|
PartCount = partCount,
|
|||
|
|
LastPartSize = lastPartSize
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 跳过原始方法执行
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|