Exemplo n.º 1
0
        private static async Task PongServer(IPipeConnection connection)
        {
            while (true)
            {
                var result = await connection.Input.ReadAsync();

                var inputBuffer = result.Buffer;

                if (inputBuffer.IsEmpty && result.IsCompleted)
                {
                    connection.Input.Advance(inputBuffer.End);
                    break;
                }

                if (inputBuffer.Length < 4)
                {
                    connection.Input.Advance(inputBuffer.Start, inputBuffer.End);
                }
                else
                {
                    bool isPing = inputBuffer.Equals(_ping);
                    if (isPing)
                    {
                        await connection.Output.WriteAsync(_pong);
                    }
                    else
                    {
                        break;
                    }

                    connection.Input.Advance(inputBuffer.End);
                }
            }
        }
Exemplo n.º 2
0
    static async Task DoTheThingViaPipelines(string host, int port, string password, bool useTls, string certificateFile)
    {
        try
        {
            await Console.Out.WriteLineAsync(ShowDetails?$"resolving ip of '{host}'..." : "resolving ip of host");

            var ip = (await Dns.GetHostAddressesAsync(host)).First();

            await Console.Out.WriteLineAsync(ShowDetails?$"connecting to '{ip}:{port}'..." : "connecting to host");

            using (var socket = await SocketConnection.ConnectAsync(new IPEndPoint(ip, port)))
            {
                IPipeConnection connection = socket;
                if (useTls) // need to think about the disposal story here?
                {
                    connection = await Leto.TlsPipeline.AuthenticateClient(connection, new Leto.ClientOptions()
                    {
                        CertificateFile = certificateFile
                    });
                }
                await ExecuteWithTimeout(connection, password);
            }
        }
        catch (Exception ex)
        {
            await Console.Error.WriteLineAsync(ex.Message);
        }
    }
Exemplo n.º 3
0
        private static async Task WriteChunkedBody(this IPipeConnection connection, HttpContext context)
        {
            while (true)
            {
                var buffer = connection.Output.Alloc();
                try
                {
                    buffer.Ensure(1024);
                    var bookMark = buffer.Memory;
                    buffer.Advance(3);
                    buffer.Write(HttpConsts.EndOfLine);
                    if (!buffer.Memory.TryGetArray(out ArraySegment <byte> byteArray))
                    {
                        throw new NotImplementedException();
                    }
                    var bytesWritten = await context.Request.Body.ReadAsync(byteArray.Array, byteArray.Offset, byteArray.Count);

                    if (bytesWritten == 0)
                    {
                        Encoding.ASCII.GetBytes("000").CopyTo(bookMark.Span);
                        buffer.Write(HttpConsts.EndOfLine);
                        return;
                    }
                    Encoding.ASCII.GetBytes($"{bytesWritten:XXX}").CopyTo(bookMark.Span);
                    buffer.Advance(bytesWritten);
                    buffer.Write(HttpConsts.EndOfLine);
                }
                finally
                {
                    await buffer.FlushAsync();
                }
            }
        }
 public RedisConnection(IPipeConnection connection, IPEndPoint serverEndpoint, int database)
 {
     _connection        = connection;
     Database           = database;
     ServerEndPoint     = serverEndpoint;
     IsDatabaseSelected = false;
 }
