示例#1
0
        public async Task Should_RewriteResponseContext(string url, string method, bool redirectHttps)
        {
            var domainConfiguration = new DomainConfiguration
            {
                HttpsRedirect = redirectHttps
            };

            hostResolver.Setup(x => x.GetMathingCofinguration(It.IsAny <HttpRequest>()))
            .Returns(domainConfiguration);

            hostResolver.Setup(x => x.GetHostUri(It.IsAny <HttpRequest>(), It.IsAny <DomainConfiguration>()))
            .Returns(new Uri("http://dummy.com"));

            var hostClient = new HostClient(httpClient, hostResolver.Object, exposedConfig);

            SetRequestMethod(method);

            await hostClient.ReverseProxy(httpContext);

            Assert.AreEqual(3, httpContext.Response.Headers.Count);

            Assert.AreEqual("1", httpContext.Response.Headers["CustomHeader"].ToString());
            Assert.AreEqual("2", httpContext.Response.Headers["CustomHeader2"].ToString());

            httpContext.Response.Body.Flush();
            httpContext.Response.Body.Position = 0;

            using (var bodyStream = new StreamReader(httpContext.Response.Body))
            {
                Assert.AreEqual(responseBodyString, bodyStream.ReadToEnd());
            }
        }
 /// <summary>
 /// Create a new node library manager.
 /// </summary>
 /// <param name="libraryPath">Path to the libraries folder</param>
 public NodeLibraryManager(string libraryPath, HostClient clientInterface)
 {
     this.clientInterface = clientInterface;
     if (!Directory.Exists(libraryPath)) Directory.CreateDirectory(libraryPath);
     this.libraryPath = libraryPath;
     Instance = this;
 }
示例#3
0
 public async Task AcceptClient() 
 {
     while (IsRunning)
     {
         var clientConn = await Listener.AcceptTcpClientAsync();
         var client = new HostClient(clientConn);
         Pool.AddClient(client);
         var task = client.ServeClient();
     }
 }
示例#4
0
            public void ForwardsToHostClient()
            {
                HostClient.WaitForProcessExit(null).ReturnsForAnyArgs(new WaitForProcessExitResult());
                Process.WaitForExit(100);

                HostClient.Received(1).WaitForProcessExit(
                    Arg.Is <WaitForProcessExitParams>(actual =>
                                                      actual.key == ProcessKey && actual.timeout == 100
                                                      )
                    );
            }
示例#5
0
            public void WhenProcessExits_SetsExitCode()
            {
                HostClient.WaitForProcessExit(null)
                .ReturnsForAnyArgs(new WaitForProcessExitResult {
                    exited = true, exitCode = 100
                });

                Process.WaitForExit();

                Assert.Equal(100, Process.ExitCode);
            }
示例#6
0
            public void WhenProcessExits_ReturnsTrue()
            {
                HostClient.WaitForProcessExit(null)
                .ReturnsForAnyArgs(new WaitForProcessExitResult {
                    exited = true
                });

                var success = Process.WaitForExit(1);

                Assert.True(success);
            }
示例#7
0
            public void WhenTimeoutOccurs_ReturnsFalse()
            {
                HostClient.WaitForProcessExit(null)
                .ReturnsForAnyArgs(new WaitForProcessExitResult {
                    exited = false
                });

                var success = Process.WaitForExit(0);

                Assert.False(success);
            }
示例#8
0
            public void DefaultTimeoutIsInfinite()
            {
                HostClient.WaitForProcessExit(null).ReturnsForAnyArgs(new WaitForProcessExitResult());
                Process.WaitForExit();

                HostClient.Received(1).WaitForProcessExit(
                    Arg.Is <WaitForProcessExitParams>(actual =>
                                                      actual.key == ProcessKey && actual.timeout == Timeout.Infinite
                                                      )
                    );
            }
            public Device(HostClient client)
            {
                Client = client;
                Name   = Guid.NewGuid().ToString().Substring(0, 18);

                TabbedWidget = new RemoteScriptingWidgets.TabbedWidget(
                    new RemoteScriptingWidgets.TabbedWidgetPage[] {
                    ApplicationOutput = new ApplicationOutputPage()
                }
                    );
            }
        private void RegisterDevice(HostClient client)
        {
            var device = new Device(client)
            {
                Updated = RefreshDevicesView
            };

            devices.Add(device);
            RefreshDevicesView();
            if (devices.Count == 1)
            {
                SelectDevice(0);
            }
        }
