Example #1
0
 public static Task WriteStatusAsync(this ImapStream stream, string status, string message)
 {
     return(stream.WriteLineAsync(status + " " + message));
 }
Example #2
0
        /// <summary>
        /// https://tools.ietf.org/html/rfc3501#section-2.2.1
        /// https://tools.ietf.org/html/rfc3501#section-4.3
        /// </summary>
        public static async Task <CommandLine> ReadCommandAsync(this ImapStream stream)
        {
            var line = await stream.ReadLineAsync();

            while (String.IsNullOrEmpty(line))
            {
                await stream.WriteLineAsync("* BAD Empty command line");

                line = await stream.ReadLineAsync();
            }

            var spl = line.Split(new char[] { ' ' }, 3);

            // No command name
            if (spl.Length < 2)
            {
                return(null);
            }

            var result = new CommandLine
            {
                Tag  = spl[0],
                Name = spl[1].ToUpperInvariant()
            };

            // No argument
            if (spl.Length < 3)
            {
                return(result);
            }

            // Rest part as default argument
            result.Args = spl[2];

            // APPEND is special to handle later
            if (result.Name == "APPEND")
            {
                return(result);
            }

            var partialArgs = ArgumentUtility.Parse(result.Args);

            // One line command
            if (partialArgs.Size == null)
            {
                return(result);
            }

            /* Continous command
             * R <tag> <command> <partial argument>{<continue size>}
             * W + Continue.
             * R ...
             * R <partial argument>{<continue size>}
             * W + Continue.
             * R ...
             * R <end argument>
             */
            var builder = new StringBuilder();

            while (partialArgs.Size != null)
            {
                builder.Append(partialArgs.Args);

                await stream.WriteLineAsync("+ Continue.");

                // Read bytes secified by literal {size}
                var bytes = await stream.ReadAsync(partialArgs.Size.Value);

                builder.Append(TextUtils.QuoteString(Encoding.UTF8.GetString(bytes)));

                // Try to read last line
                line = await stream.ReadLineAsync();

                partialArgs = ArgumentUtility.Parse(line);
            }

            builder.Append(partialArgs.Args);
            result.Args = builder.ToString();

            return(result);
        }