Exemplo n.º 5
0
    private static async Task Execute(IPipeConnection connection, string password)
    {
        await Console.Out.WriteLineAsync($"executing...");

        if (password != null)
        {
            await WriteSimpleMessage(connection.Output, $"AUTH \"{password}\"");

            // a "success" for this would be a response that says "+OK"
        }

        await WriteSimpleMessage(connection.Output, "ECHO \"noisy in here\"");

        // note that because of RESP, this actually gives 2 replies; don't worry about it :)

        await WriteSimpleMessage(connection.Output, "PING");


        var input = connection.Input;

        while (true)
        {
            await Console.Out.WriteLineAsync($"awaiting response...");

            var result = await input.ReadAsync();

            await Console.Out.WriteLineAsync($"checking response...");

            var buffer = result.Buffer;

            if (buffer.IsEmpty && result.IsCompleted)
            {
                await Console.Out.WriteLineAsync($"done");

                break;
            }

            if (!buffer.TrySliceTo((byte)'\r', (byte)'\n', out var slice, out var cursor))
            {
                await Console.Out.WriteLineAsync($"incomplete");

                input.Advance(buffer.Start, buffer.End);
                continue;
            }
            var reply = slice.GetAsciiString();
            await Console.Out.WriteLineAsync($"<< received: '{reply}'");

            if (string.Equals(reply, "+PONG", StringComparison.OrdinalIgnoreCase))
            {
                await WriteSimpleMessage(connection.Output, "QUIT");

                connection.Output.Complete();
            }

            // input.Advance(cursor); // feels like this should work, but it doesn't
            var incTerminator = buffer.Slice(0, slice.Length + 2);
            input.Advance(incTerminator.End, incTerminator.End);
        }
    }
Exemplo n.º 6
0
        static async Task <Tuple <int, int, int> > PingClient(IPipeConnection connection, int messagesToSend)
        {
            ArraySegment <byte> _ping = new ArraySegment <byte>(Encoding.ASCII.GetBytes("PING"));
            ArraySegment <byte> _pong = new ArraySegment <byte>(Encoding.ASCII.GetBytes("PING"));

            int count = 0;
            var watch = Stopwatch.StartNew();
            int sendCount = 0, replyCount = 0;

            for (int i = 0; i < messagesToSend; i++)
            {
                await connection.Output.WriteAsync(_ping);

                sendCount++;

                bool havePong = false;
                while (true)
                {
                    var result = await connection.Input.ReadAsync();

                    var inputBuffer = result.Buffer;

                    if (inputBuffer.IsEmpty && result.IsCompleted)
                    {
                        connection.Input.Advance(inputBuffer.End);
                        break;
                    }
                    if (inputBuffer.Length < 4)
                    {
                        connection.Input.Advance(inputBuffer.Start, inputBuffer.End);
                    }
                    else
                    {
                        havePong = inputBuffer.EqualsTo(_ping);
                        if (havePong)
                        {
                            count++;
                        }
                        connection.Input.Advance(inputBuffer.End);
                        break;
                    }
                }

                if (havePong)
                {
                    replyCount++;
                }
                else
                {
                    break;
                }
            }
            connection.Input.Complete();
            connection.Output.Complete();
            watch.Stop();

            // Task.Run here so that we're not on the UV thread when we complete
            return(await Task.Run(() => Tuple.Create(sendCount, replyCount, (int)watch.ElapsedMilliseconds)));
        }
Exemplo n.º 7
0
    private static async Task ExecuteWithTimeout(IPipeConnection connection, string password, int timeoutMilliseconds = 5000)
    {
        var timeout = Task.Delay(timeoutMilliseconds);
        var success = Execute(connection, password);
        var winner  = await Task.WhenAny(success, timeout);

        await Console.Out.WriteLineAsync(winner == success? "(complete)" : "(timeout)");
    }
Exemplo n.º 8
0
        public IAppSession Create(IPipeConnection pipeConnection)
        {
            var session = new AppSession <TPackageInfo>(new TPipelineFilter());

            session.Initialize(pipeConnection);
            session.PackageReceived += _packageHandler;
            return(session);
        }
Exemplo n.º 9
0
        public LoopbackPipeline(PipeOptions factory)
        {
            var backPipeline1 = new Pipe(factory);
            var backPipeline2 = new Pipe(factory);

            _clientPipeline = new TestPipeline(backPipeline1, backPipeline2);
            _serverPipeline = new TestPipeline(backPipeline2, backPipeline1);
        }
