mirror of https://gitee.com/apiumc/Gateway.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1357 lines
56 KiB
C#
1357 lines
56 KiB
C#
using System.ComponentModel;
|
|
using System.Net;
|
|
using System.Globalization;
|
|
using System.Reflection.Metadata;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
|
|
namespace UMC.ITME
|
|
{
|
|
|
|
public class SiteConfig
|
|
{
|
|
class UMCUri : Uri
|
|
{
|
|
public UMCUri([StringSyntax("Uri")] string uriString) : base(uriString)
|
|
{
|
|
isPort = uriString.IndexOf(":", 7) > -1;
|
|
}
|
|
bool isPort;
|
|
public string UMCAuthority
|
|
{
|
|
get
|
|
{
|
|
if (isPort)
|
|
{
|
|
return $"{this.Host}:{this.Port}";
|
|
|
|
}
|
|
else
|
|
{
|
|
return this.Authority;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
public enum HostReplaceModel
|
|
{
|
|
Replace = 1,
|
|
// Remove = 2,
|
|
Input = 4,
|
|
CDN = 8,
|
|
Script = 16
|
|
}
|
|
public class ReplaceSetting
|
|
{
|
|
public HostReplaceModel Model
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
HashSet<HostConvert> _Domains = new HashSet<HostConvert>(new EqualityComparer());
|
|
public HashSet<HostConvert> Domains
|
|
{
|
|
get
|
|
{
|
|
return _Domains;
|
|
}
|
|
}
|
|
}
|
|
public class LogSetting
|
|
{
|
|
public String[] Cookies
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
public String[] Headers
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
public string[] ResHeaders
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
}
|
|
public class TestUrl
|
|
{
|
|
public String[] Users
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
public String[] Auths
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
public string Url
|
|
{
|
|
|
|
get;
|
|
set;
|
|
}
|
|
}
|
|
public class HostConvert
|
|
{
|
|
public byte[][] Hosts = new byte[4][];
|
|
}
|
|
class EqualityComparer : IEqualityComparer<HostConvert>
|
|
{
|
|
|
|
public bool Equals(HostConvert x, HostConvert y)
|
|
{
|
|
return x.Hosts[0].Length == y.Hosts[0].Length && Utility.FindIndex(x.Hosts[0], 0, x.Hosts[0].Length, y.Hosts[0]) == 0;// Utility.IntParse(System.Security.Cryptography.MD5.HashData(x.Main)) == Utility.IntParse(System.Security.Cryptography.MD5.HashData(y.Main));
|
|
|
|
}
|
|
|
|
public int GetHashCode(HostConvert obj)
|
|
{
|
|
if (obj.Hosts[0].Length >= 4)
|
|
{
|
|
int v = BitConverter.ToInt32(obj.Hosts[0]);
|
|
for (var i = 4; i < obj.Hosts[0].Length; i++)
|
|
{
|
|
v = v ^ obj.Hosts[0][i];
|
|
}
|
|
return v;
|
|
}
|
|
else
|
|
{
|
|
var b = new byte[4];
|
|
Array.Copy(obj.Hosts[0], 0, b, 4 - obj.Hosts[0].Length, obj.Hosts[0].Length);
|
|
return BitConverter.ToInt32(b);
|
|
}
|
|
}
|
|
}
|
|
public class KeyValue
|
|
{
|
|
|
|
public string Key
|
|
{
|
|
|
|
get;
|
|
set;
|
|
}
|
|
public string Value
|
|
{
|
|
|
|
get;
|
|
set;
|
|
}
|
|
public bool IsDel
|
|
{
|
|
get; set;
|
|
}
|
|
}
|
|
|
|
public int WeightTotal
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
public int[] Weights
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
public string Caption
|
|
{
|
|
get; private set;
|
|
}
|
|
public bool IsFile
|
|
{
|
|
|
|
get; private set;
|
|
}
|
|
|
|
public SiteConfig() { }
|
|
public SiteConfig(Entities.Site site)
|
|
{
|
|
this.Caption = site.Caption;
|
|
|
|
if (String.IsNullOrEmpty(site.Home) == false)
|
|
{
|
|
this.Home = site.Home;
|
|
}
|
|
|
|
this.Root = site.Root;
|
|
this.Site = site;
|
|
this.PrefixHost = new Dictionary<string, string>();
|
|
|
|
var dom = site.Domain.Split(',', '\n');
|
|
List<string> domains = new List<string>();
|
|
var ls = new List<int>();
|
|
var total = 0;
|
|
var test = new Dictionary<String, TestUrl>();
|
|
for (var i = 0; i < dom.Length; i++)
|
|
{
|
|
var v = dom[i].Trim();
|
|
if (String.IsNullOrEmpty(v) == false && v.StartsWith("#") == false)
|
|
{
|
|
var valueIndex = v.IndexOf('~');
|
|
if (valueIndex > 0)
|
|
{
|
|
var KeepAlive = v.Substring(valueIndex + 1).Trim();
|
|
v = v.Substring(0, valueIndex).Trim();
|
|
|
|
var tIndex = v.LastIndexOf("/");
|
|
try
|
|
{
|
|
var kUrl = new Uri(tIndex > 8 ? v.Substring(0, tIndex) : v);
|
|
switch (KeepAlive)
|
|
{
|
|
case "ip4":
|
|
Net.NetProxy.DNS(kUrl.Host, System.Net.Sockets.AddressFamily.InterNetwork);
|
|
break;
|
|
case "ip6":
|
|
Net.NetProxy.DNS(kUrl.Host, System.Net.Sockets.AddressFamily.InterNetworkV6);
|
|
break;
|
|
default:
|
|
Net.NetProxy.KeepAlives(kUrl, Utility.IntParse(KeepAlive, 60));
|
|
break;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
if (v.StartsWith("dns://"))
|
|
{
|
|
var ds = v.Substring(6).Trim('/').Split('/');
|
|
switch (ds.Length)
|
|
{
|
|
case 1:
|
|
if (System.Text.RegularExpressions.Regex.IsMatch(ds[0], "^[a-z0-9]{1,61}\\.[a-z]{2,6}$"))
|
|
{
|
|
Net.NetProxy.HttpDNS(ds[0]);
|
|
}
|
|
break;
|
|
case 2:
|
|
if (IPAddress.TryParse(ds[1], out var address))
|
|
{
|
|
Net.NetProxy.DNS(ds[0], address);
|
|
}
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
else if (v.StartsWith("http://") || v.StartsWith("https://") || v.StartsWith("file://") || v.StartsWith("unix://"))
|
|
{
|
|
if (v.EndsWith("]"))
|
|
{
|
|
var tUrl = v;
|
|
|
|
var vin = v.LastIndexOf("[");
|
|
if (vin > -1)
|
|
{
|
|
ls.Add(UMC.Data.Utility.IntParse(v.Substring(vin + 1).Trim(']', '[').Trim(), 1));
|
|
|
|
total += ls[ls.Count - 1];
|
|
tUrl = v.Substring(0, vin).TrimEnd(']', ' ').Trim();
|
|
}
|
|
else
|
|
{
|
|
total++;
|
|
ls.Add(1);
|
|
}
|
|
|
|
var sIndex = tUrl.IndexOf('/', 8);
|
|
if (sIndex > 0)
|
|
{
|
|
tUrl = tUrl.Substring(0, sIndex);
|
|
}
|
|
domains.Add(tUrl);
|
|
|
|
}
|
|
else
|
|
{
|
|
var tIndex = v.IndexOf('@');
|
|
var tUrl = v;
|
|
if (tIndex > 0)
|
|
{
|
|
tUrl = v.Substring(0, tIndex);
|
|
var uvs = v.Substring(tIndex + 1).Split(',', ' ');
|
|
var tUsers = new List<String>();
|
|
var tAuth = new List<String>();
|
|
foreach (var uv in uvs)
|
|
{
|
|
var uname = uv.Trim();
|
|
if (String.IsNullOrEmpty(uname) == false)
|
|
{
|
|
if (uname.IndexOf('/') == -1)
|
|
{
|
|
tUsers.Add(uname);
|
|
}
|
|
else
|
|
{
|
|
tAuth.Add(uname);
|
|
}
|
|
}
|
|
}
|
|
if (tUsers.Count > 0 || tAuth.Count > 0)
|
|
{
|
|
var sIndex = tUrl.IndexOf('/', 8);//, tIndex);
|
|
if (sIndex > 0)
|
|
{
|
|
tUrl = tUrl.Substring(0, sIndex);
|
|
}
|
|
|
|
test[tUrl.Trim()] = new TestUrl { Auths = tAuth.ToArray(), Users = tUsers.ToArray(), Url = tUrl };
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (tUrl.StartsWith("file://") == false)
|
|
{
|
|
var sIndex = tUrl.IndexOf('/', 8);
|
|
if (sIndex > 0)
|
|
{
|
|
tUrl = tUrl.Substring(0, sIndex);
|
|
}
|
|
}
|
|
domains.Add(tUrl);
|
|
total++;
|
|
ls.Add(1);
|
|
}
|
|
|
|
}
|
|
}
|
|
else if (v.Contains('.'))
|
|
{
|
|
this.PrefixHost[v.Replace('.', '-')] = v;
|
|
}
|
|
}
|
|
|
|
if (domains.Count > 0)
|
|
{
|
|
if (IsFile == false)
|
|
{
|
|
var url = domains.Last();
|
|
IsFile = url.StartsWith("file://", StringComparison.CurrentCultureIgnoreCase);
|
|
if (IsFile)
|
|
{
|
|
domains.Clear();
|
|
domains.Add(url);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.Domains = domains.ToArray();
|
|
this._test = test.Values.ToArray();
|
|
|
|
this.WeightTotal = total;
|
|
this.Weights = ls.ToArray();
|
|
|
|
this.LogoutPath = Config(site.LogoutPath);
|
|
this.AppendJSConf = Config(site.AppendJSConf);
|
|
this.RedirectPath = Config(site.RedirectPath);
|
|
this.ImagesConf = Config(site.ImagesConf);
|
|
this.ConfigAllowPath(site.AuthConf);
|
|
var subSite = new List<KeyValue>();
|
|
if (String.IsNullOrEmpty(site.SubSite) == false)
|
|
{
|
|
var v = UMC.Data.JSON.Deserialize(site.SubSite) as Hashtable;
|
|
if (v != null)
|
|
{
|
|
var pem = v.GetEnumerator();
|
|
while (pem.MoveNext())
|
|
{
|
|
var key = pem.Key as string;
|
|
if (key.EndsWith("*"))
|
|
{
|
|
subSite.Add(new KeyValue { Key = key.Substring(0, key.Length - 1), Value = pem.Value.ToString(), IsDel = true });
|
|
}
|
|
else
|
|
{
|
|
subSite.Add(new KeyValue { Key = key, Value = pem.Value.ToString() });
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
_subSite = subSite.ToArray();
|
|
InitStatic(site.StaticConf);
|
|
InitHeader(site.HeaderConf);
|
|
InitLogConf(site.LogConf);
|
|
|
|
InitCookie(site.OutputCookies);
|
|
|
|
InitHost(site.HostReConf);
|
|
|
|
}
|
|
public bool AllowAllPath
|
|
{
|
|
get; set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 默认ContentType类型
|
|
/// </summary>
|
|
public string ContentType
|
|
{
|
|
get; set;
|
|
}
|
|
public static bool CheckMime(Hashtable login)
|
|
{
|
|
var rawUrl = login["RawUrl"] as string;
|
|
if (String.IsNullOrEmpty(rawUrl))
|
|
{
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
var Method = login["Method"] as string;
|
|
if (String.IsNullOrEmpty(Method))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
switch (Method)
|
|
{
|
|
case "POST":
|
|
case "PUT":
|
|
var ContentType = login["ContentType"] as string;
|
|
if (String.IsNullOrEmpty(ContentType))
|
|
{
|
|
return false;
|
|
}
|
|
var value = login["Content"] as string;
|
|
if (String.IsNullOrEmpty(value))
|
|
{
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
var Finish = login["Finish"] as string;
|
|
if (String.IsNullOrEmpty(Finish))
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
void InitLogConf(String sConf)
|
|
{
|
|
|
|
this.LogConf = new LogSetting();
|
|
|
|
var cs = new List<String>();
|
|
var hs = new List<String>();
|
|
var rhs = new List<String>();
|
|
if (String.IsNullOrEmpty(sConf) == false)
|
|
{
|
|
foreach (var k in sConf.Split('\n', ','))
|
|
{
|
|
|
|
var v = k.Trim();
|
|
if (String.IsNullOrEmpty(v) == false && v.StartsWith("#") == false)
|
|
{
|
|
if (v.StartsWith(":"))
|
|
{
|
|
hs.Add(v.Substring(1));
|
|
}
|
|
else if (v.EndsWith(":"))
|
|
{
|
|
|
|
rhs.Add(v.Substring(0, v.Length - 1));
|
|
}
|
|
else
|
|
{
|
|
cs.Add(v);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
this.LogConf.Headers = hs.ToArray();
|
|
this.LogConf.ResHeaders = rhs.ToArray();
|
|
this.LogConf.Cookies = cs.ToArray();
|
|
}
|
|
void InitCookie(String sConf)
|
|
{
|
|
|
|
if (String.IsNullOrEmpty(sConf) == false)
|
|
{
|
|
|
|
foreach (var k in sConf.Split('\n', ','))
|
|
{
|
|
|
|
var v = k.Trim();
|
|
if (String.IsNullOrEmpty(v) == false && v.StartsWith("#") == false)
|
|
{
|
|
var nindex = -1;
|
|
for (int i = 0; i < v.Length; i++)
|
|
{
|
|
if (v[i] == ' ' || v[i] == '\t' || v[i] == ':')
|
|
{
|
|
nindex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (nindex > -1)
|
|
{
|
|
var vs = _OutputCookies;
|
|
var mv = v.Substring(nindex + 1).Trim();
|
|
var key = v.Substring(0, nindex).Trim();
|
|
var kIndex = mv.IndexOf(':');
|
|
if (kIndex > 0)
|
|
{
|
|
if (_SubsOutputCookies.TryGetValue(key, out vs) == false)
|
|
{
|
|
vs = new Dictionary<string, string>();
|
|
_SubsOutputCookies[key] = vs;
|
|
}
|
|
key = mv.Substring(0, kIndex);
|
|
mv = mv.Substring(kIndex + 1).Trim();
|
|
}
|
|
if (mv.StartsWith('/'))
|
|
{
|
|
vs[key] = mv;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
void InitHeader(String sConf)
|
|
{
|
|
|
|
if (String.IsNullOrEmpty(sConf) == false)
|
|
{
|
|
|
|
foreach (var k in sConf.Split('\n', ','))
|
|
{
|
|
|
|
var v = k.Trim();
|
|
if (String.IsNullOrEmpty(v) == false && v.StartsWith("#") == false)
|
|
{
|
|
|
|
var nindex = -1;
|
|
for (int i = 0; i < v.Length; i++)
|
|
{
|
|
if (v[i] == ' ' || v[i] == '\t' || v[i] == ':')
|
|
{
|
|
nindex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (nindex > -1)
|
|
{
|
|
var mv = v.Substring(nindex + 1).Trim();
|
|
var key = v.Substring(0, nindex).Trim();
|
|
if (String.IsNullOrEmpty(mv) == false && String.IsNullOrEmpty(key) == false)
|
|
{
|
|
switch (key.ToLower())
|
|
{
|
|
case "content-type":
|
|
this.ContentType = mv;
|
|
break;
|
|
default:
|
|
_HeaderConf[key] = mv;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void InitStatic(String sConf)
|
|
{
|
|
var stateValues = new List<PageConfig<int>>();
|
|
if (String.IsNullOrEmpty(sConf) == false)
|
|
{
|
|
foreach (var k in sConf.Split('\n', ','))
|
|
{
|
|
|
|
var v = k.Trim();
|
|
if (String.IsNullOrEmpty(v) == false && v.StartsWith("#") == false)
|
|
{
|
|
|
|
var nindex = -1;
|
|
for (int i = 0; i < v.Length; i++)
|
|
{
|
|
if (v[i] == ' ' || v[i] == '\t' || v[i] == ':')
|
|
{
|
|
nindex = i;
|
|
break;
|
|
}
|
|
}
|
|
var page = new PageConfig<int>() { StartPath = String.Empty, EndPath = String.Empty };
|
|
page.Value = -1;
|
|
var key = v;
|
|
if (nindex > -1)
|
|
{
|
|
var mv = v.Substring(nindex + 1).Trim().ToLower();
|
|
key = v.Substring(0, nindex).Trim();
|
|
var splitIndex = key.IndexOf('*');
|
|
switch (splitIndex)
|
|
{
|
|
case -1:
|
|
page.StartPath = key;
|
|
break;
|
|
case 0:
|
|
if (key.Length > 1)
|
|
{
|
|
page.EndPath = key.Substring(1);
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
default:
|
|
if (splitIndex == key.Length - 1)
|
|
{
|
|
page.StartPath = key.Substring(0, key.Length - 1);
|
|
}
|
|
else
|
|
{
|
|
page.StartPath = key.Substring(0, splitIndex);
|
|
page.EndPath = key.Substring(splitIndex + 1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
switch (mv)
|
|
{
|
|
case "a":
|
|
case "all":
|
|
page.Value = 0;
|
|
break;
|
|
case "u":
|
|
case "user":
|
|
page.Value = 2;
|
|
break;
|
|
case "one":
|
|
page.Value = 3;
|
|
break;
|
|
default:
|
|
page.Value = UMC.Data.Utility.IntParse(mv, -1);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
page.StartPath = key;
|
|
}
|
|
stateValues.Add(page);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
_StatusPage = stateValues.ToArray();
|
|
}
|
|
public HostConvert MainHost
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
public bool IsUnion
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public HostConvert SuffixHost
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
public Dictionary<String, String> PrefixHost
|
|
{
|
|
get; private set;
|
|
}
|
|
|
|
void InitHost(String sConf)
|
|
{
|
|
// this.PrefixHost = new Dictionary<string, string>();
|
|
var domain = UMC.ITME.WebServlet.MainDomain;
|
|
var union = UMC.ITME.WebServlet.DomainUnion;
|
|
if (this.Domains.Length > 0)
|
|
{
|
|
var url = this.Domains[0];
|
|
var hostConvert = this.MainHost = new HostConvert();
|
|
int sufx = 1;
|
|
if (url.Contains('*'))
|
|
{
|
|
IsUnion = true;
|
|
hostConvert.Hosts[0] = System.Text.ASCIIEncoding.UTF8.GetBytes($"-{this.Site.Root}{union}{domain}");
|
|
var l = new UMCUri(url.Replace("*.", ""));
|
|
hostConvert.Hosts[1] = System.Text.ASCIIEncoding.UTF8.GetBytes('.' + l.Host);
|
|
hostConvert.Hosts[2] = System.Text.ASCIIEncoding.UTF8.GetBytes('.' + l.UMCAuthority);
|
|
hostConvert.Hosts[3] = System.Text.ASCIIEncoding.UTF8.GetBytes(Uri.EscapeDataString('.' + l.UMCAuthority));
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
if (String.IsNullOrEmpty(this.Site.Host) == false && this.Site.Host != "*")
|
|
{
|
|
url = url.Replace(new UMCUri(url).Host, this.Site.Host);
|
|
}
|
|
hostConvert.Hosts[0] = System.Text.ASCIIEncoding.UTF8.GetBytes($"{this.Site.Root}{union}{domain}");
|
|
var l = new UMCUri(url);
|
|
sufx = l.Host.IndexOf('.');
|
|
hostConvert.Hosts[1] = System.Text.ASCIIEncoding.UTF8.GetBytes(l.Host);
|
|
hostConvert.Hosts[2] = System.Text.ASCIIEncoding.UTF8.GetBytes(l.UMCAuthority);
|
|
hostConvert.Hosts[3] = System.Text.ASCIIEncoding.UTF8.GetBytes(Uri.EscapeDataString(l.UMCAuthority));
|
|
|
|
|
|
}
|
|
var suffixHost = new HostConvert();
|
|
if (union == '-')
|
|
{
|
|
suffixHost.Hosts[0] = System.Text.ASCIIEncoding.UTF8.GetBytes(domain.Substring(domain.IndexOf('.') + 1));
|
|
}
|
|
else
|
|
{
|
|
suffixHost.Hosts[0] = System.Text.ASCIIEncoding.UTF8.GetBytes(domain);
|
|
}
|
|
if (this.IsFile == false)
|
|
{
|
|
suffixHost.Hosts[1] = this.MainHost.Hosts[1].AsSpan(sufx, this.MainHost.Hosts[1].Length - sufx).ToArray();// System.Text.ASCIIEncoding.UTF8.GetBytes(String.Format(".{0}{1}{2}", this.Site.Root, union, domain));
|
|
suffixHost.Hosts[2] = this.MainHost.Hosts[2].AsSpan(sufx, this.MainHost.Hosts[2].Length - sufx).ToArray();// System.Text.ASCIIEncoding.UTF8.GetBytes(String.Format(".{0}{1}{2}", this.Site.Root, union, domain));
|
|
suffixHost.Hosts[3] = this.MainHost.Hosts[3].AsSpan(sufx, this.MainHost.Hosts[3].Length - sufx).ToArray();// System.Text.ASCIIEncoding.UTF8.GetBytes(String.Format(".{0}{1}{2}", this.Site.Root, union, domain));
|
|
}
|
|
this.SuffixHost = suffixHost;
|
|
|
|
}
|
|
var hostPage = new HashSet<PageConfig<ReplaceSetting>>(new EqualityComparer<ReplaceSetting>());
|
|
// hostPage.TryGetValue
|
|
if (String.IsNullOrEmpty(sConf) == false)
|
|
{
|
|
foreach (var k in sConf.Split('\n'))
|
|
{
|
|
|
|
var v = k.Trim();
|
|
if (String.IsNullOrEmpty(v) == false && v.StartsWith("#") == false)
|
|
{
|
|
|
|
var nindex = -1;
|
|
for (int i = 0; i < v.Length; i++)
|
|
{
|
|
if (v[i] == ' ' || v[i] == '\t' || v[i] == ':')
|
|
{
|
|
nindex = i;
|
|
break;
|
|
}
|
|
}
|
|
var key = v;
|
|
if (nindex > -1)
|
|
{
|
|
var mv = v.Substring(nindex + 1).Split(',', ' ', '\t');
|
|
key = v.Substring(0, nindex).Trim();
|
|
|
|
var page = new PageConfig<ReplaceSetting>() { StartPath = String.Empty, EndPath = String.Empty };
|
|
|
|
var splitIndex = key.IndexOf('*');
|
|
switch (splitIndex)
|
|
{
|
|
case -1:
|
|
page.StartPath = key;
|
|
break;
|
|
case 0:
|
|
if (key.Length > 1)
|
|
{
|
|
page.EndPath = key.Substring(1);
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
default:
|
|
if (splitIndex == key.Length - 1)
|
|
{
|
|
page.StartPath = key.Substring(0, key.Length - 1);
|
|
}
|
|
else
|
|
{
|
|
page.StartPath = key.Substring(0, splitIndex);
|
|
page.EndPath = key.Substring(splitIndex + 1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (hostPage.TryGetValue(page, out var _page) == false)
|
|
{
|
|
page.Value = new ReplaceSetting() { Model = HostReplaceModel.Replace };
|
|
_page = page;
|
|
hostPage.Add(page);
|
|
|
|
}
|
|
ReplaceSetting replaceSetting = _page.Value;//[key];
|
|
HostReplaceModel hostReplace = replaceSetting.Model;
|
|
var list = replaceSetting.Domains;
|
|
|
|
foreach (var kv in mv)
|
|
{
|
|
var vk = kv.Trim();
|
|
if (String.IsNullOrEmpty(vk) == false)
|
|
{
|
|
|
|
switch (vk)
|
|
{
|
|
case ".":
|
|
if (this.IsUnion || union == '-')
|
|
{
|
|
|
|
var hostConvert = new HostConvert();
|
|
if (union == '-')
|
|
{
|
|
hostConvert.Hosts[0] = System.Text.ASCIIEncoding.UTF8.GetBytes(domain.Substring(domain.IndexOf('.') + 1));
|
|
}
|
|
else
|
|
{
|
|
hostConvert.Hosts[0] = System.Text.ASCIIEncoding.UTF8.GetBytes(domain);
|
|
}
|
|
hostConvert.Hosts[1] = this.MainHost.Hosts[1].AsSpan(1, this.MainHost.Hosts[1].Length - 1).ToArray();// System.Text.ASCIIEncoding.UTF8.GetBytes(String.Format(".{0}{1}{2}", this.Site.Root, union, domain));
|
|
hostConvert.Hosts[2] = this.MainHost.Hosts[2].AsSpan(1, this.MainHost.Hosts[2].Length - 1).ToArray();// System.Text.ASCIIEncoding.UTF8.GetBytes(String.Format(".{0}{1}{2}", this.Site.Root, union, domain));
|
|
hostConvert.Hosts[3] = this.MainHost.Hosts[3].AsSpan(1, this.MainHost.Hosts[3].Length - 1).ToArray();// System.Text.ASCIIEncoding.UTF8.GetBytes(String.Format(".{0}{1}{2}", this.Site.Root, union, domain));
|
|
list.Add(hostConvert);
|
|
|
|
}
|
|
break;
|
|
default:
|
|
var vIndex = vk.IndexOf(':');
|
|
if (vIndex > 0)
|
|
{
|
|
var hostConvert = new HostConvert();
|
|
|
|
var hMain = vk.Substring(0, vIndex).Trim();
|
|
var proxy = vk.Substring(vIndex + 1).Trim();
|
|
if (hMain.EndsWith("."))
|
|
{
|
|
if (String.IsNullOrEmpty(proxy) == false && proxy.Contains('.') == false)
|
|
{
|
|
var vl = hMain.Replace('.', '-');
|
|
var sit = DataFactory.Instance().Site(proxy);
|
|
if (sit != null)
|
|
{
|
|
var doms = sit.Domain.Split(',', '\n');
|
|
foreach (var dName in doms)
|
|
{
|
|
var dName2 = dName.Trim();
|
|
var url = String.Empty;
|
|
if (String.IsNullOrEmpty(dName2) == false)
|
|
{
|
|
var tIndex = dName2.IndexOf('~');
|
|
if (tIndex > 0)
|
|
{
|
|
dName2 = dName2.Substring(0, tIndex).Trim();
|
|
}
|
|
|
|
if (dName2.EndsWith("]"))
|
|
{
|
|
var vin = dName2.LastIndexOf("[");
|
|
if (vin > -1)
|
|
{
|
|
url = dName2.Substring(0, vin).TrimEnd(']', ' ').Trim();
|
|
}
|
|
else
|
|
{
|
|
url = dName2.Substring(0, vin).TrimEnd(']', ' ').Trim();
|
|
}
|
|
var sIndex = url.LastIndexOf('/');
|
|
if (sIndex > 0)
|
|
{
|
|
|
|
url = url.Substring(0, sIndex);
|
|
}
|
|
}
|
|
else if (v.IndexOf('@') == -1)
|
|
{
|
|
url = dName2;
|
|
var sIndex = url.LastIndexOf('/');
|
|
if (sIndex > 0)
|
|
{
|
|
url = url.Substring(0, sIndex);
|
|
}
|
|
|
|
}
|
|
}
|
|
if (String.IsNullOrEmpty(url) == false)
|
|
{
|
|
if (url.Contains('*'))
|
|
{
|
|
hostConvert.Hosts[0] = System.Text.ASCIIEncoding.UTF8.GetBytes($"{vl}{sit.Root}{union}{domain}");
|
|
var l = new UMCUri(url.Replace("*.", ""));
|
|
hostConvert.Hosts[1] = System.Text.ASCIIEncoding.UTF8.GetBytes(hMain + l.Host);
|
|
hostConvert.Hosts[2] = System.Text.ASCIIEncoding.UTF8.GetBytes(hMain + l.UMCAuthority);
|
|
hostConvert.Hosts[3] = System.Text.ASCIIEncoding.UTF8.GetBytes(Uri.EscapeDataString(hMain + l.UMCAuthority));
|
|
|
|
list.Add(hostConvert);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
else if (String.Equals(hMain, "-"))
|
|
{
|
|
hMain = $"{this.Site.Root}{union}{domain}";
|
|
}
|
|
hostConvert.Hosts[0] = System.Text.ASCIIEncoding.UTF8.GetBytes(hMain);
|
|
|
|
if (String.IsNullOrEmpty(proxy) == false)
|
|
{
|
|
var pIndex = proxy.IndexOf(':');
|
|
if (pIndex > 0)
|
|
{
|
|
hostConvert.Hosts[1] = System.Text.ASCIIEncoding.UTF8.GetBytes(proxy.Substring(0, pIndex));
|
|
hostConvert.Hosts[2] = System.Text.ASCIIEncoding.UTF8.GetBytes(proxy);
|
|
|
|
}
|
|
else
|
|
{
|
|
hostConvert.Hosts[1] =
|
|
hostConvert.Hosts[2] = System.Text.ASCIIEncoding.UTF8.GetBytes(proxy);
|
|
|
|
}
|
|
hostConvert.Hosts[3] = System.Text.ASCIIEncoding.UTF8.GetBytes(Uri.EscapeDataString(proxy));
|
|
|
|
list.Add(hostConvert);
|
|
}
|
|
}
|
|
else if (vk.EndsWith("."))
|
|
{
|
|
if (this.IsUnion)
|
|
{
|
|
var vsrc = vk.Substring(0, vk.Length - 1);
|
|
var vv = vsrc.Replace('.', '-');
|
|
PrefixHost[vv] = vsrc;//vk.Replace('.', '-');
|
|
|
|
var vkb = System.Text.ASCIIEncoding.UTF8.GetBytes(vv);
|
|
var vhm = new byte[vkb.Length + this.MainHost.Hosts[0].Length];
|
|
Array.Copy(vkb, 0, vhm, 0, vkb.Length);
|
|
Array.Copy(this.MainHost.Hosts[0], 0, vhm, vkb.Length, this.MainHost.Hosts[0].Length);
|
|
var hostConvert = new HostConvert();
|
|
hostConvert.Hosts[0] = vhm;
|
|
|
|
var vsrcb = System.Text.ASCIIEncoding.UTF8.GetBytes(vsrc);
|
|
for (var i = 1; i <= 3; i++)
|
|
{
|
|
var vhm1 = new byte[vkb.Length + this.MainHost.Hosts[i].Length];
|
|
|
|
Array.Copy(vsrcb, 0, vhm1, 0, vsrcb.Length);
|
|
|
|
Array.Copy(this.MainHost.Hosts[i], 0, vhm1, vsrcb.Length, this.MainHost.Hosts[i].Length);
|
|
|
|
hostConvert.Hosts[i] = vhm1;
|
|
}
|
|
list.Add(hostConvert);
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
var sit = DataFactory.Instance().Site(vk);
|
|
if (sit != null)
|
|
{
|
|
var doms = sit.Domain.Split(',', '\n');
|
|
foreach (var dName in doms)
|
|
{
|
|
var dName2 = dName.Trim();
|
|
var url = String.Empty;
|
|
if (String.IsNullOrEmpty(dName2) == false)
|
|
{
|
|
var tIndex = dName2.IndexOf('~');
|
|
if (tIndex > 0)
|
|
{
|
|
dName2 = dName2.Substring(0, tIndex).Trim();
|
|
}
|
|
|
|
if (dName2.EndsWith("]"))
|
|
{
|
|
var vin = dName2.LastIndexOf("[");
|
|
if (vin > -1)
|
|
{
|
|
url = dName2.Substring(0, vin).TrimEnd(']', ' ').Trim();
|
|
}
|
|
else
|
|
{
|
|
url = dName2.Substring(0, vin).TrimEnd(']', ' ').Trim();
|
|
}
|
|
var sIndex = url.LastIndexOf('/');
|
|
if (sIndex > 0)
|
|
{
|
|
|
|
url = url.Substring(0, sIndex);
|
|
}
|
|
}
|
|
else if (v.IndexOf('@') == -1)
|
|
{
|
|
url = dName2;
|
|
var sIndex = url.LastIndexOf('/');
|
|
if (sIndex > 0)
|
|
{
|
|
url = url.Substring(0, sIndex);
|
|
}
|
|
|
|
}
|
|
}
|
|
if (String.IsNullOrEmpty(url) == false)
|
|
{
|
|
var hostConvert = new HostConvert();
|
|
|
|
if (url.Contains('*'))
|
|
{
|
|
hostConvert.Hosts[0] = System.Text.ASCIIEncoding.UTF8.GetBytes($"-{sit.Root}{union}{domain}");
|
|
var l = new UMCUri(url.Replace("*.", ""));
|
|
hostConvert.Hosts[1] = System.Text.ASCIIEncoding.UTF8.GetBytes('.' + l.Host);
|
|
hostConvert.Hosts[2] = System.Text.ASCIIEncoding.UTF8.GetBytes('.' + l.UMCAuthority);
|
|
hostConvert.Hosts[3] = System.Text.ASCIIEncoding.UTF8.GetBytes(Uri.EscapeDataString('.' + l.UMCAuthority));
|
|
}
|
|
else
|
|
{
|
|
if (String.IsNullOrEmpty(sit.Host) == false)
|
|
{
|
|
url = url.Replace(new UMCUri(url).Host, sit.Host);
|
|
}
|
|
hostConvert.Hosts[0] = System.Text.ASCIIEncoding.UTF8.GetBytes($"{sit.Root}{union}{domain}");
|
|
var l = new UMCUri(url);
|
|
hostConvert.Hosts[1] = System.Text.ASCIIEncoding.UTF8.GetBytes(l.Host);
|
|
hostConvert.Hosts[2] = System.Text.ASCIIEncoding.UTF8.GetBytes(l.UMCAuthority);
|
|
hostConvert.Hosts[3] = System.Text.ASCIIEncoding.UTF8.GetBytes(Uri.EscapeDataString(l.UMCAuthority));
|
|
|
|
|
|
}
|
|
list.Add(hostConvert);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case "rp":
|
|
hostReplace |= HostReplaceModel.Replace;
|
|
break;
|
|
case "rm":
|
|
hostReplace |= HostReplaceModel.Replace;
|
|
break;
|
|
case "in":
|
|
hostReplace |= HostReplaceModel.Input;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
replaceSetting.Model = hostReplace;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_HostPage = hostPage;
|
|
}
|
|
|
|
|
|
public static Guid MD5Key(params object[] keys)
|
|
{
|
|
var md5 = System.Security.Cryptography.MD5.Create();
|
|
return new Guid(md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(String.Join(",", keys))));
|
|
|
|
|
|
}
|
|
void ConfigAllowPath(String sConf)
|
|
{
|
|
|
|
var saticPagePath = new HashSet<PageConfig<int>>(new EqualityComparer<int>());
|
|
Dictionary<String, HashSet<PageConfig<int>>> subs = new System.Collections.Generic.Dictionary<string, HashSet<PageConfig<int>>>();
|
|
if (String.IsNullOrEmpty(sConf) == false)
|
|
{
|
|
|
|
foreach (var k in sConf.Split(',', ' ', '\t', '\n'))
|
|
{
|
|
var v = k.Trim();
|
|
if (String.IsNullOrEmpty(v) == false && v.StartsWith("#") == false)
|
|
{
|
|
var checPath = saticPagePath;
|
|
var vIndex = v.IndexOf(':');
|
|
if (vIndex > 0)
|
|
{
|
|
var key = v.Substring(0, vIndex);
|
|
if (subs.TryGetValue(key, out checPath) == false)
|
|
{
|
|
checPath = new HashSet<PageConfig<int>>(new EqualityComparer<int>());
|
|
subs.Add(key, checPath);
|
|
}
|
|
v = v.Substring(vIndex + 1).Trim();
|
|
}
|
|
if (String.IsNullOrEmpty(v))
|
|
{
|
|
continue;
|
|
}
|
|
var page = new PageConfig<int>() { StartPath = String.Empty, EndPath = String.Empty };
|
|
|
|
var splitIndex = v.IndexOf('*');
|
|
switch (splitIndex)
|
|
{
|
|
case -1:
|
|
page.StartPath = v;
|
|
break;
|
|
case 0:
|
|
if (v.Length > 1)
|
|
{
|
|
page.EndPath = v.Substring(1);
|
|
}
|
|
else
|
|
{
|
|
if (vIndex == -1)
|
|
{
|
|
this.AllowAllPath = true;
|
|
}
|
|
checPath.Clear();
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
default:
|
|
if (splitIndex == v.Length - 1)
|
|
{
|
|
page.StartPath = v.Substring(0, v.Length - 1);
|
|
}
|
|
else
|
|
{
|
|
page.StartPath = v.Substring(0, splitIndex);
|
|
page.EndPath = v.Substring(splitIndex + 1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
checPath.Add(page);
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
this.AllowSubsPath = new Dictionary<string, PageConfig<int>[]>();
|
|
var em = subs.GetEnumerator();
|
|
while (em.MoveNext())
|
|
{
|
|
this.AllowSubsPath.Add(em.Current.Key, em.Current.Value.ToArray());
|
|
}
|
|
this.AllowPath = saticPagePath.ToArray();
|
|
|
|
this.IsClose = this.Site.Flag < 0 || this.Domains.Length == 0;
|
|
IsCheck();
|
|
}
|
|
|
|
public bool IsCheck()
|
|
{
|
|
if (this.IsClose == false)
|
|
{
|
|
if (String.IsNullOrEmpty(this.Site.MarketKey) == false)
|
|
{
|
|
this.IsClose = UMC.Data.License.GetLicense(this.Site.MarketKey).ExpireTime < Utility.TimeSpan();
|
|
return this.IsClose;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
public static String[] Config(String sConf)
|
|
{
|
|
var saticPagePath = new HashSet<String>();
|
|
|
|
if (String.IsNullOrEmpty(sConf) == false)
|
|
{
|
|
|
|
foreach (var k in sConf.Split(',', ' ', '\t', '\n'))
|
|
{
|
|
|
|
var v = k.Trim();
|
|
if (String.IsNullOrEmpty(v) == false && v.StartsWith("#") == false)
|
|
{
|
|
saticPagePath.Add(v);
|
|
}
|
|
}
|
|
}
|
|
return saticPagePath.ToArray();
|
|
}
|
|
public String Home
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
public String Root
|
|
{
|
|
get; set;
|
|
}
|
|
|
|
public Entities.Site Site
|
|
{
|
|
get; private set;
|
|
}
|
|
|
|
public String[] Domains
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
public LogSetting LogConf
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public PageConfig<int>[] AllowPath
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
public Dictionary<String, PageConfig<int>[]> AllowSubsPath
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
public String[] LogoutPath
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
System.Collections.Generic.Dictionary<String, String> _OutputCookies = new Dictionary<string, string>();
|
|
System.Collections.Generic.Dictionary<String, Dictionary<string, String>> _SubsOutputCookies = new Dictionary<string, Dictionary<string, string>>();
|
|
|
|
public System.Collections.Generic.Dictionary<String, String> Cookies
|
|
{
|
|
get
|
|
{
|
|
return _OutputCookies;
|
|
}
|
|
}
|
|
public Dictionary<string, Dictionary<string, String>> SubCookies
|
|
{
|
|
get
|
|
{
|
|
return _SubsOutputCookies;
|
|
}
|
|
}
|
|
public String[] ImagesConf
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
public String[] AppendJSConf
|
|
{
|
|
|
|
get;
|
|
private set;
|
|
}
|
|
public string[] RedirectPath
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
public bool IsClose
|
|
{
|
|
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
|
|
public System.Collections.Generic.Dictionary<String, String> HeaderConf
|
|
{
|
|
get
|
|
{
|
|
return _HeaderConf;
|
|
}
|
|
}
|
|
System.Collections.Generic.Dictionary<String, String> _HeaderConf = new Dictionary<string, String>();
|
|
|
|
public PageConfig<int>[] StatusPage
|
|
{
|
|
get
|
|
{
|
|
return _StatusPage;
|
|
}
|
|
}
|
|
public class PageConfig<T>
|
|
{
|
|
public string StartPath;
|
|
public string EndPath;
|
|
public T Value;
|
|
}
|
|
|
|
class EqualityComparer<T> : IEqualityComparer<PageConfig<T>>
|
|
{
|
|
|
|
public bool Equals(PageConfig<T> x, PageConfig<T> y)
|
|
{
|
|
return GetHashCode(x) == GetHashCode(y);
|
|
}
|
|
|
|
public int GetHashCode([DisallowNull] PageConfig<T> obj)
|
|
{
|
|
return obj.StartPath.GetHashCode() ^ obj.EndPath.GetHashCode();
|
|
}
|
|
}
|
|
PageConfig<int>[] _StatusPage;
|
|
|
|
|
|
TestUrl[] _test;
|
|
|
|
public TestUrl[] Test
|
|
{
|
|
|
|
get
|
|
{
|
|
return _test;
|
|
}
|
|
}
|
|
HashSet<PageConfig<ReplaceSetting>> _HostPage;
|
|
public HashSet<PageConfig<ReplaceSetting>> HostPage
|
|
{
|
|
|
|
get
|
|
{
|
|
return _HostPage;
|
|
}
|
|
}
|
|
|
|
KeyValue[] _subSite;
|
|
public KeyValue[] SubSite
|
|
{
|
|
get
|
|
{
|
|
return _subSite;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|