diff --git a/BaseModule/Controllers/BookmarkController.cs b/BaseModule/Controllers/BookmarkController.cs index 0890a05..aa1f6d3 100644 --- a/BaseModule/Controllers/BookmarkController.cs +++ b/BaseModule/Controllers/BookmarkController.cs @@ -68,11 +68,8 @@ namespace Lampac.Controllers #region migration storage to sql if (AppInit.conf.sync_user.version != 1 && !string.IsNullOrEmpty(requestInfo.user_uid)) { - string profile_id = getProfileid(requestInfo, HttpContext); - string id = requestInfo.user_uid + profile_id; - - string md5key = AppInit.conf.storage.md5name ? CrypTo.md5(id) : Regex.Replace(id, "[^a-z0-9\\-]", ""); - string storageFile = $"database/storage/sync_favorite/{md5key.Substring(0, 2)}/{md5key.Substring(2)}"; + string profileId = getProfileid(requestInfo, HttpContext); + var storageFile = StorageManager.GetFilePath("sync_favorite", false, requestInfo.user_uid, profileId); if (System.IO.File.Exists(storageFile) && !System.IO.File.Exists($"{storageFile}.migration")) { diff --git a/BaseModule/Controllers/StorageController.cs b/BaseModule/Controllers/StorageController.cs index e9530e2..fc96420 100644 --- a/BaseModule/Controllers/StorageController.cs +++ b/BaseModule/Controllers/StorageController.cs @@ -1,5 +1,4 @@ using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -9,7 +8,6 @@ using Shared.Engine.Utilities; using System; using System.IO; using System.Text; -using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Web; using IO = System.IO; @@ -18,14 +16,6 @@ namespace Lampac.Controllers { public class StorageController : BaseController { - #region StorageController - static StorageController() - { - Directory.CreateDirectory("database/storage"); - Directory.CreateDirectory("database/storage/temp"); - } - #endregion - #region backup.js [HttpGet] [AllowAnonymous] @@ -83,7 +73,7 @@ namespace Lampac.Controllers if (!AppInit.conf.storage.enable) return ContentTo("{\"success\": false, \"msg\": \"disabled\"}"); - string outFile = getFilePath(path, pathfile, false); + string outFile = StorageManager.GetFilePath(path, false, requestInfo, pathfile); if (outFile == null || !IO.File.Exists(outFile)) return ContentTo("{\"success\": false, \"msg\": \"outFile\"}"); @@ -135,7 +125,7 @@ namespace Lampac.Controllers if (HttpContext.Request.ContentLength > AppInit.conf.storage.max_size) return ContentTo("{\"success\": false, \"msg\": \"max_size\"}"); - string outFile = getFilePath(path, pathfile, true); + string outFile = StorageManager.GetFilePath(path, true, requestInfo, pathfile); if (outFile == null) return ContentTo("{\"success\": false, \"msg\": \"outFile\"}"); @@ -164,8 +154,8 @@ namespace Lampac.Controllers { await semaphore.WaitAsync(); - using (var fileStream = new FileStream(outFile, FileMode.Create, FileAccess.Write, FileShare.None, PoolInvk.bufferSize)) - await memoryStream.CopyToAsync(fileStream, PoolInvk.bufferSize); + await using var fileStream = new FileStream(outFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, PoolInvk.bufferSize); + await memoryStream.CopyToAsync(fileStream, PoolInvk.bufferSize); } catch { @@ -216,7 +206,7 @@ namespace Lampac.Controllers if (!AppInit.conf.storage.enable) return ContentTo("{\"success\": false, \"msg\": \"disabled\"}"); - string outFile = getFilePath("temp", null, false, user_uid: key); + string outFile = StorageManager.GetFilePath("temp", false, key); if (outFile == null || !IO.File.Exists(outFile)) return ContentTo("{\"success\": false, \"msg\": \"outFile\"}"); @@ -268,7 +258,7 @@ namespace Lampac.Controllers if (HttpContext.Request.ContentLength > AppInit.conf.storage.max_size) return ContentTo("{\"success\": false, \"msg\": \"max_size\"}"); - string outFile = getFilePath("temp", null, true, user_uid: key); + string outFile = StorageManager.GetFilePath("temp", true, key); if (outFile == null) return ContentTo("{\"success\": false, \"msg\": \"outFile\"}"); @@ -322,35 +312,5 @@ namespace Lampac.Controllers }); } #endregion - - - #region getFilePath - string getFilePath(string path, string pathfile, bool createDirectory, string user_uid = null) - { - if (path == "temp" && string.IsNullOrEmpty(user_uid)) - return null; - - path = Regex.Replace(path, "[^a-z0-9\\-]", "", RegexOptions.IgnoreCase); - - string id = user_uid ?? requestInfo.user_uid; - if (string.IsNullOrEmpty(id)) - return null; - - id += pathfile; - string md5key = AppInit.conf.storage.md5name ? CrypTo.md5(id) : Regex.Replace(id, "[^a-z0-9\\-]", ""); - - if (path == "temp") - { - return $"database/storage/{path}/{md5key}"; - } - else - { - if (createDirectory) - Directory.CreateDirectory($"database/storage/{path}/{md5key.Substring(0, 2)}"); - - return $"database/storage/{path}/{md5key.Substring(0, 2)}/{md5key.Substring(2)}"; - } - } - #endregion } } \ No newline at end of file diff --git a/Catalog/CardController.cs b/Catalog/CardController.cs index 91c4e23..9034fa2 100644 --- a/Catalog/CardController.cs +++ b/Catalog/CardController.cs @@ -51,14 +51,14 @@ namespace Catalog.Controllers html = rch.enable ? await rch.Post(url, init.card_parse.postData, headers, useDefaultHeaders: init.useDefaultHeaders) - : await Http.Post(url, httpdata, headers: headers, proxy: proxy.proxy, timeoutSeconds: init.timeout, httpversion: init.httpversion, useDefaultHeaders: init.useDefaultHeaders); + : await Http.Post(url, httpdata, headers: headers, proxy: proxy.proxy, timeoutSeconds: init.timeout, httpversion: init.GetHttpVersion(), useDefaultHeaders: init.useDefaultHeaders); } else { html = rch.enable ? await rch.Get(url, headers, useDefaultHeaders: init.useDefaultHeaders) : init.priorityBrowser == "playwright" ? await PlaywrightBrowser.Get(init, url, headers, proxy.data, cookies: init.cookies) - : await Http.Get(url, headers: headers, proxy: proxy.proxy, timeoutSeconds: init.timeout, httpversion: init.httpversion, useDefaultHeaders: init.useDefaultHeaders); + : await Http.Get(url, headers: headers, proxy: proxy.proxy, timeoutSeconds: init.timeout, httpversion: init.GetHttpVersion(), useDefaultHeaders: init.useDefaultHeaders); } if (html == null) diff --git a/Catalog/ListController.cs b/Catalog/ListController.cs index 16f3ef6..63063f0 100644 --- a/Catalog/ListController.cs +++ b/Catalog/ListController.cs @@ -99,14 +99,14 @@ namespace Catalog.Controllers html = rch.enable ? await rch.Post(url.Replace("{page}", page.ToString()), data, headers, useDefaultHeaders: init.useDefaultHeaders) - : await Http.Post(url.Replace("{page}", page.ToString()), httpdata, headers: headers, proxy: proxy.proxy, timeoutSeconds: init.timeout, httpversion: init.httpversion, useDefaultHeaders: init.useDefaultHeaders); + : await Http.Post(url.Replace("{page}", page.ToString()), httpdata, headers: headers, proxy: proxy.proxy, timeoutSeconds: init.timeout, httpversion: init.GetHttpVersion(), useDefaultHeaders: init.useDefaultHeaders); } else { html = rch.enable ? await rch.Get(url.Replace("{page}", page.ToString()), headers, useDefaultHeaders: init.useDefaultHeaders) : init.priorityBrowser == "playwright" ? await PlaywrightBrowser.Get(init, url.Replace("{page}", page.ToString()), headers, proxy.data, cookies: init.cookies) - : await Http.Get(url.Replace("{page}", page.ToString()), headers: headers, proxy: proxy.proxy, timeoutSeconds: init.timeout, httpversion: init.httpversion, useDefaultHeaders: init.useDefaultHeaders); + : await Http.Get(url.Replace("{page}", page.ToString()), headers: headers, proxy: proxy.proxy, timeoutSeconds: init.timeout, httpversion: init.GetHttpVersion(), useDefaultHeaders: init.useDefaultHeaders); } #endregion diff --git a/Lampac/Controllers/ApiController.cs b/Lampac/Controllers/ApiController.cs index 1f27364..0cd9ac2 100644 --- a/Lampac/Controllers/ApiController.cs +++ b/Lampac/Controllers/ApiController.cs @@ -1,5 +1,4 @@ using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json; @@ -19,7 +18,9 @@ namespace Lampac.Controllers [HttpGet] [AllowAnonymous] [Route("/version")] - public ActionResult Version() => Content($"{appversion}.{minorversion}"); + public ActionResult Version() => string.IsNullOrEmpty(versionTag) + ? Content($"{appversion}.{minorversion}") + : Content($"{appversion}.{minorversion}-{versionTag}"); [HttpGet] [AllowAnonymous] diff --git a/Lampac/Engine/NativeWebSocket.cs b/Lampac/Engine/NativeWebSocket.cs index 5e323ab..5bdc9a7 100644 --- a/Lampac/Engine/NativeWebSocket.cs +++ b/Lampac/Engine/NativeWebSocket.cs @@ -317,14 +317,18 @@ namespace Lampac.Engine if (name == "devices") { - var evc = event_clients.Where(i => i.Value == uid).ToArray(); - + var uidClients = event_clients + .Where(i => i.Value == uid) + .ToDictionary(); + var devices = _connections .Where(i => i.Value.ConnectionId != connection.ConnectionId) - .Where(i => i.Value.Ip == connection.Ip || event_clients.Values.Contains(uid)) + .Where(i => + (!AppInit.conf.accsdb.enable && i.Value.Ip == connection.Ip) + || uidClients.Keys.Contains(i.Key)) .Select(i => new { - uid = event_clients.TryGetValue(i.Value.ConnectionId, out var _uid) ? _uid : null, - i.Value.ConnectionId, + uid = uidClients.TryGetValue(i.Value.ConnectionId, out var targetUid) ? targetUid : null, + i.Value.ConnectionId, i.Value.RequestInfo.UserAgent }) .ToArray(); @@ -517,7 +521,7 @@ namespace Lampac.Engine try { var now = DateTime.UtcNow; - var cutoff = now.AddSeconds(-125); // ping 40 + var cutoff = now.AddSeconds(-125); foreach (var connection in _connections) { diff --git a/Lampac/Program.cs b/Lampac/Program.cs index 2cde236..c134991 100644 --- a/Lampac/Program.cs +++ b/Lampac/Program.cs @@ -192,11 +192,17 @@ namespace Lampac #endregion #region vers.txt + Directory.CreateDirectory("data"); + if (!File.Exists("data/vers.txt")) File.WriteAllText("data/vers.txt", BaseController.appversion); if (!File.Exists("data/vers-minor.txt")) - File.WriteAllText("data/vers-minor.txt", "1"); + File.WriteAllText("data/vers-minor.txt", BaseController.minorversion); + + if (!string.IsNullOrEmpty(BaseController.versionTag) && !File.Exists("data/vers-tag.txt")) + File.WriteAllText("data/vers-tag.txt", BaseController.versionTag); + #endregion #region SQL @@ -421,6 +427,7 @@ namespace Lampac if (AppInit.modules?.FirstOrDefault(i => i.dll == "DLNA.dll" && i.enable) != null) TrackersCron.Run(); + Directory.CreateDirectory("wwwroot"); LampaCron.Run(); appReload = new AppReload(); diff --git a/Lampac/Startup.cs b/Lampac/Startup.cs index 48427e9..a311adf 100644 --- a/Lampac/Startup.cs +++ b/Lampac/Startup.cs @@ -639,7 +639,7 @@ namespace Lampac AppInit.conf.BaseModule.EnableControllers.Length == 0) return; - WebLogEnableController = AppInit.conf.BaseModule.EnableControllers.Contains("WebLogController.cs"); + WebLogEnableController = AppInit.conf.BaseModule.EnableControllers.Contains("WebLog"); var syntaxTree = new List(); diff --git a/Online/Controllers/Anime/AnimeLib.cs b/Online/Controllers/Anime/AnimeLib.cs index a443d44..334548d 100644 --- a/Online/Controllers/Anime/AnimeLib.cs +++ b/Online/Controllers/Anime/AnimeLib.cs @@ -364,7 +364,7 @@ namespace Online.Controllers ); var result = await Http.Post("https://api.cdnlibs.org/api/auth/oauth/token", content, - httpversion: init.httpversion, timeoutSeconds: init.httptimeout, headers: headers, useDefaultHeaders: false + httpversion: init.GetHttpVersion(), timeoutSeconds: init.GetHttpTimeout(), headers: headers, useDefaultHeaders: false ); if (result == null) diff --git a/Online/Controllers/Filmix.cs b/Online/Controllers/Filmix.cs index a4fdc2a..daf7662 100644 --- a/Online/Controllers/Filmix.cs +++ b/Online/Controllers/Filmix.cs @@ -27,7 +27,7 @@ namespace Online.Controllers async public Task Pro() { string uri = $"{init.corsHost()}/api/v2/token_request?user_dev_apk=2.0.1&user_dev_id=&user_dev_name=Xiaomi&user_dev_os=11&user_dev_vendor=Xiaomi&user_dev_token="; - var token_request = await Http.Get(uri, httpversion: init.httpversion, proxy: proxy, useDefaultHeaders: false); + var token_request = await Http.Get(uri, httpversion: init.GetHttpVersion(), timeoutSeconds: init.GetHttpTimeout(), proxy: proxy, useDefaultHeaders: false); if (token_request == null) return ContentTo($"нет доступа к {init.corsHost()}"); diff --git a/Online/Controllers/FilmixTV.cs b/Online/Controllers/FilmixTV.cs index e07e8ba..0555b6b 100644 --- a/Online/Controllers/FilmixTV.cs +++ b/Online/Controllers/FilmixTV.cs @@ -122,7 +122,7 @@ namespace Online.Controllers else { var rtk = await Http.Get($"{init.corsHost()}/api-fx/request-token", - proxy: proxy, httpversion: init.httpversion, timeoutSeconds: 30 + proxy: proxy, httpversion: init.GetHttpVersion(), timeoutSeconds: 30 ); if (rtk == null || !rtk.ContainsKey("token")) @@ -146,14 +146,14 @@ namespace Online.Controllers string refreshToken = Regex.Match(F.ReadAllText(authFile), "\"refreshToken\": ?\"([^\"]+)\"").Groups[1].Value; root_auth = await Http.Get($"{init.corsHost()}/api-fx/refresh?refreshToken={HttpUtility.UrlEncode(refreshToken)}", - proxy: proxy, headers: HeadersModel.Init("hash", init.hash_apitv), httpversion: init.httpversion, timeoutSeconds: 30 + proxy: proxy, headers: HeadersModel.Init("hash", init.hash_apitv), httpversion: init.GetHttpVersion(), timeoutSeconds: 30 ); } else { var data = new System.Net.Http.StringContent($"{{\"user_name\":\"{init.user_apitv}\",\"user_passw\":\"{init.passwd_apitv}\",\"session\":true}}", Encoding.UTF8, "application/json"); root_auth = await Http.Post($"{init.corsHost()}/api-fx/auth", data, - proxy: proxy, headers: HeadersModel.Init("hash", init.hash_apitv), httpversion: init.httpversion, timeoutSeconds: 30 + proxy: proxy, headers: HeadersModel.Init("hash", init.hash_apitv), httpversion: init.GetHttpVersion(), timeoutSeconds: 30 ); } diff --git a/Online/Controllers/GetsTV.cs b/Online/Controllers/GetsTV.cs index 80142c8..c77d975 100644 --- a/Online/Controllers/GetsTV.cs +++ b/Online/Controllers/GetsTV.cs @@ -33,7 +33,7 @@ namespace Online.Controllers else { var postdata = new System.Net.Http.StringContent($"{{\"email\":\"{login}\",\"password\":\"{pass}\",\"fingerprint\":\"{CrypTo.md5(DateTime.Now.ToString())}\",\"device\":{{}}}}", Encoding.UTF8, "application/json"); - var result = await Http.Post($"{init.corsHost()}/api/login", postdata, httpversion: init.httpversion, proxy: proxy, headers: httpHeaders(init)); + var result = await Http.Post($"{init.corsHost()}/api/login", postdata, httpversion: init.GetHttpVersion(), proxy: proxy, headers: httpHeaders(init)); if (result == null) return ContentTo("Ошибка авторизации ;("); diff --git a/Online/Controllers/IptvOnline.cs b/Online/Controllers/IptvOnline.cs index 836f3d9..af14439 100644 --- a/Online/Controllers/IptvOnline.cs +++ b/Online/Controllers/IptvOnline.cs @@ -168,7 +168,7 @@ namespace Online.Controllers string uri = $"{init.host}/v1/api/media/{(serial == 1 ? "serials" : "movies")}"; var data = new System.Net.Http.StringContent(JsonConvert.SerializeObject(new { search }), Encoding.UTF8, "application/json"); - var video = await Http.Get(uri, body: data, timeoutSeconds: init.httptimeout, proxy: proxy, useDefaultHeaders: false, headers: httpHeaders(init, HeadersModel.Init( + var video = await Http.Get(uri, body: data, timeoutSeconds: init.GetHttpTimeout(), httpversion: init.GetHttpVersion(), proxy: proxy, useDefaultHeaders: false, headers: httpHeaders(init, HeadersModel.Init( ("X-API-AUTH", codeauth), ("X-API-ID", init.token.Split(":")[0]) ))); diff --git a/Online/Controllers/KinoPub.cs b/Online/Controllers/KinoPub.cs index 2c208b6..6e89635 100644 --- a/Online/Controllers/KinoPub.cs +++ b/Online/Controllers/KinoPub.cs @@ -30,7 +30,7 @@ namespace Online.Controllers if (string.IsNullOrWhiteSpace(code)) { string uri = $"{init.corsHost()}/oauth2/device?grant_type=device_code&client_id=xbmc&client_secret=cgg3gtifu46urtfp2zp1nqtba0k2ezxh"; - var token_request = await Http.Post(uri, "", httpversion: init.httpversion, proxy: proxy, headers: httpHeaders(init)); + var token_request = await Http.Post(uri, "", httpversion: init.GetHttpVersion(), proxy: proxy, headers: httpHeaders(init)); if (token_request == null) return ContentTo($"нет доступа к {init.corsHost()}"); @@ -46,14 +46,14 @@ namespace Online.Controllers else { string uri = $"{init.corsHost()}/oauth2/device?grant_type=device_token&client_id=xbmc&client_secret=cgg3gtifu46urtfp2zp1nqtba0k2ezxh&code={code}"; - var device_token = await Http.Post(uri, "", httpversion: init.httpversion, proxy: proxy, headers: httpHeaders(init)); + var device_token = await Http.Post(uri, "", httpversion: init.GetHttpVersion(), proxy: proxy, headers: httpHeaders(init)); if (device_token == null || string.IsNullOrWhiteSpace(device_token.Value("access_token"))) return LocalRedirect("/lite/kinopubpro"); if (!string.IsNullOrEmpty(name)) { uri = $"{init.corsHost()}/v1/device/notify?access_token={device_token.Value("access_token")}"; - await Http.Post(uri, $"&title={name}", httpversion: init.httpversion, proxy: proxy, headers: httpHeaders(init)); + await Http.Post(uri, $"&title={name}", httpversion: init.GetHttpVersion(), proxy: proxy, headers: httpHeaders(init)); } return ContentTo("Добавьте в init.conf