Exemplo n.º 10
0
        public static async Task <TlsClientPipeline> AuthenticateClient(IPipeConnection inputPipe, ClientOptions clientOptions)
        {
            var ctx      = Interop.OpenSsl.SSL_CTX_new(Interop.OpenSsl.TLS_client_method());
            var pipeline = new TlsClientPipeline(inputPipe, ctx, clientOptions);
            await pipeline.AuthenticateAsync();

            return(pipeline);
        }
Exemplo n.º 11
0
        public LoopbackPipeline(PipeFactory factory)
        {
            var backPipeline1 = factory.Create();
            var backPipeline2 = factory.Create();

            _clientPipeline = new TestPipeline(backPipeline1, backPipeline2);
            _serverPipeline = new TestPipeline(backPipeline2, backPipeline1);
        }
        private async Task OnConnection(IPipeConnection connection)
        {
            using (connection)
            {
                WebSocketConnection socket = null;
                try
                {
                    WriteStatus(ConnectionType.Server, "Connected");

                    WriteStatus(ConnectionType.Server, "Parsing http request...");
                    var request = await ParseHttpRequest(connection.Input);

                    try
                    {
                        WriteStatus(ConnectionType.Server, "Identifying protocol...");
                        socket = GetProtocol(connection, ref request);
                        WriteStatus(ConnectionType.Server, $"Protocol: {WebSocketProtocol.Name}");
                        WriteStatus(ConnectionType.Server, "Authenticating...");
                        if (!await OnAuthenticateAsync(socket, ref request.Headers))
                        {
                            throw new InvalidOperationException("Authentication refused");
                        }
                        WriteStatus(ConnectionType.Server, "Completing handshake...");
                        await WebSocketProtocol.CompleteServerHandshakeAsync(ref request, socket);
                    }
                    finally
                    {
                        request.Dispose(); // can't use "ref request" or "ref headers" otherwise
                    }
                    WriteStatus(ConnectionType.Server, "Handshake complete hook...");
                    await OnHandshakeCompleteAsync(socket);

                    connections.TryAdd(socket, socket);
                    WriteStatus(ConnectionType.Server, "Processing incoming frames...");
                    await socket.ProcessIncomingFramesAsync(this);

                    WriteStatus(ConnectionType.Server, "Exiting...");
                    await socket.CloseAsync();
                }
                catch (Exception ex)
                {// meh, bye bye broken connection
                    try { socket?.Dispose(); } catch { }
                    WriteStatus(ConnectionType.Server, ex.StackTrace);
                    WriteStatus(ConnectionType.Server, ex.GetType().Name);
                    WriteStatus(ConnectionType.Server, ex.Message);
                }
                finally
                {
                    WebSocketConnection tmp;
                    if (socket != null)
                    {
                        connections.TryRemove(socket, out tmp);
                    }
                    try { connection.Output.Complete(); } catch { }
                    try { connection.Input.Complete(); } catch { }
                }
            }
        }
Exemplo n.º 13
0
        private Task HandleNewClient(IPipeConnection connection)
        {
            Interlocked.Increment(ref _sessionCount);
            var session = _appSessionFactory.Create(connection);

            session.Closed += OnSessionClosed;
            Task.Run(async() => await ProcessRequest(session));
            return(Task.CompletedTask);
        }
Exemplo n.º 14
0
 public AdaptedPipeline(IPipeConnection transport,
                        IPipeConnection application,
                        IPipe inputPipe,
                        IPipe outputPipe)
 {
     _transport   = transport;
     _application = application;
     Input        = inputPipe;
     Output       = outputPipe;
 }
