using System.Reflection; using NLog; using Server.Git; namespace Server.System { public class ProtocolProcessor { private static Dictionary SERVICE_DIC = new Dictionary(); private static readonly NLog.ILogger logger = LogManager.GetCurrentClassLogger(); public static string cryptoData = ""; public static string version = ""; public static void addProtocol(AbstractService abstractService) { if (SERVICE_DIC.ContainsKey(abstractService.ProtocolValue())) { logger.Error("중복된 프로토콜 : " + abstractService.ProtocolValue()); throw new Exception("중복된 프로토콜 : " + abstractService.ProtocolValue()); } SERVICE_DIC.Add(abstractService.ProtocolValue(), abstractService); } public static void Init() { // 현재 실행 중인 어셈블리를 가져옴 var assembly = Assembly.GetExecutingAssembly(); // 'AbstractService'의 하위 클래스를 모두 찾음 var serviceTypes = assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(AbstractService)) && !t.IsAbstract); // 각 클래스의 인스턴스를 생성합니다. 생성자에서 자동으로 등록됩니다. foreach (var type in serviceTypes) addProtocol((AbstractService)Activator.CreateInstance(type)); } public static string Process(HttpContext context) { AbstractService abstractService; //TODO 좀더 딥한곳에 status를 수정하게 만들기. string Response = ""; try { Protocol cmd = (Protocol)int.Parse(context.Request.Headers["cmd"]); SERVICE_DIC.TryGetValue(cmd, out abstractService); if (abstractService == null) throw new RuntimeException("Not Found", Error.NotFound); string body = Request(context.Request).GetAwaiter().GetResult(); logger.Info("GetRequst : " + body); Req req = abstractService.Requst(body); if (req == null) throw new RuntimeException("", Error.NoData); else if (!req.IsReceivedAllField()) throw new RuntimeException("Internal Server Error", Error.Unknown); else if (!req.GetRedis()) throw new RuntimeException("null session", Error.NullSession); Response = abstractService.Process(); logger.Info("GetResponse : " + Response); } catch (RuntimeException ex) { ErrorResp error = new ErrorResp(ex); Response = error.ToJson(); logger.Error("GetErrorResponse : " + Response); } catch (Exception ex) { ErrorResp error = new ErrorResp(); Response = error.ToJson(); logger.Error("GetErrorResponse : " + ex.ToString()); } finally{} return Response; } private static async Task Request(HttpRequest request) { using var reader = new StreamReader(request.Body); return await reader.ReadToEndAsync(); } } public class GItWebhook { private static readonly NLog.ILogger logger = LogManager.GetCurrentClassLogger(); public static bool isUpdate = true; public static Thread thread; private static AbstractGit git; public static ErrorResp successResp; public static string Process(HttpContext context) { isUpdate = !isUpdate; if (isUpdate) { return successResp.ToJson(); } string Response; try { string eaDelivery = context.Request.Headers["X-Gitea-Delivery"]; logger.Info($"SaveVersion : {eaDelivery}"); //task를 쓰면 멈출수가 없기에 thread를 사용 Response = successResp.ToJson(); //무작위 공격을 대비한 1차적인 방어조치 if (eaDelivery == "" || eaDelivery.Length < 15) return Response; ProtocolProcessor.version = eaDelivery; if (thread.ThreadState == ThreadState.Stopped) { logger.Info("new excel update"); thread = new Thread(git.Init); thread.Start(); } else if (thread.ThreadState == ThreadState.WaitSleepJoin || thread.ThreadState == ThreadState.Running) { logger.Info("new excel restart"); git.isRestart = true; } } catch (RuntimeException ex) { ErrorResp error = new ErrorResp(ex); Response = error.ToJson(); logger.Error("GetErrorResponse : " + Response); } catch (Exception ex) { ErrorResp error = new ErrorResp(); Response = error.ToJson(); logger.Error("GetErrorResponse : " + ex.ToString()); } return Response; } public static void Init() { git = new XlsxToJson(); thread = new Thread(git.Init); successResp = new ErrorResp(); successResp.status = 200; successResp.message = "Success"; thread.Start(); } } }