示例#11
0
        public static void Main(string[] args)
        {
            running = true;
            log4net.Config.XmlConfigurator.Configure();
            log.Info("=== Matrix Host Server Launching ===");

            log.Debug("Searching for encryption key "+Settings.Default.KeyFile+"...");
            if(!File.Exists(Settings.Default.KeyFile))
            {
                log.Error("No encryption key! Exiting...");
                Console.ReadLine();
                return;
            }

            byte[] hash;
            AES encrypt;
            //Hash the file to a all lowercase string
            using (var md5 = MD5.Create())
            {
                using (var stream = File.OpenRead(Settings.Default.KeyFile))
                {
                    hash = md5.ComputeHash(stream);
                    encrypt = new AES(Encoding.UTF8, Settings.Default.KeyFile);
                }
            }

            client = new HostClient(Settings.Default.MasterIP, Settings.Default.MasterPort, encrypt, hash);
            nodeLibraryManager = new NodeLibraryManager("CompiledNodes", client);
            pool = new NodePool();
            client.Startup();

            while(running)
            {
                Thread.Sleep(50);
            }

            client.Shutdown();
            if(restart)
            {
                restart = false;
                Main(args);
            }
        }
示例#12
0
        public async Task <bool> Connect(HostEndPoint endPoint, int timeout = 1000)
        {
            // TODO: remove this from here.
            FloodNetwork.NetworkInitialize();

            var client = new HostClient();

            host = client;

            var tcs = new TaskCompletionSource <bool>();

            var session = client.Session;

            session.StateChange += state =>
            {
                if (state == SessionState.Open)
                {
                    tcs.SetResult(true);
                }
            };

            var details = new HostConnectionDetails()
            {
                Address      = endPoint.Address,
                Port         = endPoint.Port,
                ChannelCount = ChannelCount
            };

            client.Connect(details);

            // Wait for task somewhere else
            if (await Task.WhenAny(tcs.Task, Task.Delay(timeout)) != tcs.Task)
            {
                return(false);
            }

            client.SessionPacket += OnPacket;

            Log.Info("Client connected with session!");
            return(true);
        }
示例#13
0
        public async Task<bool> Connect(HostEndPoint endPoint, int timeout = 1000)
        {
            // TODO: remove this from here.
            //Flood.Network.NetworkInitialize();

            var client = new HostClient();
            host = client;

            var tcs = new TaskCompletionSource<bool>();

            var session = client.Session;
            session.StateChange += state =>
                                       {
                                           if (state == SessionState.Open)
                                               tcs.SetResult(true);
                                       };

            var details = new HostConnectionDetails()
            {
                Address = endPoint.Address,
                Port = endPoint.Port,
                ChannelCount = ChannelCount
            };

            client.Connect(details);

            // Wait for task somewhere else
            if (await Task.WhenAny(tcs.Task, Task.Delay(timeout)) != tcs.Task)
                return false;

            client.SessionPacket += OnPacket;

            Log.Info("Client connected with session!");
            return true;
        }