Exemplo n.º 15
0
        static async Task <Tuple <int, int, int> > PingClient(IPipeConnection connection, int messagesToSend)
        {
            int count = 0;
            var watch = Stopwatch.StartNew();
            int sendCount = 0, replyCount = 0;

            for (int i = 0; i < messagesToSend; i++)
            {
                await connection.Output.WriteAsync(_ping);

                sendCount++;

                bool havePong = false;
                while (true)
                {
                    var result = await connection.Input.ReadAsync();

                    var inputBuffer = result.Buffer;

                    if (inputBuffer.IsEmpty && result.IsCompleted)
                    {
                        connection.Input.Advance(inputBuffer.End);
                        break;
                    }
                    if (inputBuffer.Length < 4)
                    {
                        connection.Input.Advance(inputBuffer.Start, inputBuffer.End);
                    }
                    else
                    {
                        havePong = inputBuffer.Equals(_ping);
                        if (havePong)
                        {
                            count++;
                        }
                        connection.Input.Advance(inputBuffer.End);
                        break;
                    }
                }

                if (havePong)
                {
                    replyCount++;
                }
                else
                {
                    break;
                }
            }
            connection.Input.Complete();
            connection.Output.Complete();
            watch.Stop();

            return(Tuple.Create(sendCount, replyCount, (int)watch.ElapsedMilliseconds));
        }
Exemplo n.º 16
0
 public SecurePipelineConnection(IPipeConnection pipeline, PipeFactory factory, SecurePipeListener listener, ILogger <SecurePipelineConnection> logger)
 {
     _logger          = logger;
     _listener        = listener;
     _lowerConnection = pipeline;
     _outputPipe      = factory.Create();
     _inputPipe       = factory.Create();
     _handshakePipe   = factory.Create();
     _state           = new ServerStateTls12(_listener, _logger);
     StartReading();
 }
Exemplo n.º 17
0
 public void Dispose()
 {
     lock (_lock)
     {
         _logger?.LogTrace("Disposed connection");
         _lowerConnection?.Dispose();
         _state?.Dispose();
         _lowerConnection = null;
         _state           = null;
         GC.SuppressFinalize(this);
     }
 }
Exemplo n.º 18
0
 public static Task WriteBodyAsync(this IPipeConnection connection, HttpContext context)
 {
     if (context.Request.Headers["Transfer-Encoding"] == "chunked")
     {
         return(connection.WriteChunkedBody(context));
     }
     if (context.Request.ContentLength > 0)
     {
         return(connection.WriteBody(context));
     }
     return(_cachedTask);
 }
Exemplo n.º 19
0
 private Http2Connection CreateHttp2Connection(IPipeConnection transport, IPipeConnection application)
 {
     return(new Http2Connection(new Http2ConnectionContext
     {
         ConnectionId = _context.ConnectionId,
         ServiceContext = _context.ServiceContext,
         ConnectionFeatures = _context.ConnectionFeatures,
         MemoryPool = MemoryPool,
         LocalEndPoint = LocalEndPoint,
         RemoteEndPoint = RemoteEndPoint,
         Application = application,
         Transport = transport
     }));
 }
Exemplo n.º 20
0
 internal SecurePipeConnection(IPipeConnection connection, SecurePipeOptions securePipeOptions, IConnectionState connectionState)
 {
     RecordHandler      = new GeneralRecordHandler(null, TlsVersion.Tls1, connection.Output);
     _securePipeOptions = securePipeOptions;
     _inputPipe         = new Pipe(securePipeOptions.PipeOptions);
     _outputPipe        = new Pipe(securePipeOptions.PipeOptions);
     _connection        = connection;
     _state             = connectionState;
     _state.Connection  = this;
     _handshakeInput    = new Pipe(securePipeOptions.PipeOptions);
     _handshakeOutput   = new Pipe(securePipeOptions.PipeOptions);
     RecordHandler      = new GeneralRecordHandler(_state, TlsVersion.Tls12, _connection.Output);
     var ignore = ReadingLoop();
 }
 private Http1Connection CreateHttp1Connection(IPipeConnection transport, IPipeConnection application)
 {
     return(new Http1Connection(new Http1ConnectionContext
     {
         ConnectionId = _context.ConnectionId,
         ConnectionFeatures = _context.ConnectionFeatures,
         BufferPool = BufferPool,
         LocalEndPoint = LocalEndPoint,
         RemoteEndPoint = RemoteEndPoint,
         ServiceContext = _context.ServiceContext,
         TimeoutControl = this,
         Transport = transport,
         Application = application
     }));
 }
