Skip to content

Commit

Permalink
feat: 修了一堆 bug,现在能上线了
Browse files Browse the repository at this point in the history
remove: 删掉了插件系统什么的
  • Loading branch information
SALTWOOD committed Jul 14, 2024
1 parent e77f8a7 commit 43c3a1a
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 336 deletions.
16 changes: 7 additions & 9 deletions CSharp-OpenBMCLAPI/Modules/Cluster.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CSharpOpenBMCLAPI.Modules.Plugin;
using CSharpOpenBMCLAPI.Modules.Storage;
using CSharpOpenBMCLAPI.Modules.Storage;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
Expand Down Expand Up @@ -91,12 +90,10 @@ protected SocketIOClient.SocketIO InitializeSocket()
/// <returns></returns>
public int Start()
{
requiredData.PluginManager.TriggerEvent(this, ProgramEventType.ClusterStarted);
// 工作进程启动
Logger.Instance.LogSystem($"工作进程 {guid} 已启动");
Task<int> task = AsyncRun();
task.Wait();
requiredData.PluginManager.TriggerEvent(this, ProgramEventType.ClusterStopped);
return task.Result;
}

Expand Down Expand Up @@ -177,7 +174,7 @@ private void InitializeService()
WebApplicationBuilder builder = WebApplication.CreateBuilder();
builder.WebHost.UseKestrel(options =>
{
options.ListenAnyIP(9388, cert != null ? configure =>
options.ListenAnyIP(ClusterRequiredData.Config.PORT, cert != null ? configure =>
{
configure.UseHttps(cert);
}
Expand All @@ -186,15 +183,16 @@ private void InitializeService()
application = builder.Build();

// 下载路由
application.MapGet("/download/{hash}", (HttpContext context, string hash) =>
application.MapGet("/download/{hash}", async (HttpContext context, string hash) =>
{
FileAccessInfo fai = HttpServiceProvider.DownloadHash(context, this).Result;
FileAccessInfo fai = await HttpServiceProvider.DownloadHash(context, this, hash);
this.counter.Add(fai);
return Task.CompletedTask;
});

// 测速路由
application.MapGet("/measure", (context) => HttpServiceProvider.Measure(context, this));
application.MapGet("/measure/{size}", async (HttpContext context, int size) => await HttpServiceProvider.Measure(context, this, size));

application.MapGet("/api/{name}", async (HttpContext context, string name) => await HttpServiceProvider.Api(context, name, this));

// 因为暂时禁用面板而注释掉

Expand Down
4 changes: 1 addition & 3 deletions CSharp-OpenBMCLAPI/Modules/ClusterRequiredData.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CSharpOpenBMCLAPI.Modules.Plugin;
using CSharpOpenBMCLAPI.Modules.Statistician;
using CSharpOpenBMCLAPI.Modules.Statistician;

namespace CSharpOpenBMCLAPI.Modules
{
Expand All @@ -9,7 +8,6 @@ public class ClusterRequiredData
public Logger Logger { get => Logger.Instance; }
public ClusterInfo ClusterInfo { get; set; }
public TokenManager Token { get; set; }
public PluginManager PluginManager { get => PluginManager.Instance; }
public static DataStatistician DataStatistician { get; set; } = new DataStatistician();
public SemaphoreSlim SemaphoreSlim { get; set; } = new SemaphoreSlim(0);

Expand Down
1 change: 1 addition & 0 deletions CSharp-OpenBMCLAPI/Modules/HttpRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ static HttpRequest()
{
client = new HttpClient()
{
// BaseAddress = new Uri("http://saltwood.top:9393")
// 设置基础地址,根据配置文件中的StagingMode属性判断使用哪个地址
BaseAddress = ClusterRequiredData.Config.StagingMode ?
new Uri("https://openbmclapi.staging.bangbang93.com/") :
Expand Down
158 changes: 73 additions & 85 deletions CSharp-OpenBMCLAPI/Modules/HttpServiceProvider.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using CSharpOpenBMCLAPI.Modules.Plugin;
using CSharpOpenBMCLAPI.Modules.Storage;
using CSharpOpenBMCLAPI.Modules.Storage;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System;

namespace CSharpOpenBMCLAPI.Modules
{
Expand All @@ -28,20 +28,20 @@ public static void LogAccess(HttpContext context)
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static async Task Measure(HttpContext context, Cluster cluster)
public static async Task Measure(HttpContext context, Cluster cluster, int size)
{
PluginManager.Instance.TriggerHttpEvent(context, HttpEventType.ClientMeasure);
var pairs = Utils.GetQueryStrings(context.Request.Path.Value?.Split('?').Last());
context.Request.Query.TryGetValue("s", out StringValues s);
context.Request.Query.TryGetValue("e", out StringValues e);
bool valid = Utils.CheckSign(context.Request.Path.Value?.Split('?').First()
, cluster.requiredData.ClusterInfo.ClusterSecret
, pairs.GetValueOrDefault("s")
, pairs.GetValueOrDefault("e")
, s.FirstOrDefault()
, e.FirstOrDefault()
);
if (valid)
{
context.Response.StatusCode = 200;
byte[] buffer = new byte[1024];
for (int i = 0; i < Convert.ToInt32(context.Request.Path.Value?.Split('/').Last().Split('?').First()); i++)
for (int i = 0; i < size; i++)
{
for (int j = 0; j < 1024; j++)
{
Expand All @@ -63,108 +63,96 @@ public static async Task Measure(HttpContext context, Cluster cluster)
/// <param name="context"></param>
/// <param name="storage"></param>
/// <returns></returns>
public static async Task<FileAccessInfo> DownloadHash(HttpContext context, Cluster cluster)
public static async Task<FileAccessInfo> DownloadHash(HttpContext context, Cluster cluster, string hash)
{
PluginManager.Instance.TriggerHttpEvent(context, HttpEventType.ClientDownload);
// 处理用户下载
FileAccessInfo fai = default;
var pairs = Utils.GetQueryStrings(context.Request.Path.Value?.Split('?').Last());
string? hash = context.Request.Path.Value?.Split('/').LastOrDefault()?.Split('?').First();
string? s = pairs.GetValueOrDefault("s");
string? e = pairs.GetValueOrDefault("e");
context.Request.Query.TryGetValue("s", out StringValues s);
context.Request.Query.TryGetValue("e", out StringValues e);

bool valid = Utils.CheckSign(hash, cluster.clusterInfo.ClusterSecret, s, e);
bool isValid = Utils.CheckSign(hash, cluster.clusterInfo.ClusterSecret, s.FirstOrDefault(), e.FirstOrDefault());

if (valid && hash != null && s != null && e != null)
if (!cluster.storage.Exists(Utils.HashToFileName(hash)))
{
if (!cluster.storage.Exists(Utils.HashToFileName(hash)))
{
await cluster.FetchFileFromCenter(hash, force: true);
}
LogAccess(context);
context.Response.StatusCode = 404;
}

long from, to;
try
{
if (context.Request.Headers.ContainsKey("range"))
{
// 206 处理部分
context.Response.StatusCode = 206;
(from, to) = ToRangeByte(context.Request.Headers["range"].FirstOrDefault()?.Split("=").Last().Split("-"));
if (to < from && to != -1) (from, to) = (to, from);
long length = 0;
// 获取文件信息
using var stream = cluster.storage.ReadFileStream(Utils.HashToFileName(hash));
long fileSize = cluster.storage.GetFileSize(Utils.HashToFileName(hash));

using (Stream file = cluster.storage.ReadFileStream(Utils.HashToFileName(hash)))
{
if (to == -1) to = file.Length;
// 检查是否支持断点续传
var isRangeRequest = context.Request.Headers.ContainsKey("Range");
if (isRangeRequest)
{
// 解析 Range 头部,获取断点续传的起始位置和结束位置
var rangeHeader = context.Request.Headers["Range"].ToString();
var (startByte, endByte) = GetRange(rangeHeader, fileSize);

length = (to - from + 1);
context.Response.Headers["Content-Length"] = length.ToString();
// 设置响应头部
context.Response.StatusCode = 206; // Partial Content
context.Response.Headers.Append("Accept-Ranges", "bytes");
context.Response.Headers.Append("Content-Range", $"bytes {startByte}-{endByte}/{fileSize}");
// context.Response.Headers.Append("Content-Type", MimeTypesMap.GetMimeType(fullPath));
context.Response.Headers.Append("Content-Disposition", $"attachment; filename=\"{Path.GetFileName(hash)}\"");

file.Seek(from, SeekOrigin.Begin);
byte[] buffer = new byte[4096];
for (; file.Position < to;)
{
int count = file.Read(buffer, 0, buffer.Length);
if (file.Position > to && file.Position - count < to) await context.Response.Body.WriteAsync(buffer[..(int)(count - file.Position + to + 1)]);
else if (count != buffer.Length) await context.Response.Body.WriteAsync(buffer[..(count)]);
else await context.Response.Body.WriteAsync(buffer);
}
context.Response.Headers["Content-Range"] = $"{from}-{to}/{file.Length}";
}
// 计算要读取的字节数
var totalBytesToRead = endByte - startByte + 1;

using (Stream file = cluster.storage.ReadFileStream(Utils.HashToFileName(hash)))
{
context.Response.Headers["Content-Length"] = totalBytesToRead.ToString();

context.Response.Headers["x-bmclapi-hash"] = hash;
context.Response.Headers["Accept-Ranges"] = "bytes";
context.Response.Headers["Content-Type"] = "application/octet-stream";
context.Response.Headers["Connection"] = "closed";
fai = new FileAccessInfo
{
hits = 1,
bytes = length
};
ClusterRequiredData.DataStatistician.DownloadCount(fai);
}
else
file.Seek(startByte, SeekOrigin.Begin);
byte[] buffer = new byte[4096];
for (; file.Position < endByte;)
{
fai = await cluster.storage.HandleRequest(Utils.HashToFileName(hash), context);
ClusterRequiredData.DataStatistician.DownloadCount(fai);
int count = file.Read(buffer, 0, buffer.Length);
if (file.Position > endByte && file.Position - count < endByte) await context.Response.Body.WriteAsync(buffer[..(int)(count - file.Position + endByte + 1)]);
else if (count != buffer.Length) await context.Response.Body.WriteAsync(buffer[..(count)]);
else await context.Response.Body.WriteAsync(buffer);
}
}
catch (Exception ex)
LogAccess(context);
return new FileAccessInfo
{
Logger.Instance.LogError(ex.ExceptionToDetail());
Logger.Instance.LogError(context.Request.Path);
//Logger.Instance.LogError(ex.StackTrace);
context.Response.StatusCode = 404;
}
hits = 1,
bytes = totalBytesToRead
};
}
else
{
context.Response.StatusCode = 403;
context.Response.Headers.Remove("Content-Length");
await context.Response.WriteAsync($"Access to \"{context.Request.Path}\" has been blocked due to your request timeout or invalidity.");
// 设置响应头部
context.Response.Headers.Append("Accept-Ranges", "bytes");
context.Response.Headers.Append("Content-Disposition", $"attachment; filename=\"{Path.GetFileName(hash)}\"");
//context.Response.Headers.Append("Content-Type", MimeTypesMap.GetMimeType(fullPath));
context.Response.Headers.Append("Content-Range", $"bytes {0}-{fileSize - 1}/{fileSize}");
LogAccess(context);
return await cluster.storage.HandleRequest(Utils.HashToFileName(hash), context);
}
LogAccess(context);
return fai;
}

private static (long from, long to) ToRangeByte(string[]? rangeHeader)

private static (long startByte, long endByte) GetRange(string rangeHeader, long fileSize)
{
int from, to;
if (string.IsNullOrWhiteSpace(rangeHeader?.FirstOrDefault()))
from = 0;
else
from = Convert.ToInt32(rangeHeader?.FirstOrDefault());
if (string.IsNullOrWhiteSpace(rangeHeader?.LastOrDefault()))
to = -1;
else
to = Convert.ToInt32(rangeHeader?.LastOrDefault());
return (from, to);
if (rangeHeader.Length <= 6) return (0, fileSize);
var ranges = rangeHeader[6..].Split("-");
try
{
if (ranges[1].Length > 0)
{
return (long.Parse(ranges[0]), long.Parse(ranges[1]));
}
}
catch (Exception)
{
return (long.Parse(ranges[0]), fileSize - 1);
}

return (long.Parse(ranges[0]), fileSize - 1);
}

public static async Task Api(HttpContext context, string query, Cluster cluster)
{
PluginManager.Instance.TriggerHttpEvent(context, HttpEventType.ClientOtherRequest);
context.Response.Headers["content-type"] = "application/json";
context.Response.Headers["access-control-allow-origin"] = "*";
context.Response.StatusCode = 200;
Expand Down
9 changes: 0 additions & 9 deletions CSharp-OpenBMCLAPI/Modules/Plugin/HttpEventType.cs

This file was deleted.

8 changes: 0 additions & 8 deletions CSharp-OpenBMCLAPI/Modules/Plugin/PluginAttribute.cs

This file was deleted.

43 changes: 0 additions & 43 deletions CSharp-OpenBMCLAPI/Modules/Plugin/PluginBase.cs

This file was deleted.

21 changes: 0 additions & 21 deletions CSharp-OpenBMCLAPI/Modules/Plugin/PluginHttpEvent.cs

This file was deleted.

Loading

0 comments on commit 43c3a1a

Please sign in to comment.