示例#14
0
        public void SendCommand(RemoteSessionCommand command, string args = "")
        {
            if (RemoteSession.State == RemoteSessionState.NotConnected ||
                RemoteSession.State == RemoteSessionState.Disconnected)
            {
                return;
            }

            var commandWithArgs = string.Concat((string)RemoteSessionCommandMapping.ToPrefix[command], args);

            switch (command)
            {
            // as the process command line can be displayed into the task manager / process explorer, the connection settings (including user credentials) are now passed to the host client through the inputs pipe
            // their values are set from the login page (using http(s) post), they shouldn't be modified at this step
            case RemoteSessionCommand.SendServerAddress:
            case RemoteSessionCommand.SendVMGuid:
            case RemoteSessionCommand.SendUserDomain:
            case RemoteSessionCommand.SendUserName:
            case RemoteSessionCommand.SendUserPassword:
            case RemoteSessionCommand.SendStartProgram:

                if (RemoteSession.State != RemoteSessionState.Connecting)
                {
                    return;
                }

                break;

            // browser, keyboard, mouse, etc.
            case RemoteSessionCommand.SendBrowserResize:
            case RemoteSessionCommand.SendKeyUnicode:
            case RemoteSessionCommand.SendMouseMove:
            case RemoteSessionCommand.SendMouseLeftButton:
            case RemoteSessionCommand.SendMouseMiddleButton:
            case RemoteSessionCommand.SendMouseRightButton:
            case RemoteSessionCommand.SendMouseWheelUp:
            case RemoteSessionCommand.SendMouseWheelDown:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                break;

            case RemoteSessionCommand.SendKeyScancode:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                var keyCodeAndState = args.Split(new[] { "-" }, StringSplitOptions.None);

                var jsKeyCode = int.Parse(keyCodeAndState[0]);
                var keyState  = keyCodeAndState[1];

                var rdpScanCode = JsKeyCodeToRdpScanCodeMapping.MapTable[jsKeyCode];
                if (rdpScanCode != null && (int)rdpScanCode != 0)
                {
                    commandWithArgs = string.Concat((string)RemoteSessionCommandMapping.ToPrefix[command], (int)rdpScanCode + "-" + keyState);
                }
                break;

            // control
            case RemoteSessionCommand.SetStatMode:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Stat mode {0}, remote session {1}", args == "1" ? "ON" : "OFF", RemoteSession.Id);
                RemoteSession.StatMode = args == "1";
                break;

            case RemoteSessionCommand.SetDebugMode:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Debug mode {0}, remote session {1}", args == "1" ? "ON" : "OFF", RemoteSession.Id);
                RemoteSession.DebugMode = args == "1";
                break;

            case RemoteSessionCommand.SetCompatibilityMode:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Compatibility mode {0}, remote session {1}", args == "1" ? "ON" : "OFF", RemoteSession.Id);
                RemoteSession.CompatibilityMode = args == "1";
                break;

            case RemoteSessionCommand.SetScaleDisplay:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Display scaling {0}, remote session {1}", args != "0" ? args : "OFF", RemoteSession.Id);
                RemoteSession.ScaleDisplay = args != "0";
                break;

            case RemoteSessionCommand.SetImageEncoding:

                if (RemoteSession.State != RemoteSessionState.Connecting &&
                    RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Image encoding {0}, remote session {1}", int.Parse(args), RemoteSession.Id);
                RemoteSession.ImageEncoding = (ImageEncoding)int.Parse(args);
                break;

            case RemoteSessionCommand.SetImageQuality:

                if (RemoteSession.State != RemoteSessionState.Connecting &&
                    RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Image quality {0}, remote session {1}", int.Parse(args), RemoteSession.Id);
                RemoteSession.ImageQuality = int.Parse(args);
                break;

            case RemoteSessionCommand.SetImageQuantity:

                if (RemoteSession.State != RemoteSessionState.Connecting &&
                    RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Image quantity {0}, remote session {1}", int.Parse(args), RemoteSession.Id);
                RemoteSession.ImageQuantity = int.Parse(args);
                break;

            case RemoteSessionCommand.RequestFullscreenUpdate:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Requesting fullscreen update, all image(s) will now be discarded while waiting for it, remote session {0}", RemoteSession.Id);
                FullscreenEventPending = true;
                break;

            case RemoteSessionCommand.RequestRemoteClipboard:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Requesting remote clipboard, remote session {0}", RemoteSession.Id);
                break;

            case RemoteSessionCommand.ConnectClient:

                if (RemoteSession.State != RemoteSessionState.Connecting)
                {
                    return;
                }

                Trace.TraceInformation("Connecting remote session, remote session {0}", RemoteSession.Id);
                break;

            case RemoteSessionCommand.CloseClient:

                if (RemoteSession.State != RemoteSessionState.Disconnecting)
                {
                    return;
                }

                Trace.TraceInformation("Closing remote session, remote session {0}", RemoteSession.Id);
                break;
            }

            Trace.TraceInformation("Sending command with args {0}, remote session {1}", commandWithArgs, RemoteSession.Id);

            try
            {
                PipeHelper.WritePipeMessage(
                    Pipes.InputsPipe,
                    "remotesession_" + RemoteSession.Id + "_inputs",
                    commandWithArgs + "\t");
            }
            catch (Exception exc)
            {
                Trace.TraceWarning("Failed to send command {0}, args {1}, remote session {2} ({3})", command, args, RemoteSession.Id, exc);

                // there is a problem with the inputs pipe, force close the remote session in order to avoid it being stuck
                // it's usually not a big deal, some inputs being sent while the pipes are being disconnected when the host client is closed (and thus before the remote session state is set to disconnected), but better take no risk...
                HostClient.StopProcess();
            }
        }
示例#15
0
        public void TestPeerConnection()
        {
            Flood.Network.NetworkInitialize();

            var conn = new HostConnectionDetails {Address = "", Port = 13131};

            var hostServer = new HostServer();
            var hostClient = new HostClient();

            hostServer.CreateSocket(conn);
            hostClient.Connect(conn);

            //Test Connections
            {
                //bool clientConnected = false;
                //bool serverConnected = false;
                //hostClient.PeerConnect += peer => clientConnected = true;
                //hostServer.PeerConnect += peer => serverConnected = true;

                var watch = Stopwatch.StartNew();
                while (watch.ElapsedMilliseconds < 20)
                {
                    hostClient.ProcessEvents(1);
                    hostServer.ProcessEvents(1);
                }

                //Assert.IsTrue(clientConnected);
                //Assert.IsTrue(serverConnected);
            }

            //Test QueuePacket
            {
                const ushort packetId = 13;
                const string packetString = "message";

                var packetReceived = false;
                var packetReceivedId = -1;
                var packetReceiveString = "";

                hostServer.SessionPacket += (session, packet, channel) =>
                                           {
                                               packetReceived = true;
                                               packetReceivedId = packet.Id;
                                               var bytes = packet.Read();
                                               packetReceiveString = Encoding.UTF8.GetString(bytes.ToArray(),0,bytes.Count);
                                           };

                var p = new Packet(packetId);
                p.Write(new List<byte>(Encoding.ASCII.GetBytes(packetString)));

                hostClient.Peer.QueuePacket(p, 0);

                var watch = Stopwatch.StartNew();
                while (watch.ElapsedMilliseconds < 20)
                {
                    hostClient.ProcessEvents(1);
                    hostServer.ProcessEvents(1);
                }

                Assert.IsTrue(packetReceived);
                Assert.AreEqual(packetId,packetReceivedId);
                Assert.AreEqual(packetString,packetReceiveString);
            }

            //Test Encrypted Packet
            {
                const ushort packetId = 13;
                const string packetString = "message";

                var packetReceived = false;
                var packetReceivedId = -1;
                var packetReceiveString = "";

                hostServer.SessionPacket += (session, packet, channel) =>
                                           {
                                               packetReceived = true;
                                               packetReceivedId = packet.Id;
                                               var bytes = packet.Read();
                                               packetReceiveString = Encoding.UTF8.GetString(bytes.ToArray(),0,bytes.Count);
                                           };

                var p = new Packet(packetId) {Flags = PacketFlags.Encrypted};
                p.Write(new List<byte>(Encoding.ASCII.GetBytes(packetString)));

                hostClient.Peer.QueuePacket(p, 0);

                var watch = Stopwatch.StartNew();
                while (watch.ElapsedMilliseconds < 20)
                {
                    hostClient.ProcessEvents(1);
                    hostServer.ProcessEvents(1);
                }

                Assert.IsTrue(packetReceived);
                Assert.AreEqual(packetId,packetReceivedId);
                Assert.AreEqual(packetString,packetReceiveString);
            }
        }
示例#16
0
        public void TestPeerConnection()
        {
            FloodNetwork.NetworkInitialize();

            var conn = new HostConnectionDetails {
                Address = "", Port = 13131
            };

            var hostServer = new HostServer();
            var hostClient = new HostClient();

            hostServer.CreateSocket(conn);
            hostClient.Connect(conn);

            //Test Connections
            {
                //bool clientConnected = false;
                //bool serverConnected = false;
                //hostClient.PeerConnect += peer => clientConnected = true;
                //hostServer.PeerConnect += peer => serverConnected = true;

                var watch = Stopwatch.StartNew();
                while (watch.ElapsedMilliseconds < 20)
                {
                    hostClient.ProcessEvents(1);
                    hostServer.ProcessEvents(1);
                }

                //Assert.IsTrue(clientConnected);
                //Assert.IsTrue(serverConnected);
            }

            //Test QueuePacket
            {
                const ushort packetId     = 13;
                const string packetString = "message";

                var packetReceived      = false;
                var packetReceivedId    = -1;
                var packetReceiveString = "";

                hostServer.SessionPacket += (session, packet, channel) =>
                {
                    packetReceived   = true;
                    packetReceivedId = packet.Id;
                    var bytes = packet.Read();
                    packetReceiveString = Encoding.UTF8.GetString(bytes.ToArray(), 0, bytes.Count);
                };

                var p = new Packet(packetId);
                p.Write(new List <byte>(Encoding.ASCII.GetBytes(packetString)));

                hostClient.Peer.QueuePacket(p, 0);

                var watch = Stopwatch.StartNew();
                while (watch.ElapsedMilliseconds < 20)
                {
                    hostClient.ProcessEvents(1);
                    hostServer.ProcessEvents(1);
                }

                Assert.IsTrue(packetReceived);
                Assert.AreEqual(packetId, packetReceivedId);
                Assert.AreEqual(packetString, packetReceiveString);
            }

            //Test Encrypted Packet
            {
                const ushort packetId     = 13;
                const string packetString = "message";

                var packetReceived      = false;
                var packetReceivedId    = -1;
                var packetReceiveString = "";

                hostServer.SessionPacket += (session, packet, channel) =>
                {
                    packetReceived   = true;
                    packetReceivedId = packet.Id;
                    var bytes = packet.Read();
                    packetReceiveString = Encoding.UTF8.GetString(bytes.ToArray(), 0, bytes.Count);
                };

                var p = new Packet(packetId)
                {
                    Flags = PacketFlags.Encrypted
                };
                p.Write(new List <byte>(Encoding.ASCII.GetBytes(packetString)));

                hostClient.Peer.QueuePacket(p, 0);

                var watch = Stopwatch.StartNew();
                while (watch.ElapsedMilliseconds < 20)
                {
                    hostClient.ProcessEvents(1);
                    hostServer.ProcessEvents(1);
                }

                Assert.IsTrue(packetReceived);
                Assert.AreEqual(packetId, packetReceivedId);
                Assert.AreEqual(packetString, packetReceiveString);
            }
        }
示例#17
0
        public void SendCommand(RemoteSessionCommand command, string args = "")
        {
            if (RemoteSession.State == RemoteSessionState.NotConnected ||
                RemoteSession.State == RemoteSessionState.Disconnected)
            {
                return;
            }

            var commandWithArgs = string.Concat((string)RemoteSessionCommandMapping.ToPrefix[command], args);

            switch (command)
            {
            // as the process command line can be displayed into the task manager / process explorer, the connection settings (including user credentials) are now passed to the host client through the inputs pipe
            // their values are set from the login page (using http(s) get or post) and shouldn't be modified at this step
            case RemoteSessionCommand.SendServerAddress:
            case RemoteSessionCommand.SendVMGuid:
            case RemoteSessionCommand.SendUserDomain:
            case RemoteSessionCommand.SendUserName:
            case RemoteSessionCommand.SendUserPassword:
            case RemoteSessionCommand.SendStartProgram:

                if (RemoteSession.State != RemoteSessionState.Connecting)
                {
                    return;
                }

                break;

            // browser resize
            case RemoteSessionCommand.SendBrowserResize:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                if (_resizeDelayed)
                {
                    if (_resizeTimeout != null)
                    {
                        _resizeTimeout.Cancel();
                        _resizeTimeout.Dispose();
                    }
                    _resizeTimeout = new CancellationTokenSource();
                    Task.Delay(500, _resizeTimeout.Token).ContinueWith(task =>
                    {
                        var resolution = args.Split(new[] { "x" }, StringSplitOptions.None);
                        var width      = int.Parse(resolution[0]);
                        var height     = int.Parse(resolution[1]);

                        RemoteSession.ClientWidth  = width < 100 ? 100 : width;
                        RemoteSession.ClientHeight = height < 100 ? 100 : height;

                        if (RemoteSession.BrowserResize == BrowserResize.Reconnect)
                        {
                            RemoteSession.Reconnect = true;
                            SendCommand(RemoteSessionCommand.CloseClient);
                        }
                        else
                        {
                            _resizeDelayed = false;
                            SendCommand(RemoteSessionCommand.SendBrowserResize, args);
                        }
                    }, TaskContinuationOptions.NotOnCanceled);
                    return;
                }
                _resizeDelayed = true;
                break;

            // browser pulse
            case RemoteSessionCommand.SendBrowserPulse:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                break;

            // keyboard, mouse
            case RemoteSessionCommand.SendKeyUnicode:
            case RemoteSessionCommand.SendMouseMove:
            case RemoteSessionCommand.SendMouseLeftButton:
            case RemoteSessionCommand.SendMouseMiddleButton:
            case RemoteSessionCommand.SendMouseRightButton:
            case RemoteSessionCommand.SendMouseWheelUp:
            case RemoteSessionCommand.SendMouseWheelDown:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                break;

            case RemoteSessionCommand.SendKeyScancode:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                var keyCodeAndState = args.Split(new[] { "-" }, StringSplitOptions.None);

                var jsKeyCode = int.Parse(keyCodeAndState[0]);
                var keyState  = keyCodeAndState[1];

                var rdpScanCode = JsKeyCodeToRdpScanCodeMapping.MapTable[jsKeyCode] as RdpScanCode;
                if (rdpScanCode != null && rdpScanCode.Value != 0)
                {
                    commandWithArgs = string.Concat((string)RemoteSessionCommandMapping.ToPrefix[command], rdpScanCode.Value + "-" + keyState + "-" + (rdpScanCode.Extend ? "1" : "0"));
                }
                break;

            // control
            case RemoteSessionCommand.SetScaleDisplay:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Display scaling {0}, remote session {1}", args != "0" ? args : "OFF", RemoteSession.Id);
                RemoteSession.BrowserResize = args != "0" ? BrowserResize.Scale : BrowserResize.None;
                break;

            case RemoteSessionCommand.SetReconnectSession:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Session reconnect {0}, remote session {1}", args == "1" ? "ON" : "OFF", RemoteSession.Id);
                RemoteSession.BrowserResize = args == "1" ? BrowserResize.Reconnect : BrowserResize.None;
                break;

            case RemoteSessionCommand.SetImageEncoding:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Image encoding {0}, remote session {1}", int.Parse(args), RemoteSession.Id);
                RemoteSession.ImageEncoding = (ImageEncoding)int.Parse(args);
                break;

            case RemoteSessionCommand.SetImageQuality:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Image quality {0}, remote session {1}", int.Parse(args), RemoteSession.Id);
                RemoteSession.ImageQuality = int.Parse(args);
                break;

            case RemoteSessionCommand.SetImageQuantity:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Image quantity {0}, remote session {1}", int.Parse(args), RemoteSession.Id);
                RemoteSession.ImageQuantity = int.Parse(args);
                break;

            case RemoteSessionCommand.SetAudioFormat:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Audio format {0}, remote session {1}", int.Parse(args), RemoteSession.Id);
                RemoteSession.AudioFormat = (AudioFormat)int.Parse(args);
                break;

            case RemoteSessionCommand.SetAudioBitrate:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                Trace.TraceInformation("Audio bitrate {0}, remote session {1}", int.Parse(args), RemoteSession.Id);
                RemoteSession.AudioBitrate = int.Parse(args);
                break;

            case RemoteSessionCommand.SetScreenshotConfig:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                var config = args.Split(new[] { "|" }, StringSplitOptions.None);
                RemoteSession.ScreenshotIntervalSecs = int.Parse(config[0]);
                RemoteSession.ScreenshotFormat       = (CaptureFormat)int.Parse(config[1]);
                RemoteSession.ScreenshotPath         = config[2];

                Trace.TraceInformation("Screenshot config {0}, remote session {1}", args, RemoteSession.Id);
                break;

            case RemoteSessionCommand.StartTakingScreenshots:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                if (_screenshotTimeout != null)
                {
                    _screenshotTimeout.Cancel();
                    _screenshotTimeout.Dispose();
                }
                _screenshotTimeout = new CancellationTokenSource();
                SendCommand(RemoteSessionCommand.TakeScreenshot);

                Trace.TraceInformation("Starting taking screenshots {0}, remote session {1}", args, RemoteSession.Id);
                break;

            case RemoteSessionCommand.StopTakingScreenshots:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                if (_screenshotTimeout != null)
                {
                    _screenshotTimeout.Cancel();
                    _screenshotTimeout.Dispose();
                }
                _screenshotTimeout = null;

                Trace.TraceInformation("Stopping taking screenshots {0}, remote session {1}", args, RemoteSession.Id);
                break;

            case RemoteSessionCommand.TakeScreenshot:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                if (_screenshotTimeout != null)
                {
                    _screenshotTimeout.Cancel();
                    _screenshotTimeout.Dispose();
                    _screenshotTimeout = new CancellationTokenSource();
                    Task.Delay(RemoteSession.ScreenshotIntervalSecs * 1000, _screenshotTimeout.Token).ContinueWith(task =>
                    {
                        SendCommand(RemoteSessionCommand.TakeScreenshot);
                    }, TaskContinuationOptions.NotOnCanceled);
                }

                FullscreenEventPending = true;

                Trace.TraceInformation("Taking screenshot {0}, remote session {1}", args, RemoteSession.Id);
                break;

            case RemoteSessionCommand.RequestFullscreenUpdate:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                FullscreenEventPending = true;

                Trace.TraceInformation("Requesting fullscreen update, all image(s) will now be discarded while waiting for it, remote session {0}", RemoteSession.Id);
                break;

            case RemoteSessionCommand.SendLocalClipboard:

                if (RemoteSession.State != RemoteSessionState.Connected)
                {
                    return;
                }

                var clipboardText = string.Empty;

                // read the clipboard text from unicode code points
                var charsCodes = args.Split(new[] { "-" }, StringSplitOptions.None);
                foreach (var charCode in charsCodes)
                {
                    clipboardText += char.ConvertFromUtf32(int.Parse(charCode));
                }

                // truncated above max length, which was normally already enforced client side; re-checking
                if (clipboardText.Length > _clipboardMaxLength)
                {
                    clipboardText = clipboardText.Substring(0, _clipboardMaxLength) + "--- TRUNCATED ---";
                }

                commandWithArgs = string.Concat((string)RemoteSessionCommandMapping.ToPrefix[command], clipboardText);

                Trace.TraceInformation("Sending local clipboard, remote session {0}", RemoteSession.Id);
                break;

            case RemoteSessionCommand.ConnectClient:

                if (RemoteSession.State != RemoteSessionState.Connecting)
                {
                    return;
                }

                Trace.TraceInformation("Connecting remote session, remote session {0}", RemoteSession.Id);
                break;

            case RemoteSessionCommand.CloseClient:

                if ((RemoteSession.State != RemoteSessionState.Connecting) &&
                    (RemoteSession.State != RemoteSessionState.Connected))
                {
                    return;
                }

                RemoteSession.State = RemoteSessionState.Disconnecting;

                Trace.TraceInformation("disconnecting remote session, remote session {0}", RemoteSession.Id);
                break;
            }

            Trace.TraceInformation("Sending command with args {0}, remote session {1}", commandWithArgs, RemoteSession.Id);

            try
            {
                PipeHelper.WritePipeData(
                    Pipes.InputsPipe,
                    "remotesession_" + RemoteSession.Id + "_inputs",
                    commandWithArgs);
            }
            catch (Exception exc)
            {
                Trace.TraceWarning("Failed to send command {0}, args {1}, remote session {2} ({3})", command, args, RemoteSession.Id, exc);

                // there is a problem with the inputs pipe, force close the remote session in order to avoid it being stuck
                // it's usually not a big deal, some inputs being sent while the pipes are being disconnected when the host client is closed (and thus before the remote session state is set to disconnected), but better take no risk...
                HostClient.StopProcess();
            }
        }
示例#18
0
 public async Task Invoke(HttpContext httpContext, HostClient hostClient)
 {
     await hostClient.ReverseProxy(httpContext).ConfigureAwait(false);
 }