Exemplo n.º 22
0
        internal TlsClientPipeline(IPipeConnection inputPipe, SSL_CTX context, ClientOptions clientOptions)
        {
            _innerConnection = inputPipe;
            _readInnerPipe   = new Pipe(new PipeOptions(System.Buffers.MemoryPool.Default));
            _writeInnerPipe  = new Pipe(new PipeOptions(System.Buffers.MemoryPool.Default));
            _context         = context;
            _ssl             = SSL_new(_context);

            _clientOptions = clientOptions;

            _readBio  = s_ReadBio.New();
            _writeBio = s_WriteBio.New();
            SSL_set0_rbio(_ssl, _readBio);
            SSL_set0_wbio(_ssl, _writeBio);
            SSL_set_connect_state(_ssl);
        }
Exemplo n.º 23
0
        private static async Task WriteBody(this IPipeConnection connection, HttpContext context)
        {
            var bytesToWrite = context.Request.ContentLength.Value;

            while (bytesToWrite > 0)
            {
                var buffer = connection.Output.Alloc(1024);
                if (!buffer.Memory.TryGetArray(out ArraySegment <byte> byteArray))
                {
                    throw new NotImplementedException();
                }
                var byteCount = await context.Request.Body.ReadAsync(byteArray.Array, byteArray.Offset, byteArray.Count);

                buffer.Advance(byteCount);
                bytesToWrite -= byteCount;
                await buffer.FlushAsync();
            }
        }
Exemplo n.º 24
0
        public static async Task ReceiveHeaderAsync(this IPipeConnection connection, HttpContext context)
        {
            var finished = false;

            while (true)
            {
                var reader = await connection.Input.ReadAsync();

                var buffer = reader.Buffer;
                try
                {
                    if (!buffer.TrySliceTo(HttpConsts.HeadersEnd, out ReadableBuffer currentSlice, out ReadCursor cursor))
                    {
                        continue;
                    }
                    buffer = buffer.Slice(cursor).Slice(HttpConsts.HeadersEnd.Length);
                    //first line
                    if (!currentSlice.TrySliceTo(HttpConsts.EndOfLine, out ReadableBuffer currentLine, out cursor))
                    {
                        throw new InvalidOperationException();
                    }
                    context.Response.StatusCode = int.Parse(currentLine.Split(HttpConsts.Space[0]).Skip(1).First().GetAsciiString());
                    currentSlice = currentSlice.Slice(cursor).Slice(HttpConsts.EndOfLine.Length);

                    while (currentSlice.Length > 0)
                    {
                        cursor = ProcessHeader(context, ref currentSlice);
                    }
                    finished = true;
                    return;
                }
                finally
                {
                    if (finished)
                    {
                        connection.Input.Advance(buffer.Start, buffer.Start);
                    }
                    else
                    {
                        connection.Input.Advance(buffer.Start, buffer.End);
                    }
                }
            }
        }
Exemplo n.º 25
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="name"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task InitializeAsync(string name, CancellationToken cancellationToken = default)
        {
            if (IsFactory)
            {
                var client = CreateClient <Message>(name);
                client.MessageReceived += (_, args) =>
                {
                    if (args.Message == null)
                    {
                        OnExceptionOccurred(new InvalidOperationException("Received null message from server."));
                        return;
                    }

                    OnMessageReceived(args.Message);
                };
                client.ExceptionOccurred += (_, args) => OnExceptionOccurred(args.Exception);

                await client.ConnectAsync(cancellationToken).ConfigureAwait(false);

                InternalConnection = client;
            }
            else
            {
                var server = CreateServer <Message>(name);
                server.MessageReceived += (_, args) =>
                {
                    if (args.Message == null)
                    {
                        OnExceptionOccurred(new InvalidOperationException("Received null message from client."));
                        return;
                    }

                    OnMessageReceived(args.Message);
                };
                server.ExceptionOccurred += (_, args) => OnExceptionOccurred(args.Exception);

                await server.StartAsync(cancellationToken);

                InternalConnection = server;
            }
        }
