using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Text; using System.Linq; using UMC.Data; using System.Reflection; using UMC.Net; using UMC.Web; using System.Security.Cryptography.X509Certificates; using UMC.Host; namespace UMC.ITME { class WebResource : UMC.Data.WebResource { public override void Push(Guid tid, params object[] objs) { var str = JSON.Serialize(objs); var device = Utility.Guid(tid); foreach (var p in Net.NetSubscribe.Subscribes) { try { new Uri($"http://{p.Address}:{p.Port}/UMC.WS/{device}") .WebRequest().Post(str, w => { }); } catch { } } UMC.Host.HttpWebSocket.Send(tid, str); } } public class Utility : UMC.Data.Utility { public static String MD5(System.Guid guid) { using (var md5 = System.Security.Cryptography.MD5.Create()) { return Guid(new System.Guid(md5.ComputeHash(guid.ToByteArray()))); } } public static String NameValue(NameValueCollection Headers) { var sb = new StringBuilder(); for (var i = 0; i < Headers.Count; i++) { sb.AppendFormat("{0}: {1}", Headers.GetKey(i), Headers.Get(i)); sb.AppendLine(); } sb.AppendLine(); return sb.ToString(); } static Web.WebMeta FromValue(int index, String html, out int tagEndIndex) { tagEndIndex = -1; var startIndex = 0; while (index > -1) { index--; switch (html[index]) { case ' ': break; case '<': startIndex = index; break; case '\'': case '"': index = html.LastIndexOf(html[index], index - 1); break; } if (startIndex > 0) { break; } } var start = startIndex + 1; var attrStart = -1; var attrName = String.Empty; var webMeta = new Web.WebMeta(); var IsFindTag = true; while (IsFindTag) { start++; switch (html[start]) { case '\r': case '\n': case '\t': case ' ': IsFindTag = false; webMeta.Put("tag", html.Substring(startIndex + 1, start - startIndex - 1)); break; default: IsFindTag = start < html.Length; break; } } var startValue = -1; while (start < html.Length) { switch (html[start]) { case '\r': case '\n': case '\t': case ' ': if (startValue == -1) { if (attrStart < start - 1 && attrStart > 0) { attrName = html.Substring(attrStart, start - attrStart); webMeta.Put(attrName.ToLower(), String.Empty); } } else { webMeta.Put(attrName.ToLower(), html.Substring(startValue, start - startValue)); startValue = -1; } attrStart = start + 1; break; case '=': if (attrStart < start - 1) { attrName = html.Substring(attrStart, start - attrStart); } attrStart = start + 1; startValue = attrStart; break; case '\'': case '"': var startValueIndex = html.IndexOf(html[start], start + 1); if (startValueIndex > 0) { webMeta.Put(attrName.ToLower(), System.Web.HttpUtility.HtmlDecode(html.Substring(start + 1, startValueIndex - start - 1))); } start = startValueIndex; startValue = -1; attrStart = start + 1; break; case '/': tagEndIndex = start + 1; return webMeta; case '>': tagEndIndex = start; return webMeta; default: break; } start++; } return webMeta; } static String FromValue(String html, int index, bool isForm, out int endIndex) { var ms = FromValue(index, html, out endIndex); if (ms.ContainsKey("disabled")) { return null; } switch (ms["tag"]) { case "input": var type = ms["type"]; switch (type) { case "radio": case "checkbox": if (!ms.ContainsKey("checked") && isForm) { return null; } return ms["value"] ?? "on"; } return ms["value"]; case "select": var end5 = html.IndexOf("", endIndex); var optionHtml = html.Substring(endIndex + 1, end5 - endIndex - 1); var selectedIndex = optionHtml.IndexOf(" selected", StringComparison.CurrentCultureIgnoreCase); if (selectedIndex == -1) { selectedIndex = optionHtml.IndexOf("option"); if (selectedIndex == -1) { return String.Empty; } } int optionEndIndex; var ov = FromValue(selectedIndex, optionHtml, out optionEndIndex); if (ov.ContainsKey("value")) { return ov["value"]; } else { if (html[endIndex - 1] == '/') { return String.Empty; } var end9 = optionHtml.IndexOf('<', optionEndIndex); return optionHtml.Substring(optionEndIndex + 1, end9 - optionEndIndex - 1); } case "textarea": if (html[endIndex - 1] == '/') { return ms["value"] ?? String.Empty; } var end4 = html.IndexOf('<', endIndex); if (end4 > 0) { return System.Web.HttpUtility.HtmlDecode(html.Substring(endIndex + 1, end4 - endIndex - 1)); } break; } return null; } public static string Expire(int now, int expireTime, string defaultStr) { var sExpireTime = defaultStr;// "未启用"; if (expireTime > 0) { if (expireTime > now) { var t = new TimeSpan(0, 0, expireTime - now).TotalDays; if (t < 0) { sExpireTime = $"还剩{t:0.0}天"; } else { sExpireTime = $"还剩{t:0}天"; } } else { sExpireTime = "已过期"; } } return sExpireTime; } public static void Certificate(NetHttpResponse r) { if (r.StatusCode == System.Net.HttpStatusCode.OK) { r.ReadAsString(str => { var cert = JSON.Deserialize(str); if (cert.ContainsKey("privateKey")) { var domain = cert["domain"]; var privateKey = cert["privateKey"]; var publicKey = cert["publicKey"]; var x509 = X509Certificate2.CreateFromPem(publicKey, privateKey); Certificater.Certificates[domain] = new Certificater { Name = domain, Certificate = x509 }; HotCache.Put(new Entities.SiteCert { Domain = domain, ExpirationTime = Utility.TimeSpan(x509.NotAfter), CheckTime = Utility.TimeSpan(), PrivateKey = privateKey, PublicKey = publicKey, IsApiumc = false }); } }); } else { r.ReadAsString(); } } public static Web.WebMeta FromValue(String html, bool isKey) { var webMeta = new System.Collections.Generic.Dictionary>(); var nKey = " name="; int index = html.IndexOf(nKey); while (index > 0) { var startIndex = index + nKey.Length; var start = html[startIndex]; switch (start) { case '\'': case '"': var endIndex = html.IndexOf(start, startIndex + 1); if (endIndex > startIndex) { var name = html.Substring(startIndex + 1, endIndex - startIndex - 1); var value = FromValue(html, index, !isKey, out endIndex); if (value != null) { List vs; if (webMeta.TryGetValue(name, out vs)) { vs.Add(value); } else { vs = new List(); vs.Add(value); webMeta[name] = vs; } startIndex = endIndex; } else { startIndex = endIndex; } } break; } index = html.IndexOf(nKey, startIndex); } var meta = new Web.WebMeta(); var em = webMeta.GetEnumerator(); while (em.MoveNext()) { meta.Put(em.Current.Key, String.Join(",", em.Current.Value.ToArray())); } return meta; } public static String FormValue(String html, String name) { var nKey = " name="; int index = html.IndexOf(nKey); while (index > 0) { var startIndex = index + nKey.Length; var start = html[startIndex]; switch (start) { case '\'': case '"': var endIndex = html.IndexOf(start, startIndex + 1); if (endIndex > startIndex) { if (String.Equals(name, html.Substring(startIndex + 1, endIndex - startIndex - 1))) { return FromValue(html, index, false, out endIndex); } } break; } index = html.IndexOf(nKey, startIndex); } return null; } public static NetHttpRequest Sign(NetHttpRequest http, String secret) { http.Headers.Add("umc-app-version", APIProxy.Version); http.Headers.Add("umc-proxy-sites", HotCache.Caches().First(r => r.Name == "Site").Count.ToString()); http.Headers.Add("umc-proxy-session", HotCache.Caches().First(r => r.Name == "Session").Count.ToString()); http.Headers.Add("umc-client-pfm", "sync"); http.Headers.Add("umc-request-time", UMC.Data.Utility.TimeSpan().ToString()); if (String.IsNullOrEmpty(secret) == false) { http.Headers.Add("umc-request-sign", UMC.Data.Utility.Sign(http.Headers, "umc-", secret)); } return http; } public static int Random(string val) { if (String.IsNullOrEmpty(val) == false) { var fs = System.Text.Encoding.UTF8.GetBytes(val); if (fs.Length >= 4) { int v = BitConverter.ToInt32(fs); for (var i = 4; i < fs.Length; i++) { v = v ^ fs[i]; } return v; } else { var b = new byte[4]; Array.Copy(fs, 0, b, 4 - fs.Length, fs.Length); return BitConverter.ToInt32(b); } } return 0; } public static string FirstReplace(string val, string s, string t) { var index = val.IndexOf(s); if (index == -1) { return val; } else { return $"{val.Substring(0, index)}{t}{val.Substring(index + s.Length)}"; } } } }