\"KinoPub\": {
  \"enable\": true,
  \"token\": \"" + device_token.Value("access_token") + "\"
}"); diff --git a/Online/Controllers/VideoDB.cs b/Online/Controllers/VideoDB.cs index 67bcbd9..ade0a60 100644 --- a/Online/Controllers/VideoDB.cs +++ b/Online/Controllers/VideoDB.cs @@ -119,7 +119,7 @@ namespace Online.Controllers } else if (init.priorityBrowser == "http") { - location = await Http.GetLocation(link, httpversion: init.httpversion, timeoutSeconds: init.httptimeout, proxy: proxy, headers: headers); + location = await Http.GetLocation(link, httpversion: init.GetHttpVersion(), timeoutSeconds: init.GetHttpTimeout(), proxy: proxy, headers: headers); } else { diff --git a/SISI/Controllers/Ebalovo/ViewController.cs b/SISI/Controllers/Ebalovo/ViewController.cs index b4a6e46..5d5f43c 100644 --- a/SISI/Controllers/Ebalovo/ViewController.cs +++ b/SISI/Controllers/Ebalovo/ViewController.cs @@ -41,7 +41,7 @@ namespace SISI.Controllers.Ebalovo return res.currentUrl; } - return await Http.GetLocation(init.cors(location), timeoutSeconds: init.httptimeout, httpversion: init.httpversion, proxy: proxy, headers: httpHeaders(init)); + return await Http.GetLocation(init.cors(location), timeoutSeconds: init.GetHttpTimeout(), httpversion: init.GetHttpVersion(), proxy: proxy, headers: httpHeaders(init)); } ); diff --git a/SISI/Controllers/NextHUB/ListController.cs b/SISI/Controllers/NextHUB/ListController.cs index 6269502..e671212 100644 --- a/SISI/Controllers/NextHUB/ListController.cs +++ b/SISI/Controllers/NextHUB/ListController.cs @@ -613,13 +613,13 @@ namespace SISI.Controllers.NextHUB return rch?.enable == true ? await rch.Post(url.Replace("{page}", pg.ToString()), data, httpHeaders(init)) - : await Http.Post(url.Replace("{page}", pg.ToString()), data, encoding: encodingResponse, headers: httpHeaders(init), proxy: proxy, timeoutSeconds: init.timeout, httpversion: init.httpversion); + : await Http.Post(url.Replace("{page}", pg.ToString()), data, encoding: encodingResponse, headers: httpHeaders(init), proxy: proxy, timeoutSeconds: init.GetHttpTimeout(), httpversion: init.GetHttpVersion()); } else { return rch?.enable == true ? await rch.Get(url.Replace("{page}", pg.ToString()), httpHeaders(init)) - : init.priorityBrowser == "http" ? await Http.Get(url.Replace("{page}", pg.ToString()), encoding: encodingResponse, headers: httpHeaders(init), proxy: proxy, timeoutSeconds: init.timeout, httpversion: init.httpversion) + : init.priorityBrowser == "http" ? await Http.Get(url.Replace("{page}", pg.ToString()), encoding: encodingResponse, headers: httpHeaders(init), proxy: proxy, timeoutSeconds: init.timeout, httpversion: init.GetHttpVersion()) : init.list.viewsource ? await PlaywrightBrowser.Get(init, url.Replace("{page}", pg.ToString()), httpHeaders(init), proxy_data, cookies: init.cookies) : await ContentAsync(init, url.Replace("{page}", pg.ToString()), httpHeaders(init), proxy_data, search, sort, cat, model, pg); } diff --git a/SISI/Controllers/Porntrex/ViewController.cs b/SISI/Controllers/Porntrex/ViewController.cs index 014c352..2de8105 100644 --- a/SISI/Controllers/Porntrex/ViewController.cs +++ b/SISI/Controllers/Porntrex/ViewController.cs @@ -89,7 +89,7 @@ namespace SISI.Controllers.Porntrex } else { - location = await Http.GetLocation(init.cors(link), timeoutSeconds: init.httptimeout, httpversion: init.httpversion, proxy: proxy, headers: headers); + location = await Http.GetLocation(init.cors(link), timeoutSeconds: init.GetHttpTimeout(), httpversion: init.GetHttpVersion(), proxy: proxy, headers: headers); } if (string.IsNullOrEmpty(location) || link == location) diff --git a/SISI/Controllers/XvideosRED/ListController.cs b/SISI/Controllers/XvideosRED/ListController.cs index 719923e..bb9a94a 100644 --- a/SISI/Controllers/XvideosRED/ListController.cs +++ b/SISI/Controllers/XvideosRED/ListController.cs @@ -45,7 +45,7 @@ namespace SISI.Controllers.XvideosRED } #endregion - string html = await Http.Get(init.cors(url), cookie: init.cookie, timeoutSeconds: init.httptimeout, proxy: proxy, headers: httpHeaders(init)); + string html = await Http.Get(init.cors(url), cookie: init.cookie, timeoutSeconds: init.GetHttpVersion(), httpversion: init.GetHttpVersion(), proxy: proxy, headers: httpHeaders(init)); if (html == null) return OnError("html", refresh_proxy: string.IsNullOrEmpty(search)); diff --git a/SISI/Controllers/XvideosRED/ViewController.cs b/SISI/Controllers/XvideosRED/ViewController.cs index 339530f..b666597 100644 --- a/SISI/Controllers/XvideosRED/ViewController.cs +++ b/SISI/Controllers/XvideosRED/ViewController.cs @@ -21,7 +21,7 @@ namespace SISI.Controllers.XvideosRED if (url == null) return OnError("stream_links"); - string html = await Http.Get(url, cookie: init.cookie, timeoutSeconds: init.httptimeout, proxy: proxy, headers: httpHeaders(init)); + string html = await Http.Get(url, cookie: init.cookie, timeoutSeconds: init.GetHttpVersion(), httpversion: init.GetHttpVersion(), proxy: proxy, headers: httpHeaders(init)); if (html == null) return OnError("stream_links"); diff --git a/Shared/AppInit.cs b/Shared/AppInit.cs index e1ddb25..f05efd5 100644 --- a/Shared/AppInit.cs +++ b/Shared/AppInit.cs @@ -464,7 +464,7 @@ namespace Shared public SyncUserConf sync_user = new SyncUserConf() { enable = true, version = 2 }; - public StorageConf storage = new StorageConf() { enable = true, max_size = 7_000000, brotli = false, md5name = true }; + public StorageConf storage = new StorageConf() { enable = true, max_size = 7_000000, brotli = false, }; public GCConf GC { get; set; } = new GCConf() { diff --git a/Shared/BaseController.cs b/Shared/BaseController.cs index eccba47..72a2a9b 100644 --- a/Shared/BaseController.cs +++ b/Shared/BaseController.cs @@ -24,10 +24,12 @@ namespace Shared { public class BaseController : Controller { - public static string appversion => "154"; - public static string minorversion => "3"; + public static string versionTag => "ce"; + public static string appversion => "155"; + + public static string minorversion => "1"; protected static readonly ConcurrentDictionary _semaphoreLocks = new(); diff --git a/Shared/Engine/HTTP/HttpHydra.cs b/Shared/Engine/HTTP/HttpHydra.cs index 3976281..806d973 100644 --- a/Shared/Engine/HTTP/HttpHydra.cs +++ b/Shared/Engine/HTTP/HttpHydra.cs @@ -27,7 +27,7 @@ namespace Shared.Engine return IsRchEnable(safety) ? rch.Get(init.cors(url), headers, IgnoreDeserializeObject, useDefaultHeaders) - : Http.Get(init.cors(url), timeoutSeconds: init.httptimeout, httpversion: init.httpversion, proxy: proxy, headers: headers, useDefaultHeaders: useDefaultHeaders, statusCodeOK: statusCodeOK); + : Http.Get(init.cors(url), timeoutSeconds: init.GetHttpTimeout(), httpversion: init.GetHttpVersion(), proxy: proxy, headers: headers, useDefaultHeaders: useDefaultHeaders, statusCodeOK: statusCodeOK); } public Task Get(string url, List addheaders = null, List newheaders = null, bool useDefaultHeaders = true, bool statusCodeOK = true, Encoding encoding = default, bool safety = false) @@ -36,7 +36,7 @@ namespace Shared.Engine return IsRchEnable(safety) ? rch.Get(init.cors(url), headers, useDefaultHeaders) - : Http.Get(init.cors(url), encoding, timeoutSeconds: init.httptimeout, httpversion: init.httpversion, proxy: proxy, headers: headers, useDefaultHeaders: useDefaultHeaders, statusCodeOK: statusCodeOK); + : Http.Get(init.cors(url), encoding, timeoutSeconds: init.GetHttpTimeout(), httpversion: init.GetHttpVersion(), proxy: proxy, headers: headers, useDefaultHeaders: useDefaultHeaders, statusCodeOK: statusCodeOK); } #endregion @@ -47,7 +47,7 @@ namespace Shared.Engine return IsRchEnable(safety) ? rch.GetSpan(spanAction, init.cors(url), headers, useDefaultHeaders) - : Http.GetSpan(spanAction, init.cors(url), timeoutSeconds: init.httptimeout, httpversion: init.httpversion, proxy: proxy, headers: headers, useDefaultHeaders: useDefaultHeaders, statusCodeOK: statusCodeOK); + : Http.GetSpan(spanAction, init.cors(url), timeoutSeconds: init.GetHttpTimeout(), httpversion: init.GetHttpVersion(), proxy: proxy, headers: headers, useDefaultHeaders: useDefaultHeaders, statusCodeOK: statusCodeOK); } #endregion @@ -58,7 +58,7 @@ namespace Shared.Engine return IsRchEnable(safety) ? rch.Post(init.cors(url), data, headers, IgnoreDeserializeObject, useDefaultHeaders) - : Http.Post(init.cors(url), data, encoding: encoding, timeoutSeconds: init.httptimeout, httpversion: init.httpversion, proxy: proxy, headers: headers, useDefaultHeaders: useDefaultHeaders, statusCodeOK: statusCodeOK); + : Http.Post(init.cors(url), data, encoding: encoding, timeoutSeconds: init.GetHttpTimeout(), httpversion: init.GetHttpVersion(), proxy: proxy, headers: headers, useDefaultHeaders: useDefaultHeaders, statusCodeOK: statusCodeOK); } public Task Post(string url, string data, List addheaders = null, List newheaders = null, bool useDefaultHeaders = true, bool statusCodeOK = true, Encoding encoding = default, bool safety = false) @@ -67,7 +67,7 @@ namespace Shared.Engine return IsRchEnable(safety) ? rch.Post(init.cors(url), data, headers, useDefaultHeaders) - : Http.Post(init.cors(url), data, encoding: encoding, timeoutSeconds: init.httptimeout, httpversion: init.httpversion, proxy: proxy, headers: headers, useDefaultHeaders: useDefaultHeaders, statusCodeOK: statusCodeOK); + : Http.Post(init.cors(url), data, encoding: encoding, timeoutSeconds: init.GetHttpTimeout(), httpversion: init.GetHttpVersion(), proxy: proxy, headers: headers, useDefaultHeaders: useDefaultHeaders, statusCodeOK: statusCodeOK); } #endregion @@ -78,7 +78,7 @@ namespace Shared.Engine return IsRchEnable(safety) ? rch.PostSpan(spanAction, init.cors(url), data, headers, useDefaultHeaders) - : Http.PostSpan(spanAction, init.cors(url), data, encoding: encoding, timeoutSeconds: init.httptimeout, httpversion: init.httpversion, proxy: proxy, headers: headers, useDefaultHeaders: useDefaultHeaders, statusCodeOK: statusCodeOK); + : Http.PostSpan(spanAction, init.cors(url), data, encoding: encoding, timeoutSeconds: init.GetHttpTimeout(), httpversion: init.GetHttpVersion(), proxy: proxy, headers: headers, useDefaultHeaders: useDefaultHeaders, statusCodeOK: statusCodeOK); } #endregion diff --git a/Shared/Engine/StorageManager.cs b/Shared/Engine/StorageManager.cs new file mode 100644 index 0000000..b19f549 --- /dev/null +++ b/Shared/Engine/StorageManager.cs @@ -0,0 +1,161 @@ +using System.Text; +using Shared.Models; + +namespace Shared.Engine +{ + public static class StorageManager + { + private const string TempDirectoryName = "temp"; + + private static readonly string BaseStoragePath = + Path.GetFullPath("database/storage"); + + private static readonly string BaseTempStoragePath = $"{BaseStoragePath}/{TempDirectoryName}"; + + static StorageManager() + { + Directory.CreateDirectory(BaseStoragePath); + Directory.CreateDirectory(BaseTempStoragePath); + } + + public static string? GetFilePath( + string pathType, + bool createDirectory = false, + RequestModel? requestInfo = null, + string? profileUid = null) + { + return GetFilePath(pathType, createDirectory, requestInfo?.user_uid, profileUid); + } + + public static string? GetFilePath( + string pathType, + bool createDirectory = false, + string? userUid = null, + string? profileUid = null) + { + if (string.IsNullOrWhiteSpace(userUid)) + { + return null; + } + + string cleanedUserId = CleanIdentifier(userUid); + + if (string.IsNullOrEmpty(cleanedUserId)) + { + return null; + } + + string cleanedProfileUid = CleanIdentifier(profileUid ?? string.Empty); + string hashInput = cleanedUserId + cleanedProfileUid; + string md5Key = CrypTo.md5(hashInput); + + string safePathType = CleanPathType(pathType); + if (string.IsNullOrEmpty(safePathType)) + { + return null; + } + + string fullPath; + try + { + if (safePathType == TempDirectoryName) + { + fullPath = $"{BaseStoragePath}/{TempDirectoryName}/{md5Key}"; + } + else + { + string level1 = md5Key[..2]; + string level2 = md5Key[2..]; + + string directoryPath = $"{BaseStoragePath}/{safePathType}/{level1}"; + fullPath = $"{directoryPath}/{level2}"; + } + } + catch + { + return null; + } + + if (!fullPath.StartsWith(BaseStoragePath + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) + && !string.Equals(fullPath, BaseStoragePath, StringComparison.OrdinalIgnoreCase)) + { + return null; + } + + if (!createDirectory || safePathType == TempDirectoryName) + { + return fullPath; + } + + try + { + string directoryPath = Path.GetDirectoryName(fullPath); + if (!string.IsNullOrEmpty(directoryPath)) + { + Directory.CreateDirectory(directoryPath); + } + } + catch + { + // ignore all exceptions + return null; + } + + return fullPath; + } + + private static string CleanIdentifier(string? input) + { + if (string.IsNullOrWhiteSpace(input)) + return ""; + + var sb = new StringBuilder(input.Length); + + foreach (var c in input.Where(c => char.IsLetterOrDigit(c) + || c is '-' or '_' or '@' or '.' or '+' or '=')) + { + sb.Append(c); + } + + string cleaned = sb.ToString(); + + if (cleaned.Length is 0 or > 160 + || cleaned.StartsWith(".") + || cleaned.EndsWith(".") + || cleaned.Contains("..") + || cleaned.Contains("//") + || cleaned.Contains(@"\") + || cleaned.Contains(":")) + { + return ""; + } + + return cleaned; + } + private static string CleanPathType(string? input) + { + if (string.IsNullOrWhiteSpace(input)) + return ""; + + var sb = new StringBuilder(); + + foreach (var c in input.ToLowerInvariant().Where(c => char.IsLetterOrDigit(c) + || c is '-' or '_')) + { + sb.Append(c); + } + + string cleaned = sb.ToString(); + + if (cleaned.Length is 0 or > 40 + || cleaned.Contains("..") + || cleaned.StartsWith("-") + || cleaned.EndsWith("-")) + { + return ""; + } + + return cleaned; + } + } +} \ No newline at end of file diff --git a/Shared/Models/AppConf/StorageConf.cs b/Shared/Models/AppConf/StorageConf.cs index b0add91..44fc809 100644 --- a/Shared/Models/AppConf/StorageConf.cs +++ b/Shared/Models/AppConf/StorageConf.cs @@ -7,7 +7,5 @@ public long max_size { get; set; } public bool brotli { get; set; } - - public bool md5name { get; set; } } } diff --git a/Shared/Models/Base/BaseSettings.cs b/Shared/Models/Base/BaseSettings.cs index c5c5ede..9e2f33c 100644 --- a/Shared/Models/Base/BaseSettings.cs +++ b/Shared/Models/Base/BaseSettings.cs @@ -138,10 +138,13 @@ namespace Shared.Models.Base public string priorityBrowser { get; set; } - public int httptimeout { get; set; } = 8; - - public int httpversion { get; set; } = 1; - + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + public int? httptimeout { get; set; } + public int GetHttpTimeout() => httpversion ?? 8; + + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + public int? httpversion { get; set; } + public int GetHttpVersion() => httpversion ?? 1; #region proxy public bool useproxy { get; set; }