Exemplo n.º 26
0
        private async Task Echo(IPipeConnection connection)
        {
            while (true)
            {
                var result = await connection.Input.ReadAsync();

                var request = result.Buffer;

                if (request.IsEmpty && result.IsCompleted)
                {
                    connection.Input.Advance(request.End);
                    break;
                }

                var response = connection.Output.Alloc();
                response.Append(request);
                await response.FlushAsync();

                connection.Input.Advance(request.End);
            }
        }
Exemplo n.º 27
0
        public Http1ConnectionTests()
        {
            _pipelineFactory = new MemoryPool();
            var pair = PipeFactory.CreateConnectionPair(_pipelineFactory);

            _transport   = pair.Transport;
            _application = pair.Application;

            _serviceContext         = new TestServiceContext();
            _timeoutControl         = new Mock <ITimeoutControl>();
            _http1ConnectionContext = new Http1ConnectionContext
            {
                ServiceContext     = _serviceContext,
                ConnectionFeatures = new FeatureCollection(),
                MemoryPool         = _pipelineFactory,
                TimeoutControl     = _timeoutControl.Object,
                Application        = pair.Application,
                Transport          = pair.Transport
            };

            _http1Connection = new TestHttp1Connection(_http1ConnectionContext);
            _http1Connection.Reset();
        }
Exemplo n.º 28
0
        private static async Task Handle(IPipeConnection connection)
        {
            while (true)
            {
                var result = await connection.Input.ReadAsync();

                var request = result.Buffer;

                if (request.IsEmpty && result.IsCompleted)
                {
                    connection.Input.Advance(request.End);
                    break;
                }

                Console.Out.WriteLine(request.GetUtf8String());

                var response = connection.Output.Alloc();
                response.Append(request);
                await response.FlushAsync();

                connection.Input.Advance(request.End);
            }
        }
Exemplo n.º 29
0
        private static async Task PongServer(IPipeConnection connection)
        {
            ArraySegment <byte> _ping = new ArraySegment <byte>(Encoding.ASCII.GetBytes("PING"));
            ArraySegment <byte> _pong = new ArraySegment <byte>(Encoding.ASCII.GetBytes("PING"));

            while (true)
            {
                var result = await connection.Input.ReadAsync();

                var inputBuffer = result.Buffer;

                if (inputBuffer.IsEmpty && result.IsCompleted)
                {
                    connection.Input.Advance(inputBuffer.End);
                    break;
                }

                if (inputBuffer.Length < 4)
                {
                    connection.Input.Advance(inputBuffer.Start, inputBuffer.End);
                }
                else
                {
                    bool isPing = inputBuffer.EqualsTo(_ping);
                    if (isPing)
                    {
                        await connection.Output.WriteAsync(_pong);
                    }
                    else
                    {
                        break;
                    }

                    connection.Input.Advance(inputBuffer.End);
                }
            }
        }
Exemplo n.º 30
0
        public static WritableBufferAwaitable WriteHeadersAsync(this IPipeConnection connection, HttpContext context, byte[] host)
        {
            var writer = connection.Output.Alloc();

            writer.Append(context.Request.Method, TextEncoder.Utf8);
            writer.Write(HttpConsts.Space);
            writer.Append(context.Request.Path.Value, TextEncoder.Utf8);
            writer.Write(HttpConsts.Space);
            writer.Append(context.Request.Protocol, TextEncoder.Utf8);
            writer.Write(HttpConsts.EndOfLine);
            foreach (var header in context.Request.Headers)
            {
                if (header.Key == "Host" || header.Key == "Connection")
                {
                }
                writer.Append(header.Key, TextEncoder.Utf8);
                writer.Write(HttpConsts.HeaderSplit);
                writer.Append(string.Join(", ", header.Value), TextEncoder.Utf8);
                writer.Write(HttpConsts.EndOfLine);
            }
            writer.Write(host);
            writer.Write(HttpConsts.ConnectionHeaderBytes);
            return(writer.FlushAsync());
        }