/* Copyright © 2019 Tara Piccari (Aria; Tashia Redrose) Licensed under the GPLv2 */ using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Reflection; using System.Text; using System.IO; using Newtonsoft.Json; namespace Bot.WebHookServer { public sealed class WebhookRegistry { private static WebhookRegistry _reg = null; private static readonly object locks = new object(); static WebhookRegistry() { } public static WebhookRegistry Instance { get { lock (locks) { if(_reg == null) { _reg = new WebhookRegistry(); _reg.LocateHooks(); } return _reg; } } } public Dictionary hooks = new Dictionary(); public void LocateHooks() { try { int i = 0; for(i = 0; i< AppDomain.CurrentDomain.GetAssemblies().Length; i++) { // Grab Assembly Assembly asm = null; try { asm = AppDomain.CurrentDomain.GetAssemblies()[i]; }catch(Exception e) { } if(asm != null) { int ii = 0; for(ii = 0; ii arguments = new List(); string sCheck = zAPIPath.Path; bool Found = true; // Default to true if (method != zAPIPath.HTTPMethod) Found = false; string[] aCheck = sCheck.Split(new[] { '/' }); string[] actualRequest = path.Split(new[] { '/', '?' }); // if it contains a ?, we'll put that into the GETBody string theArgs = ""; if (path.Contains('?')) { // continue string[] tmp1 = path.Split(new[] { '?' }); theArgs = tmp1[1]; actualRequest = tmp1[0].Split(new[] { '/' }); } if (actualRequest.Length == aCheck.Length) { int i = 0; for (i = 0; i < aCheck.Length; i++) { // TODO: CHANGE THIS SLOPPY MESS TO REGEX.. FOR NOW IT WORKS! if (aCheck[i] == "%") { arguments.Add(actualRequest[i]); } else { if (aCheck[i] == actualRequest[i]) { // we're good! } else { // check other path hooks before returning 404! Found = false; } } } } else Found = false; arguments.Add(theArgs); if (Found) { // Run the method Console.WriteLine("Running: " + zAPIPath.Path + "; " + zAPIPath.AssignedMethod.Name + "; For inbound: " + path); object _method = Activator.CreateInstance(zAPIPath.AssignedMethod.DeclaringType); hrd = (HTTPResponseData)zAPIPath.AssignedMethod.Invoke(_method, new object[] { arguments, body, method, headers }); // Console.WriteLine("====> " + hrd.ReplyString); return hrd; } } // an API Path wasn't found // check the filesystem string[] noArgPath = path.Split(new[] { '?' }); if (File.Exists($"htdocs/{noArgPath[0]}")) // This will provide a way to display HTML to the user. If the server must process data internally, please use a method & attribute. Nothing is stopping you from also loading in a HTML/js file and returning a stylized response. { hrd.Status = 200; hrd.ReplyString = File.ReadAllText($"htdocs/{noArgPath[0]}"); Dictionary customHeaders = null; // This is mainly going to be used in instances where the domain-server needs a document but CORS isnt set } return hrd; } public struct HTTPResponseData { public int Status; public string ReplyString; public string ReturnContentType; } } }