http client with cache

This commit is contained in:
HolographicHat
2022-06-13 22:22:40 +08:00
parent bbe7c2cd03
commit 1dcaf7ed8f
6 changed files with 432 additions and 4 deletions

View File

@@ -1,8 +1,14 @@
using System.ComponentModel;
using System.Diagnostics;
using System.IO.Compression;
using System.IO.Pipes;
using System.Net;
using System.Net.Http.Headers;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json.Nodes;
using Google.Protobuf;
using YaeAchievement.Win32;
using static YaeAchievement.Win32.OpenFileFlags;
@@ -10,7 +16,72 @@ namespace YaeAchievement;
public static class Utils {
private static readonly Lazy<HttpClient> CHttpClient = new (() => {
var c = new HttpClient(new HttpClientHandler {
Proxy = new WebProxy("http://127.0.0.1:8888")
}) {
DefaultRequestHeaders = {
UserAgent = {
new ProductInfoHeaderValue("YaeAchievement", GlobalVars.AppVersion.ToString(2))
}
}
};
return c;
});
public static string GetBucketFileAsString(string path) {
return Encoding.UTF8.GetString(GetBucketFileAsByteArray(path));
}
public static byte[] GetBucketFileAsByteArray(string path) {
using var msg = new HttpRequestMessage {
Method = HttpMethod.Get,
RequestUri = new Uri($"{GlobalVars.BucketHost}/{path}")
};
CacheItem? ci = null;
string? etag = null;
var cacheName = $"./cache/{CalculateMD5(path)[..16]}.miko";
if (File.Exists(cacheName)) {
using var input = File.OpenRead(cacheName);
using var dInput = new GZipStream(input, CompressionMode.Decompress);
ci = CacheItem.Parser.ParseFrom(dInput);
etag = ci.Etag;
}
if (etag != null) {
msg.Headers.TryAddWithoutValidation("If-None-Match", $"{etag}");
}
using var response = CHttpClient.Value.Send(msg);
if (response.StatusCode == HttpStatusCode.NotModified) {
return ci!.Content.ToByteArray();
}
response.EnsureSuccessStatusCode();
etag = response.Headers.ETag!.Tag;
var responseBytes = response.Content.ReadAsByteArrayAsync().Result;
using var os = File.OpenWrite(cacheName);
using var cos = new GZipStream(os, CompressionLevel.SmallestSize);
new CacheItem {
Etag = etag,
Version = 3,
Checksum = CalculateMD5(responseBytes),
Content = ByteString.CopyFrom(responseBytes)
}.WriteTo(cos);
return responseBytes;
}
// ReSharper disable once InconsistentNaming
private static string CalculateMD5(string text) {
return CalculateMD5(Encoding.UTF8.GetBytes(text));
}
// ReSharper disable once InconsistentNaming
private static string CalculateMD5(byte[] bytes) {
using var md5 = MD5.Create();
var b = md5.ComputeHash(bytes);
return Convert.ToHexString(b).ToLower();
}
public static void LoadConfig() {
Directory.CreateDirectory("cache");
var conf = JsonNode.Parse(File.ReadAllText(GlobalVars.ConfigFileName))!;
var path = conf["genshinPath"];
if (path == null || CheckGamePathValid(path.GetValue<string>())) {
@@ -112,7 +183,9 @@ public static class Utils {
while (!proc.HasExited) {
var line = reader.ReadLine();
if (line?.Length > 0) {
if (onReceive(line)) break;
if (onReceive(line)) {
break;
}
server.Disconnect();
server.WaitForConnection();
}