public async Task <string[]> DirAsync(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentException("invalid path", nameof(path));
            }

            var payload       = path.ToNullTerminatedBytes();
            var messageheader = new ClientMessageHeader(MessageTypes.Dir, ControlFlags.Default, payload);

            return(await InternalDirAsync(payload, messageheader));
        }
        public async Task SendAsync(ClientMessageHeader header, byte[] payload, CancellationToken token = default)
        {
            if (!Connected)
            {
                throw new InvalidOperationException("Cannot send. No open connection!");
            }
            var buffer = header.ToByteArray();
            await _stream.WriteAsync(buffer, 0, buffer.Length, token);

            if (payload != null && payload.Length > 0)
            {
                await _stream.WriteAsync(payload, 0, payload.Length, token);
            }
            await _stream.FlushAsync(token);
        }
        private async Task <byte[]> InternalReadRawAsync(string path, uint datalen)
        {
            await _connection.ConnectAsync();

            var payload       = path.ToNullTerminatedBytes();
            var messageheader = new ClientMessageHeader(MessageTypes.Read, ControlFlags.Default, payload, datalen);
            await _connection.SendAsync(messageheader, payload);

            var result = await _connection.ReceiveAsync();

            await _connection.DisconnectAsync();

            if (result.Payload != null && result.Payload.Length > 0)
            {
                var value = result.Payload.FromNullTerminatedBytes();
            }
            return(result.Payload);
        }
        private async Task <string[]> InternalDirAsync(byte[] payload, ClientMessageHeader messageheader)
        {
            await _connection.ConnectAsync();

            await _connection.SendAsync(messageheader, payload);

            var result = await _connection.ReceiveAsync();

            await _connection.DisconnectAsync();

            if (result.Payload != null && result.Payload.Length > 0)
            {
                var value   = result.Payload.FromNullTerminatedBytes();
                var folders = value.Split(',');
                return(folders);
            }
            return(new string[0]);
        }
        private static ClientMessageHeader ParseClientMessage(Stream clientStream)
        {
            var streamReader = new StreamReader(clientStream);
            {
                clientStream.Position = 0;

                var httpCmd = String.Empty;

                for (var i = 0; i < 10; i++)
                {
                    httpCmd = streamReader.ReadLine();

                    if (String.IsNullOrEmpty(httpCmd))
                    {
                        continue;
                    }
                    if (httpCmd.Count(c => c.Equals(' ')) >= 2)
                    {
                        break;
                    }
                }

                if (String.IsNullOrEmpty(httpCmd))
                {
                    return null;
                }

                var splitBuffer = httpCmd.Split(new[] { ' ' }, 3);

                var method = splitBuffer[0];
                var remoteUri = splitBuffer[1];
                if (method.Equals("CONNECT", StringComparison.InvariantCultureIgnoreCase))
                {
                    remoteUri = "https://" + remoteUri;
                }
                var protocollVersion = splitBuffer[2];

                splitBuffer = protocollVersion.Split(new[] { '/' }, 2);
                var protocol = splitBuffer[0];
                var version = splitBuffer[1];

                var headers = new Dictionary<string, string>();
                while (true)
                {
                    var headerline = streamReader.ReadLine();
                    if (String.IsNullOrEmpty(headerline))
                    {
                        break;
                    }

                    var lineBuffer = headerline.Split(new[] { ':' }, 2);
                    var key = lineBuffer[0].Trim();
                    var value = lineBuffer[1].Trim();
                    headers.TryAdd(key, value);
                }

                if (remoteUri.StartsWith("/"))
                {
                    remoteUri = string.Format("https://{0}{1}", headers["Host"], remoteUri);
                }

                var message = new ClientMessageHeader
                {
                    Method = method,
                    RemoteUri = new Uri(remoteUri),
                    Protocol = protocol,
                    ProtocolVersion = Version.Parse(version),
                    Headers = headers
                };

                clientStream.Position = 0;

                return message;
            }
        }