Skip to content

Commit

Permalink
feat: 提供下载服务(仍然无法上线,代码待优化)
Browse files Browse the repository at this point in the history
  • Loading branch information
SALTWOOD committed Mar 9, 2024
1 parent 9e241f0 commit 3d462de
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 27 deletions.
20 changes: 10 additions & 10 deletions CSharp-OpenBMCLAPI/Modules/Cluster.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ public Cluster(ClusterInfo info, TokenManager token) : base()
client.BaseAddress = HttpRequest.client.BaseAddress;
client.DefaultRequestHeaders.Add("User-Agent", $"openbmclapi-cluster/{SharedData.Config.clusterVersion}");
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token.Token.token}");

this.socket = new(HttpRequest.client.BaseAddress?.ToString(), new SocketIOOptions()
{
Transport = SocketIOClient.Transport.TransportProtocol.WebSocket,
Auth = new
{
token = token.Token.token
}
});

}

private void HandleError(SocketIOResponse resp)
Expand Down Expand Up @@ -76,7 +86,6 @@ protected async Task<int> AsyncRun()
{
"http://localhost:4000/"
};
hs.Load();
hs.Start();

await RequestCertification();
Expand All @@ -102,15 +111,6 @@ protected async Task<int> AsyncRun()

public void Connect()
{
this.socket = new(HttpRequest.client.BaseAddress?.ToString(), new SocketIOOptions()
{
Transport = SocketIOClient.Transport.TransportProtocol.WebSocket,
Auth = new
{
token = token.Token.token
}
});

this.socket.ConnectAsync().Wait();

this.socket.On("error", error => HandleError(error));
Expand Down
94 changes: 80 additions & 14 deletions CSharp-OpenBMCLAPI/Modules/HttpServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using TeraIO.Network.Http;
Expand All @@ -10,33 +11,98 @@ namespace CSharpOpenBMCLAPI.Modules
{
public class HttpServer : HttpServerAppBase
{
public HttpServer() : base() { }
public HttpServer() : base() => LoadNew();

[HttpHandler("/measure")]
public void Measure(HttpClientRequest req)
{
Dictionary<string, string> pairs = new();
if (req.Request.RawUrl != null)
string? url = req.Request.RawUrl?.Split('?').FirstOrDefault();

Dictionary<string, string> pairs = ParseRequest(req);
bool valid = Utils.CheckSign(url, SharedData.ClusterInfo.ClusterSecret, pairs.GetValueOrDefault("s"), pairs.GetValueOrDefault("e"));
if (valid)
{
byte[] bytes = new byte[1024];
for (int i = 0; i < Convert.ToInt32(url?.Split('/').LastOrDefault()); i++)
{
for (int j = 0; j < 1024; j++)
{
req.ResponseStatusCode = 200;
req.Send(bytes);
}
}
req.Response.Close();
}
else
{
req.ResponseStatusCode = 403;
req.Send($"Access to \"{req.Request.RawUrl}\" has been blocked due to your request timeout or invalidity.");
}
}

[HttpHandler("/download/")]
public void DownloadHash(HttpClientRequest req)
{
var pairs = ParseRequest(req);
string? hash = req.Request.RawUrl?.Split('?').FirstOrDefault()?.Split('/').LastOrDefault();
string? s = pairs.GetValueOrDefault("s");
string? e = pairs.GetValueOrDefault("e");

bool valid = Utils.CheckSign(hash, SharedData.ClusterInfo.ClusterSecret, s, e);

if (valid && hash != null && s != null && e != null)
{
foreach ((string key, string value) in req.Request.RawUrl.Split('?').Last().Split('&').Select(param => (param.Split('=')[0], param.Split('=')[1])))
string? range = req.Request.Headers.GetValues("Range")?.FirstOrDefault();
try
{
pairs[key] = value;
if (range != null)
{
(int from, int to) = (Convert.ToInt32(range?.Split('-')[0]), Convert.ToInt32(range?.Split('-')[1]));
using var file = File.OpenRead($"{SharedData.Config.clusterFileDirectory}cache/{hash[0..2]}/{hash}");
file.Position = from;
byte[] buffer = new byte[to - from + 1];
file.Read(buffer, 0, to - from + 1);
req.ResponseStatusCode = 206;
req.Send(buffer);
}
else
{
using var file = File.OpenRead($"{SharedData.Config.clusterFileDirectory}cache/{hash[0..2]}/{hash}");
file.CopyTo(req.OutputStream);
}
}
bool valid = Utils.CheckSign(req.Request.RawUrl, SharedData.ClusterInfo.ClusterSecret, pairs.GetValueOrDefault("s"), pairs.GetValueOrDefault("e"));
if (valid)
catch
{
byte[] bytes = new byte[1024];
for (int i = 0; i < Convert.ToInt32(pairs.GetValueOrDefault("e"), 36); i++)
var destination = req.Request.Headers.GetValues("Referer")?.FirstOrDefault();
if (destination != null)
{
for (int j = 0; j < 1024; j++)
{
req.Send(bytes);
}
req.ResponseStatusCode = 302;
req.Response.AddHeader("Location", destination);
}
else
{
req.Response.Close();
}
}
}
else
{
req.ResponseStatusCode = 403;
req.Send($"Access to \"{req.Request.RawUrl}\" has been blocked due to your request timeout or invalidity.");
}
}

public void Load() => this.LoadNew();
private static Dictionary<string, string> ParseRequest(HttpClientRequest req)
{
Dictionary<string, string> pairs = new();
if (req.Request.RawUrl != null)
{
foreach ((string? key, string? value) in req.Request.RawUrl.Split('?').Last().Split('&').Select(param => (param.Split('=').FirstOrDefault(), param.Split('=').LastOrDefault())))
{
if (key != null && value != null) pairs[key] = value;
}
}
return pairs;
}
}
}
30 changes: 27 additions & 3 deletions CSharp-OpenBMCLAPI/Modules/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,39 @@ namespace CSharpOpenBMCLAPI.Modules
{
public static class Utils
{
public static bool CheckSign(string hash, string secret, string? s, string? e)
static long ToDecimal(string hex)
{
Dictionary<char, int> pairs = new();
int count = 0;
foreach (char i in "0123456789abcdefghijklmnopqrstuvwxyz")
{
pairs[i] = count;
count++;
}
long decimalValue = 0;
for (int i = 0; i < hex.Length; i++)
{
char c = hex[i];
int digit = pairs[c];
decimalValue = decimalValue * 36 + digit;
}
return decimalValue;
}

public static string ToUrlSafeBase64String(string b) => b.Replace('/', '_').Replace('+', '-').Replace("=", "");
public static string ToUrlSafeBase64String(byte[] b) => Convert.ToBase64String(b).Replace('/', '_').Replace('+', '-').Replace("=", "");

public static bool CheckSign(string? hash, string? secret, string? s, string? e)
{
if (string.IsNullOrEmpty(e) || string.IsNullOrEmpty(s))
{
return false;
}
var sha1 = SHA1.Create();
var sign = Convert.ToBase64String(sha1.ComputeHash(Encoding.UTF8.GetBytes($"{secret}{hash}{e}")));
return sign == s && DateTime.Now.Ticks < (Convert.ToInt32(e, 36) / 100);
var sign = ToUrlSafeBase64String(sha1.ComputeHash(Encoding.UTF8.GetBytes($"{secret}{hash}{e}")));
var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
var a = timestamp < (ToDecimal(e) / 100);
return sign == s && timestamp < (ToDecimal(e) / 100);
}

}
Expand Down

0 comments on commit 3d462de

Please sign in to comment.