301 lines
11 KiB
C#
301 lines
11 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace Pixiview.Utils
|
|
{
|
|
public class HttpUtility
|
|
{
|
|
public static T LoadObject<T>(string file, string url, string referer,
|
|
bool force = false,
|
|
Action<HttpRequestHeaders> header = null,
|
|
Func<T, string> namehandler = null,
|
|
Func<string, string> action = null)
|
|
{
|
|
string content = null;
|
|
if (!force && file != null && File.Exists(file))
|
|
{
|
|
try
|
|
{
|
|
content = File.ReadAllText(file);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.DebugError("load", $"failed to read file: {file}, error: {ex.Message}");
|
|
}
|
|
}
|
|
if (content == null)
|
|
{
|
|
var response = Download(url, headers =>
|
|
{
|
|
if (referer != null)
|
|
{
|
|
headers.Referrer = new Uri(referer);
|
|
}
|
|
headers.Add("User-Agent", Configs.UserAgent);
|
|
headers.Add("Accept", Configs.AcceptJson);
|
|
var cookie = Configs.Cookie;
|
|
if (cookie != null)
|
|
{
|
|
headers.Add("Cookie", cookie);
|
|
}
|
|
if (header == null)
|
|
{
|
|
var userId = Configs.UserId;
|
|
if (userId != null)
|
|
{
|
|
headers.Add("X-User-Id", userId);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
header(headers);
|
|
}
|
|
});
|
|
if (response == null)
|
|
{
|
|
return default;
|
|
}
|
|
using (response)
|
|
{
|
|
try
|
|
{
|
|
content = response.Content.ReadAsStringAsync().Result;
|
|
if (action != null)
|
|
{
|
|
content = action(content);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.DebugError("load.strea", $"failed to read stream, error: {ex.Message}");
|
|
return default;
|
|
}
|
|
|
|
bool rtn = false;
|
|
T result = default;
|
|
if (namehandler != null)
|
|
{
|
|
try
|
|
{
|
|
result = JsonConvert.DeserializeObject<T>(content);
|
|
file = namehandler(result);
|
|
rtn = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.DebugError("load", $"failed to parse illust JSON object, error: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
if (file != null)
|
|
{
|
|
try
|
|
{
|
|
var folder = Path.GetDirectoryName(file);
|
|
if (!Directory.Exists(folder))
|
|
{
|
|
Directory.CreateDirectory(folder);
|
|
}
|
|
File.WriteAllText(file, content, Encoding.UTF8);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.DebugError("save", $"failed to save illust JSON object, error: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
if (rtn)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
try
|
|
{
|
|
return JsonConvert.DeserializeObject<T>(content);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.DebugError("load", $"failed to parse illust JSON object, error: {ex.Message}");
|
|
return default;
|
|
}
|
|
}
|
|
|
|
public static string DownloadImage(string url, string working, string folder)
|
|
{
|
|
try
|
|
{
|
|
var directory = Path.Combine(working, folder);
|
|
if (!Directory.Exists(directory))
|
|
{
|
|
Directory.CreateDirectory(directory);
|
|
}
|
|
var file = Path.Combine(directory, Path.GetFileName(url));
|
|
var response = Download(url, headers =>
|
|
{
|
|
headers.Referrer = new Uri(Configs.Referer);
|
|
headers.Add("User-Agent", Configs.UserAgent);
|
|
headers.Add("Accept", Configs.AcceptImage);
|
|
});
|
|
if (response == null)
|
|
{
|
|
return null;
|
|
}
|
|
using (response)
|
|
using (var fs = File.OpenWrite(file))
|
|
{
|
|
response.Content.CopyToAsync(fs).Wait();
|
|
//if (response.Headers.Date != null)
|
|
//{
|
|
// File.SetLastWriteTimeUtc(file, response.Headers.Date.Value.UtcDateTime);
|
|
//}
|
|
}
|
|
return file;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.DebugError("image.download", ex.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private static HttpResponseMessage Download(string url, Action<HttpRequestHeaders> headerAction)
|
|
{
|
|
App.DebugPrint($"GET: {url}");
|
|
var uri = new Uri(url);
|
|
var proxy = Configs.Proxy;
|
|
var handler = new HttpClientHandler
|
|
{
|
|
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
|
|
UseCookies = false
|
|
};
|
|
if (proxy != null)
|
|
{
|
|
handler.Proxy = proxy;
|
|
handler.UseProxy = true;
|
|
}
|
|
var client = new HttpClient(handler)
|
|
{
|
|
BaseAddress = new Uri($"{uri.Scheme}://{uri.Host}"),
|
|
Timeout = TimeSpan.FromSeconds(30)
|
|
};
|
|
return TryCount(() =>
|
|
{
|
|
using (var request = new HttpRequestMessage(HttpMethod.Get, uri.PathAndQuery)
|
|
{
|
|
Version = new Version(2, 0)
|
|
})
|
|
{
|
|
var headers = request.Headers;
|
|
headerAction(headers);
|
|
if (proxy == null)
|
|
{
|
|
headers.Add("x-reverse", "yes");
|
|
}
|
|
headers.Add("Accept-Language", Configs.AcceptLanguage);
|
|
//headers.Add("Accept-Encoding", Configs.AcceptEncoding);
|
|
return client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).Result;
|
|
}
|
|
});
|
|
}
|
|
|
|
private static T TryCount<T>(Func<T> func, int tryCount = 2)
|
|
{
|
|
int tries = 0;
|
|
while (tries < tryCount)
|
|
{
|
|
try
|
|
{
|
|
return func();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
tries++;
|
|
Thread.Sleep(1000);
|
|
App.DebugError("try.do", $"tries: {tries}, error: {ex.Message}");
|
|
}
|
|
}
|
|
return default;
|
|
}
|
|
|
|
public static (long Size, DateTimeOffset LastModified, HttpClient Client) GetUgoiraHeader(string url, string id)
|
|
{
|
|
var uri = new Uri(url);
|
|
var proxy = Configs.Proxy;
|
|
var handler = new HttpClientHandler
|
|
{
|
|
UseCookies = false
|
|
};
|
|
if (proxy != null)
|
|
{
|
|
handler.Proxy = proxy;
|
|
handler.UseProxy = true;
|
|
}
|
|
var client = new HttpClient(handler)
|
|
{
|
|
BaseAddress = new Uri($"{uri.Scheme}://{uri.Host}"),
|
|
Timeout = TimeSpan.FromSeconds(30)
|
|
};
|
|
var response = TryCount(() =>
|
|
{
|
|
using (var request = new HttpRequestMessage(HttpMethod.Head, uri.PathAndQuery)
|
|
{
|
|
Version = new Version(2, 0)
|
|
})
|
|
{
|
|
var headers = request.Headers;
|
|
UgoiraHeaderAction(headers, id);
|
|
headers.Add("Accept-Encoding", "gzip, deflate");
|
|
headers.Add("Accept-Language", Configs.AcceptLanguage);
|
|
return client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).Result;
|
|
}
|
|
});
|
|
|
|
var size = response.Content.Headers.ContentLength.Value;
|
|
var lastModified = response.Content.Headers.LastModified.Value;
|
|
|
|
return (size, lastModified, client);
|
|
}
|
|
|
|
public static long DownloadUgoiraImage(HttpClient client, string url, string id, DateTimeOffset lastModified, long from, long to, Stream stream)
|
|
{
|
|
var uri = new Uri(url);
|
|
var response = TryCount(() =>
|
|
{
|
|
using (var request = new HttpRequestMessage(HttpMethod.Get, uri.PathAndQuery)
|
|
{
|
|
Version = new Version(2, 0)
|
|
})
|
|
{
|
|
var headers = request.Headers;
|
|
UgoiraHeaderAction(headers, id);
|
|
headers.Add("Accept-Encoding", "identity");
|
|
headers.IfRange = new RangeConditionHeaderValue(lastModified);
|
|
headers.Range = new RangeHeaderValue(from, to);
|
|
headers.Add("Accept-Language", Configs.AcceptLanguage);
|
|
return client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).Result;
|
|
}
|
|
});
|
|
|
|
var length = response.Content.Headers.ContentLength.Value;
|
|
response.Content.CopyToAsync(stream).Wait();
|
|
return length;
|
|
}
|
|
|
|
private static void UgoiraHeaderAction(HttpRequestHeaders headers, string id)
|
|
{
|
|
headers.Add("Accept", "*/*");
|
|
headers.Add("Origin", Configs.Referer);
|
|
headers.Referrer = new Uri(string.Format(Configs.RefererIllust, id));
|
|
headers.Add("User-Agent", Configs.UserAgent);
|
|
}
|
|
}
|
|
|
|
}
|