public Task SaveAsync(IMailWriteReference reference, CancellationToken token) { ((MockMailReference)reference).IsSaved = true; return(Task.CompletedTask); }
public override async Task ExecuteAsync(CancellationToken token) { if (string.IsNullOrEmpty(_builder.PendingMail?.FromPath?.Mailbox) || _builder.PendingMail?.Recipents?.Count == 0 || _builder.PendingMail?.IsBinary != true) { await _session.SendReplyAsync(SmtpReplyCode.BadSequence, "Bad sequence", token); return; } string[] parts = Arguments?.Split(' '); if (parts == null || parts.Length == 0 || parts.Length > 2) { await _session.SendReplyAsync(SmtpReplyCode.InvalidArguments, "Length required, optional LAST", token); return; } if (!int.TryParse(parts[0], out int length) || length < 1) { await _session.SendReplyAsync(SmtpReplyCode.InvalidArguments, "Length must be positive integer", token); return; } var last = false; if (parts.Length == 2) { if (!string.Equals("LAST", parts[1], StringComparison.OrdinalIgnoreCase)) { await _session.SendReplyAsync(SmtpReplyCode.InvalidArguments, "LAST expected", token); return; } last = true; } using (IMailWriteReference mailReference = await _mailQueue.NewMailAsync( _builder.PendingMail.FromPath.Mailbox, _builder.PendingMail.Recipents.ToImmutableList(), token)) { using (Stream mailStream = mailReference.BodyStream) { var chunk = new byte[1000]; var totalRead = 0; do { int toRead = Math.Min(chunk.Length, length - totalRead); int read = await _connection.ReadBytesAsync(chunk, 0, toRead, token); totalRead += read; await mailStream.WriteAsync(chunk, 0, read, token); } while (totalRead < length); } await _mailQueue.SaveAsync(mailReference, token); } await _session.SendReplyAsync(SmtpReplyCode.Okay, $"Recieved {length} octets", token); if (last) { _builder.PendingMail = null; await _session.SendReplyAsync(SmtpReplyCode.Okay, "Message complete", token); } }
public override async Task ExecuteAsync(CancellationToken token) { if (string.IsNullOrEmpty(_builder.PendingMail?.FromPath?.Mailbox) || _builder.PendingMail?.Recipents?.Count == 0 || _builder.PendingMail?.IsBinary == true) { await _channel.SendReplyAsync(SmtpReplyCode.BadSequence, "Bad sequence", token); return; } await _channel.SendReplyAsync(SmtpReplyCode.StartMail, "Send data, end with .<CR><LF>", token); var rejected = false; using (IMailWriteReference reference = await _mailQueue.NewMailAsync( _builder.PendingMail.FromPath.Mailbox, _builder.PendingMail.Recipents.ToImmutableList(), token)) { using (var mailWriter = new StreamWriter(reference.BodyStream, new UTF8Encoding(false))) { await mailWriter.WriteLineAsync( $"Received: FROM {_channel.ConnectedHost} ({_connectionInformation.RemoteAddress}) BY {_settings.DomainName} ({_connectionInformation.LocalAddress}); {DateTime.UtcNow:ddd, dd MMM yyy HH:mm:ss zzzz}"); string line; while ((line = await _reader.ReadLineAsync(Encoding.UTF8, token)) != ".") { if (!rejected && !_channel.IsAuthenticated && _settings.UnauthenticatedMessageSizeLimit != 0 && _settings.UnauthenticatedMessageSizeLimit <= mailWriter.BaseStream.Length) { await _channel.SendReplyAsync(SmtpReplyCode.ExceededQuota, "Message rejected, too large", token); mailWriter.Dispose(); reference.Dispose(); rejected = true; } if (rejected) { continue; } await mailWriter.WriteLineAsync(line); await mailWriter.FlushAsync(); } } if (!rejected) { await _mailQueue.SaveAsync(reference, token); } } _builder.PendingMail = null; if (!rejected) { await _channel.SendReplyAsync(SmtpReplyCode.Okay, "OK", token); } }