Ejemplo n.º 1
0
 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());
     }
 }
Ejemplo n.º 2
0
        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]);
Ejemplo n.º 3
0
        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);
            }
        }
Ejemplo n.º 4
0
        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();
        }
Ejemplo n.º 5
0
        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));
            }
        }
Ejemplo n.º 6
0
        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;
            }
        }