Exemplo n.º 1
1
        private async void StartInternal(CancellationToken cancellationToken)
        {
            byte[] buffer = new byte[256];
            var commandBuilder = new StringBuilder();

            var serverStream = new NamedPipeServerStream(this.PipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 0, 0);

            using (cancellationToken.Register(() => serverStream.Close()))
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    await Task.Factory.FromAsync(serverStream.BeginWaitForConnection, serverStream.EndWaitForConnection, TaskCreationOptions.None);

                    int read = await serverStream.ReadAsync(buffer, 0, buffer.Length);
                    commandBuilder.Append(Encoding.ASCII.GetString(buffer, 0, read));

                    while (!serverStream.IsMessageComplete)
                    {
                        read = serverStream.Read(buffer, 0, buffer.Length);
                        commandBuilder.Append(Encoding.ASCII.GetString(buffer, 0, read));
                    }

                    var response = this.HandleReceivedCommand(commandBuilder.ToString());
                    var responseBytes = Encoding.ASCII.GetBytes(response);
                    serverStream.Write(responseBytes, 0, responseBytes.Length);

                    serverStream.WaitForPipeDrain();
                    serverStream.Disconnect();

                    commandBuilder.Clear();
                }
            }
        }
        public async void Process(NamedPipeServerStream pipeServerStream)
        {
            serverStream = pipeServerStream;

            while (serverStream.IsConnected)
            {
                var ipcMessage = new byte[1];

                if (await serverStream.ReadAsync(ipcMessage, 0, 1) > 0)
                    await ProcessPacket(ipcMessage[0], serverStream);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        ///   Starts the listener.
        /// </summary>
        /// <remarks>
        /// </remarks>
        private void StartListener()
        {
            if (_cancellationTokenSource.Token.IsCancellationRequested) {
                return;
            }

            try {
                if (IsRunning) {
                    Logger.Message("Starting New Listener {0}", listenerCount++);
                    var serverPipe = new NamedPipeServerStream(PipeName, PipeDirection.InOut, Instances, PipeTransmissionMode.Message, PipeOptions.Asynchronous,
                        BufferSize, BufferSize, _pipeSecurity);
                    var listenTask = Task.Factory.FromAsync(serverPipe.BeginWaitForConnection, serverPipe.EndWaitForConnection, serverPipe);

                    listenTask.ContinueWith(t => {
                        if (t.IsCanceled || _cancellationTokenSource.Token.IsCancellationRequested) {
                            return;
                        }

                        StartListener(); // spawn next one!

                        if (serverPipe.IsConnected) {
                            var serverInput = new byte[BufferSize];

                            serverPipe.ReadAsync(serverInput, 0, serverInput.Length).AutoManage().ContinueWith(antecedent => {
                                var rawMessage = Encoding.UTF8.GetString(serverInput, 0, antecedent.Result);
                                if (string.IsNullOrEmpty(rawMessage)) {
                                    return;
                                }

                                var requestMessage = new UrlEncodedMessage(rawMessage);

                                // first command must be "startsession"
                                if (!requestMessage.Command.Equals("StartSession", StringComparison.CurrentCultureIgnoreCase)) {
                                    return;
                                }

                                // verify that user is allowed to connect.
                                try {
                                    var hasAccess = false;
                                    serverPipe.RunAsClient(() => {
                                        hasAccess = PermissionPolicy.Connect.HasPermission;
                                    });
                                    if (!hasAccess) {
                                        return;
                                    }
                                } catch {
                                    return;
                                }

                                // check for the required parameters.
                                // close the session if they are not here.
                                if (string.IsNullOrEmpty(requestMessage["id"]) || string.IsNullOrEmpty(requestMessage["client"])) {
                                    return;
                                }
                                var isSync = requestMessage["async"].IsFalse();

                                if (isSync) {
                                    StartResponsePipeAndProcessMesages(requestMessage["client"], requestMessage["id"], serverPipe);
                                } else {
                                    Session.Start(requestMessage["client"], requestMessage["id"], serverPipe, serverPipe);
                                }
                            }).Wait();
                        }
                    }, _cancellationTokenSource.Token, TaskContinuationOptions.AttachedToParent, TaskScheduler.Current);
                }
            } catch /* (Exception e) */ {
                RequestStop();
            }
        }
Exemplo n.º 4
0
        private async Task ConnectToBrokerWorker() {
            Trace.Assert(_brokerProcess == null);

            string rhostBrokerExe = Path.Combine(_rhostDirectory, RHostBrokerExe);
            if (!_services.FileSystem.FileExists(rhostBrokerExe)) {
                throw new RHostBrokerBinaryMissingException();
            }

            Process process = null;
            try {
                string pipeName = Guid.NewGuid().ToString();

                using (var serverUriPipe = new NamedPipeServerStream(pipeName, PipeDirection.In)) {
                    var psi = new ProcessStartInfo {
                        FileName = rhostBrokerExe,
                        UseShellExecute = false,
                        Arguments =
                            $" --logging:logHostOutput {Log.LogVerbosity >= LogVerbosity.Normal}" +
                            $" --logging:logPackets {Log.LogVerbosity == LogVerbosity.Traffic}" +
                            $" --server.urls http://127.0.0.1:0" + // :0 means first available ephemeral port
                            $" --startup:name \"{Name}\"" +
                            $" --startup:writeServerUrlsToPipe {pipeName}" +
                            $" --lifetime:parentProcessId {Process.GetCurrentProcess().Id}" +
                            $" --security:secret \"{_credentials.Password}\"" +
                            $" --R:autoDetect false" +
                            $" --R:interpreters:{InterpreterId}:name \"{Name}\"" +
                            $" --R:interpreters:{InterpreterId}:basePath \"{_rHome.TrimTrailingSlash()}\""
                    };

                    if (!ShowConsole) {
                        psi.CreateNoWindow = true;
                    }

                    process = StartBroker(psi);
                    process.EnableRaisingEvents = true;

                    var cts = new CancellationTokenSource(100000);
                    process.Exited += delegate {
                        cts.Cancel();
                        _brokerProcess = null;
                        _connectLock.EnqueueReset();
                    };

                    await serverUriPipe.WaitForConnectionAsync(cts.Token);

                    var serverUriData = new MemoryStream();
                    try {
                        // Pipes are special in that a zero-length read is not an indicator of end-of-stream.
                        // Stream.CopyTo uses a zero-length read as indicator of end-of-stream, so it cannot 
                        // be used here. Instead, copy the data manually, using PipeStream.IsConnected to detect
                        // when the other side has finished writing and closed the pipe.
                        var buffer = new byte[0x1000];
                        do {
                            int count = await serverUriPipe.ReadAsync(buffer, 0, buffer.Length, cts.Token);
                            serverUriData.Write(buffer, 0, count);
                        } while (serverUriPipe.IsConnected);
                    } catch (OperationCanceledException) {
                        throw new RHostDisconnectedException("Timed out while waiting for broker process to report its endpoint URI");
                    }

                    string serverUriStr = Encoding.UTF8.GetString(serverUriData.ToArray());
                    Uri[] serverUri;
                    try {
                        serverUri = Json.DeserializeObject<Uri[]>(serverUriStr);
                    } catch (JsonSerializationException ex) {
                        throw new RHostDisconnectedException($"Invalid JSON for endpoint URIs received from broker ({ex.Message}): {serverUriStr}");
                    }
                    if (serverUri?.Length != 1) {
                        throw new RHostDisconnectedException($"Unexpected number of endpoint URIs received from broker: {serverUriStr}");
                    }

                    CreateHttpClient(serverUri[0]);
                }

                if (DisposableBag.TryAdd(DisposeBrokerProcess)) {
                    _brokerProcess = process;
                }
            } finally {
                if (_brokerProcess == null) {
                    try {
                        process?.Kill();
                    } catch (Exception) {
                    } finally {
                        process?.Dispose();
                    }
                }
            }
        }
Exemplo n.º 5
0
    public static async Task ClientCloneTests()
    {
        const string pipeName = "fooClientclone";

        byte[] msg1 = new byte[] { 5, 7, 9, 10 };
        byte[] received0 = new byte[] { };
        byte[] received1 = new byte[] { 0, 0, 0, 0 };

        using (NamedPipeServerStream server = new NamedPipeServerStream(pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte))
        using (NamedPipeClientStream clientBase = new NamedPipeClientStream(".", pipeName, PipeDirection.Out, PipeOptions.None))
        {
            await Task.WhenAll(server.WaitForConnectionAsync(), clientBase.ConnectAsync());

            using (NamedPipeClientStream client = new NamedPipeClientStream(PipeDirection.Out, false, true, clientBase.SafePipeHandle))
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    Assert.Equal(1, client.NumberOfServerInstances);
                }
                Assert.Equal(PipeTransmissionMode.Byte, client.TransmissionMode);

                Task clientTask = Task.Run(() => client.Write(msg1, 0, msg1.Length));
                int len1 = server.Read(received1, 0, msg1.Length);
                await clientTask;
                Assert.Equal(msg1.Length, len1);
                Assert.Equal(msg1, received1);

                // test special cases of buffer lengths = 0
                int len0 = server.Read(received0, 0, 0);
                Assert.Equal(0, len0);
                Assert.Equal(0, await server.ReadAsync(received0, 0, 0));
            }
        }
    }
