public void ProcessRequestHeader(TcpClient client, int max_header = -1) { // don't re-read! if (State != HttpRequestState.None) { return; } try { State = ReadContentHeader(client.GetStream(), max_header).Result; } catch (Exception exp) { State = HttpRequestState.GENERIC_FAILURE; ErrorLogger.WithTrace(Server.Settings, string.Format("[Error][Server request handler => ProcessRequestHeader()] : exception-message : {0}.\nstacktrace : {1}\n", exp.Message, exp.StackTrace), GetType()); } }
internal static void SetupScope(dynamic Scope, System.Net.Sockets.TcpClient client, Settings Settings, HttpRequestHeader req = null) { System.Diagnostics.Contracts.Contract.Requires(Settings != null); if (client != null && client.Connected && client.Client != null) { //System.Net.Sockets.TransmitFileOptions.UseSystemThread //client.Client.SendFile(,,, System.Net.Sockets.TransmitFileOptions.UseKernelApc) Scope.Client = client; try { Scope.Stream = client?.GetStream(); } catch (Exception exp) { ErrorLogger.WithTrace(Settings, string.Format("[Fatel][Backend error => SetupScope()] : exception-message : {0}.\nstacktrace : {1}\n", exp.Message, exp.StackTrace), typeof(PythonRunner)); } finally { Scope.Stream = new System.Net.Sockets.NetworkStream(client.Client); //new System.IO.MemoryStream(new byte[2048], true); } Scope.SendAsync = new Action <byte[]>(async(bytes) => { try { if (!Scope.Stream.CanWrite) { return; } await Scope.Stream.WriteAsync(bytes); await Scope.Stream?.FlushAsync(); if ((bool)Scope.AutoClose) { client.Close(); } } catch (Exception exp) { ErrorLogger.WithTrace(Settings, string.Format("[Fatel][Backend error => SendAsync()] : exception-message : {0}.\nstacktrace : {1}\n", exp.Message, exp.StackTrace), typeof(IronPythonObject)); } }); Scope.SendTextAsync = new Action <string>(async(text) => { try { if (!Scope.Stream.CanWrite) { return; } await Scope.Stream.WriteAsync(System.Text.Encoding.UTF8.GetBytes(text)); await Scope.Stream?.FlushAsync(); if ((bool)Scope.AutoClose) { client.Close(); } } catch (Exception exp) { ErrorLogger.WithTrace(Settings, string.Format("[Fatel][Backend error => SendTextAsync()] : exception-message : {0}.\nstacktrace : {1}\n", exp.Message, exp.StackTrace), typeof(IronPythonObject)); } }); Scope.SendFile = new Action <string, bool>((file, isBigFile) => { client.Client.SendFile(file, null, null, isBigFile ? System.Net.Sockets.TransmitFileOptions.UseSystemThread : System.Net.Sockets.TransmitFileOptions.UseDefaultWorkerThread); }); Scope.SendText = new Action <string>((text) => { try { if (!Scope.Stream.CanWrite) { return; } Scope.Stream.Write(System.Text.Encoding.UTF8.GetBytes(text)); Scope.Stream.Flush(); if ((bool)Scope.AutoClose) { client.Close(); } } catch (Exception exp) { ErrorLogger.WithTrace(Settings, string.Format("[Fatel][Backend error => SendText()] : exception-message : {0}.\nstacktrace : {1}\n", exp.Message, exp.StackTrace), typeof(IronPythonObject)); } }); Scope.Send = new Action <byte[]>(bytes => { try { Scope.Stream.Write(bytes); Scope.Stream.Flush(); if ((bool)Scope.AutoClose) { client.Close(); } } catch (Exception exp) { ErrorLogger.WithTrace(Settings, string.Format("[Fatel][Backend error => Send()] : exception-message : {0}.\nstacktrace : {1}\n", exp.Message, exp.StackTrace), typeof(IronPythonObject)); } }); Scope.ReadAsync = new Action <byte[], int, int> (async(buffer, offest, length) => await Scope.Stream?.ReadAsync(buffer, offest, length)); Scope.Read = new Action <byte[], int, int>( (buffer, offest, length) => Scope.Stream?.Read(buffer, offest, length)); Scope.Close = new Action(() => client?.Close()); Scope.IsClientConnected = new Func <bool>(() => client.IsConnected()); //string address = client.Client.RemoteEndPoint.ToString(); //Scope.Address = address; //Scope.AddressParts = address.Split(':'); } Scope.AutoClose = false; Scope.ReadFileBytes = new Func <string, byte[]>(f => { try { return(System.IO.File.ReadAllBytes(f)); } catch (Exception exp) { ErrorLogger.WithTrace(Settings, string.Format("[Fatel][Backend error => ReadFileBytes()] : exception-message : {0}.\nstacktrace : {1}\n", exp.Message, exp.StackTrace), typeof(IronPythonObject)); return(new byte[] { 0 }); } }); Scope.ReadFileBytesAction = new Action <string, Action <byte[]> >((f, work) => { try { using System.IO.FileStream stream = new System.IO.FileStream(f, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite); byte[] buffer = new byte[2048]; int read = 0; while ((read = stream.Read(buffer, 0, buffer.Length)) != 0) { work?.Invoke(buffer[..read]);
private static byte[] RunNativeRequestProcessorApp(HttpRequestHeader requestHeader, Settings settings) { using (System.Diagnostics.Process process = new System.Diagnostics.Process()) { StringBuilder output = new StringBuilder(); StringBuilder error = new StringBuilder(); string serializedString = GenerateSerializedInput(requestHeader); process.StartInfo.FileName = CPYTHON_PATH; process.StartInfo.UseShellExecute = false; process.StartInfo.Arguments = $"\"{requestHeader.AbsoluteFilePath}\" \"{serializedString}\""; process.StartInfo.RedirectStandardOutput = process.StartInfo.RedirectStandardError = true; // Decision made in 31/2/2021 to wrap all input streams // to pass arguments process.StartInfo.RedirectStandardInput = true; process.OutputDataReceived += (s, e) => { output.Append(e.Data); }; process.ErrorDataReceived += (s, e) => { error.Append(e.Data); }; process.Start(); process.StandardInput.WriteLine(serializedString); process.StandardInput.Flush(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.WaitForExit(); //process.WaitForExit(); process.Close(); //RedirectErrors string result = ""; if (error.Length != 0) { if ((bool)settings.Current.RedirectErrors) { result = error.ToString(); } else { result = ERR_MESSAGE; } ErrorLogger.WithTrace(settings, string.Format("[Warning][Server error => ProcessPython3Script()] : exception : {0}\n", error.ToString()), typeof(HttpRespondHeader)); } else { result = output.ToString(); } byte[] bytes = Encoding.UTF8.GetBytes(result); return(bytes); } }
public static byte[] RunScript(string file, HttpRequestHeader req, HttpRespondHeader res) { using (ChakraContext context = Runtime.CreateContext(true)) { //HttpRequestHeader if (!registered) { context.ServiceNode.GetService <IJSValueConverterService>().RegisterProxyConverter <HttpRequestHeader>( //register the object converter (binding, instance, serviceNode) => { binding.SetFunction("getServer", new Func <HttpServers.BaseServer>(() => instance.Server)); binding.SetFunction("getHeaderKeys", new Func <Dictionary <string, string> >(() => instance.HeaderKeys)); binding.SetFunction("getParameters", new Func <System.Collections.Specialized.NameValueCollection>(() => instance.Parameters)); binding.SetFunction("getParametersJSON", new Func <string>(() => instance.Parameters.Serialize())); binding.SetFunction("getAbsoluteFilePath", new Func <string>(() => instance.AbsoluteFilePath)); }); // HttpRespondHeader context.ServiceNode.GetService <IJSValueConverterService>().RegisterProxyConverter <HttpRespondHeader>( //register the object converter (binding, instance, serviceNode) => { binding.SetMethod <string, string>("setState", (http, state) => instance.SetState(http.Equals("HTTP/1.0") ? HttpVersion.HTTP1_0 : http.Equals("HTTP/1.1") ? HttpVersion.HTTP2_0 : HttpVersion.UNKNOWN, state)); binding.SetMethod <string, string>("addHeader", (key, value) => instance.AddHeader(key, value)); binding.SetMethod <string>("setBody", (body) => instance.SetBody(body)); binding.SetMethod <System.Net.Sockets.TcpClient>("send", c => { byte[] b = instance.Build(); c.GetStream().Write(b, 0, b.Length); c.GetStream().Flush(); }); binding.SetMethod("markAsResponded", instance.Responded); }); // TcpClient stuff context.ServiceNode.GetService <IJSValueConverterService>().RegisterProxyConverter <System.Net.Sockets.TcpClient>( //register the object converter (binding, instance, serviceNode) => { binding.SetMethod <string>("sendText", (s) => { byte[] b = Encoding.UTF8.GetBytes(s); instance.GetStream().Write(b, 0, b.Length); instance.GetStream().Flush(); }); binding.SetMethod <HttpRespondHeader>("send", (s) => { byte[] b = s.Build(); instance.GetStream().Write(b, 0, b.Length); instance.GetStream().Flush(); }); binding.SetFunction <string>("getIP", () => ((System.Net.IPEndPoint)instance.Client.RemoteEndPoint).Address.ToString()); binding.SetFunction <int>("getPort", () => ((System.Net.IPEndPoint)instance.Client.RemoteEndPoint).Port); binding.SetMethod("close", instance.Close); binding.SetFunction <string>("readString", () => { byte[] b = new byte[instance.Available]; instance.GetStream().Read(b, 0, b.Length); return(Encoding.UTF8.GetString(b)); }); binding.SetMethod <string, bool>("sendFile", (file, isBigFile) => { instance.Client.SendFile(file, null, null, isBigFile ? System.Net.Sockets.TransmitFileOptions.UseSystemThread : System.Net.Sockets.TransmitFileOptions.UseDefaultWorkerThread); }); }); registered = true; } context.GlobalObject.WriteProperty("RequestResult", ""); context.GlobalObject.WriteProperty("RequestHandler", req); context.GlobalObject.WriteProperty("RespondHandler", res); context.GlobalObject.WriteProperty("Client", req.Client); context.GlobalObject.WriteProperty("AutoFlush", true); context.GlobalObject.Binding.SetMethod <string>("log", (s) => Console.WriteLine(s)); context.GlobalObject.Binding.SetMethod <string>("send", (s) => { req.Client.GetStream().Write(Encoding.UTF32.GetBytes(s), 0, s.Length); if (context.GlobalObject.ReadProperty <bool>("AutoFlush")) { req.Client.GetStream().Flush(); } }); context.GlobalObject.Binding.SetMethod("flush", () => req.Client.GetStream().Flush()); context.GlobalObject.Binding.SetMethod("closeStream", () => req.Client.GetStream().Dispose()); context.GlobalObject.Binding.SetMethod("closeConnection", () => req.Client.Close()); try { context.RunScript(System.IO.File.ReadAllText(file)); } catch (Exception exp) { ErrorLogger.WithTrace(req.Server.Settings, string.Format("[Warning][Backend error => RunScript()] : exception-message : {0}.\nstacktrace : {1}\n", exp.Message, exp.StackTrace), typeof(ChakraCoreObject)); } if (res.DidRespond()) { Runtime.CollectGarbage(); return(HttpRequestHeader.ContentSplitter); } else { byte[] b = Encoding.UTF8.GetBytes(context.GlobalObject.ReadProperty <string>("RequestResult")); Runtime.CollectGarbage(); return(b); } } //context.Dispose(); }
private void AppendRule(string repositoryRule, string ruleFile) { Rule rule = new Rule(repositoryRule); rule.SetPath(ResourcePath + $"{repositoryRule}{System.IO.Path.DirectorySeparatorChar}"); foreach (string line in System.IO.File.ReadLines(ruleFile)) { if (string.IsNullOrEmpty(line) || !line.Contains(':') || line.StartsWith("--") || line.StartsWith('#')) { continue; } string[] parts = line.Split(':', 2, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim()).ToArray(); if (parts.Length != 2) { if ((bool)Current.AllowOutput) { ErrorLogger.Error($"[Settings] : Property error in repository({repositoryRule}) rule file at line '{line}'.\nProperty ignored but it might causes bugs"); } continue; } if (parts[0].StartsWith("home")) { rule.SetHome(parts[1]); } else if (parts[0].StartsWith("connection-handler")) { rule.SetConnectionHandler(parts[1]); } else if (parts[0].StartsWith("upload-directory")) { rule.SetUploadDirectory(parts[1]); } else if (parts[0].StartsWith("shared-resources")) { rule.SetAsSharedResources("true".Equals(parts[1])); } else if (parts[0].StartsWith("available")) { rule.SetAvailable("true".Equals(parts[1])); } else if (parts[0].StartsWith("private-directories")) { rule.SetPrivateDirectories(parts[1].Split(',').Select(a => a.Trim()).ToArray()); } else if (parts[0].StartsWith("exclusive-for-server")) { rule.SetExclusiveForServer(parts[1]); } else if (parts[0].StartsWith("allow-websocket-protocol")) { rule.SetAllowWebsocket(parts[1].Equals("true")); } else if (parts[0].StartsWith("websocket-idle-timeout")) { rule.SetWebSocketIdelTimeout(int.Parse(parts[1])); } else if (parts[0].StartsWith("websocket-idle-chances")) { rule.SetWebSocketIdelChances(int.Parse(parts[1])); } else if (parts[0].StartsWith("allow-server-event")) { rule.SetAllowServerEvent(parts[1].Equals("true")); } else if (parts[0].StartsWith("server-event-method")) { rule.SetServerEventMethod(parts[1].ToLower().Equals("push") ? ServerEventMethod.PUSH : ServerEventMethod.LOOP); } else if (parts[0].StartsWith("startup")) { rule.SetStartupFile(parts[1]); } else if (parts[0].StartsWith("allow-cross-repo-requests")) { rule.SetAllowCrossRepositoriesRequests(parts[1].Equals("true")); } } try { rule.Verify(); if (rule.WebSocketIdelChances == -1) { rule.SetWebSocketIdelChances((int)Current.WebSocketIdelChances); } if (rule.WebSocketIdelTimeout == -1) { rule.SetWebSocketIdelTimeout((int)Current.WebSocketIdelChances); } RepositoriesRules.Add(repositoryRule, rule); } catch (Exception exp) { ErrorLogger.WithTrace(string.Format("[Warning][Server error => Verify()] : exception-message : {0}.\nstacktrace : {1}\n", exp.Message, exp.StackTrace), typeof(Settings)); } }
private void LoadSettings() { try { string lines = System.IO.File.ReadAllText(SettingsFilePath, System.Text.Encoding.UTF8); if (string.IsNullOrEmpty(lines)) { throw new System.IO.IOException("failed to read file:" + SettingsFilePath); } Current = Newtonsoft.Json.JsonConvert.DeserializeObject <dynamic>(lines); if (Current.MainPage == null) { throw new InvalidPropertyValue("[Settings] : settings.json must contains main-page property"); } if (Current.FileNotFoundPage == null) { throw new InvalidPropertyValue("[Settings] : settings.json must contains fnf-page property"); } if (Current.WebSocketIdelChances == null || Current.WebSocketIdelChances == null) { throw new InvalidPropertyValue("[Settings] : settings.json must contains WebSocketIdleTimeout and WebSocketIdelChances"); } Current.MainPage = BasePath + ((string)Current.MainPage).Replace('/', System.IO.Path.DirectorySeparatorChar); Current.FileNotFoundPage = BasePath + ((string)Current.FileNotFoundPage).Replace('/', System.IO.Path.DirectorySeparatorChar); RepositoriesRules?.Clear(); foreach (string repositoryRule in Current.Repos) { string ruleFile = ResourcePath + $"{repositoryRule}{System.IO.Path.DirectorySeparatorChar}.rules"; if (!System.IO.File.Exists(ruleFile)) { ErrorLogger.Warn("[Settings] : Repository '" + repositoryRule + "' has no .rules file which might cause issues, won't be available"); continue; } AppendRule(repositoryRule, ruleFile); } if ((bool)Current.AllowSocketControlFlow && Current.SocketControlFlow != null) { if (SocketControlFlow.Count > 0) { SocketControlFlow.Clear(); } foreach (dynamic item in Current.SocketControlFlow) { if (!(bool)item.Enabled) { continue; } SocketControlFlow controlFlow = new SocketControlFlow(); if (controlFlow.Setup((string)item.Filter, BasePath + ((string)item.Target).Replace('/', System.IO.Path.DirectorySeparatorChar))) { SocketControlFlow.Add(controlFlow); } } } if ((bool)Current.EnableVirtualLinks && Current.VirtualLinks != null) { if (VirtualLinks.Count > 0) { VirtualLinks.Clear(); } foreach (dynamic vlink in Current.VirtualLinks) { if ((bool)vlink.Dupricated) { continue; } VirtualLinks virtualLink = new(); virtualLink.Enabled = (bool)vlink.Enabled; virtualLink.Link = (string)vlink.Link; virtualLink.Target = (string)vlink.Target; VirtualLinks.Add(virtualLink.Link, virtualLink); } } ReceiveTimeout = (Current?.ReceiveTimeout != null) ? (int)Current?.ReceiveTimeout : System.Threading.Timeout.Infinite; SendTimeout = (Current.SendTimeout != null) ? (int)Current.SendTimeout : System.Threading.Timeout.Infinite; IsReady = true; } catch (Exception exp) { if (Current == null) { ErrorLogger.WithTrace(string.Format("[Warning][Server error => LoadSettings()] : exception-message : {0}.\nstacktrace : {1}\n", exp.Message, exp.StackTrace), GetType()); } else { ErrorLogger.WithTrace(this, string.Format("[Warning][Server error => LoadSettings()] : exception-message : {0}.\nstacktrace : {1}\n", exp.Message, exp.StackTrace), GetType()); } IsReady = false; } }