Exemplo n.º 6
0
    public static async Task ServerPInvokeChecks()
    {
        // calling every API related to server and client to detect any bad PInvokes
        using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.Out))
        {
            Task clientTask = Task.Run(() => StartClient(PipeDirection.In));
            server.WaitForConnection();

            Assert.False(server.CanRead);
            Assert.False(server.CanSeek);
            Assert.False(server.CanTimeout);
            Assert.True(server.CanWrite);
            Assert.False(server.IsAsync);
            Assert.True(server.IsConnected);
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Equal(0, server.OutBufferSize);
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                Assert.True(server.OutBufferSize > 0);
            }
            else
            {
                Assert.Throws<PlatformNotSupportedException>(() => server.OutBufferSize);
            }
            Assert.Equal(PipeTransmissionMode.Byte, server.ReadMode);
            Assert.NotNull(server.SafePipeHandle);
            Assert.Equal(PipeTransmissionMode.Byte, server.TransmissionMode);

            server.Write(new byte[] { 123 }, 0, 1);
            await server.WriteAsync(new byte[] { 124 }, 0, 1);
            server.Flush();
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                server.WaitForPipeDrain();
            }
            else
            {
                Assert.Throws<PlatformNotSupportedException>(() => server.WaitForPipeDrain());
            }

            await clientTask;
        }

        using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.In))
        {
            Task clientTask = Task.Run(() => StartClient(PipeDirection.Out));
            server.WaitForConnection();

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Equal(0, server.InBufferSize);
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                Assert.True(server.InBufferSize > 0);
            }
            else
            {
                Assert.Throws<PlatformNotSupportedException>(() => server.InBufferSize);
            }
            byte[] readData = new byte[] { 0, 1 };
            Assert.Equal(1, server.Read(readData, 0, 1));
            Assert.Equal(1, server.ReadAsync(readData, 1, 1).Result);
            Assert.Equal(123, readData[0]);
            Assert.Equal(124, readData[1]);
        }
    }
Exemplo n.º 7
0
 //public void readFromNamedPipeStream(NamedPipeServerStream stream)
 //{
 //    discardProcessedData();
 //    //read if there's something to read and if we have available storage
 //    if (m_bytesInBuffer < m_maxChunkSize)
 //        m_bytesInBuffer += stream.Read(m_buffer, m_bytesInBuffer, m_maxChunkSize - m_bytesInBuffer);
 //}
 public async Task< int> readFromNamedPipeStreamAsync(NamedPipeServerStream stream,CancellationToken cancelToken)
 {
     int numBytesRead= 0;
     discardProcessedData();
     //read if there's something to read and if we have available storage
     if (m_bytesInBuffer < m_maxChunkSize)
     {
         try
         {
             numBytesRead = await stream.ReadAsync(m_buffer, m_bytesInBuffer, m_maxChunkSize - m_bytesInBuffer, cancelToken);
         }
         catch(OperationCanceledException)
         {
             logMessage("async read from pipe opeartion cancelled");
         }
         m_bytesInBuffer += numBytesRead;
     }
     return numBytesRead;
 }
Exemplo n.º 8
0
    public static void ClientCloneTests()
    {
        const string pipeName = "fooClientclone";
        
        byte[] msg1 = new byte[] { 5, 7, 9, 10 };
        byte[] received0 = new byte[] { };
        byte[] received1 = new byte[] { 0, 0, 0, 0 };

        using (NamedPipeServerStream server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte))
        {
            using (NamedPipeClientStream clientBase = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None))
            {
                Task clientTask = Task.Run(() =>
                {
                    clientBase.Connect();

                    using (NamedPipeClientStream client = new NamedPipeClientStream(PipeDirection.InOut, false, true, clientBase.SafePipeHandle))
                    {
                        client.Write(msg1, 0, msg1.Length);

                        int serverCount = client.NumberOfServerInstances;
                        Assert.Equal(1, serverCount);
                        Assert.Equal(PipeTransmissionMode.Byte, client.TransmissionMode);
                    }
                });

                server.WaitForConnection();
                int len1 = server.Read(received1, 0, msg1.Length);
                Assert.Equal(msg1.Length, len1);
                Assert.Equal(msg1, received1);

                // test special cases of buffer lengths = 0
                int len0 = server.Read(received0, 0, 0);
                Assert.Equal(0, len0);

                server.Write(received0, 0, 0);

                Task<int> serverTaskRead = server.ReadAsync(received0, 0, 0);
                serverTaskRead.Wait();
                Assert.Equal(0, serverTaskRead.Result);

                server.WriteAsync(received0, 0, 0).Wait();
            }
        }
    }
Exemplo n.º 9
0
    public static void ServerPInvokeChecks()
    {
        // calling every API related to server and client to detect any bad PInvokes
        using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.Out))
        {
            Task clientTask = StartClientAsync(PipeDirection.In);

            server.WaitForConnection();
            Console.WriteLine("server.CanRead = {0}", server.CanRead);
            Console.WriteLine("server.CanSeek = {0}", server.CanSeek);
            Console.WriteLine("server.CanTimeout = {0}", server.CanTimeout);
            Console.WriteLine("server.CanWrite = {0}", server.CanWrite);
            Console.WriteLine("server.IsAsync = {0}", server.IsAsync);
            Console.WriteLine("server.IsConnected = {0}", server.IsConnected);
            Console.WriteLine("server.OutBufferSize = {0}", server.OutBufferSize);
            Console.WriteLine("server.ReadMode = {0}", server.ReadMode);
            Console.WriteLine("server.SafePipeHandle = {0}", server.SafePipeHandle);
            Console.WriteLine("server.TransmissionMode = {0}", server.TransmissionMode);
            server.Write(new byte[] { 123 }, 0, 1);
            server.WriteAsync(new byte[] { 124 }, 0, 1).Wait();
            server.Flush();
            server.WaitForPipeDrain();
            clientTask.Wait();
        }
        using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.In))
        {
            Task clientTask = StartClientAsync(PipeDirection.Out);

            server.WaitForConnection();
            Console.WriteLine("server.InBufferSize = {0}", server.InBufferSize);
            byte[] readData = new byte[] { 0, 1 };
            server.Read(readData, 0, 1);
            server.ReadAsync(readData, 1, 1).Wait();
            Assert.Equal(123, readData[0]);
            Assert.Equal(124, readData[1]);
        }
    }