Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Src/SmtpServer/ISmtpServerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,12 @@ public interface ISmtpServerOptions
/// The size of the buffer that is read from each call to the underlying network client.
/// </summary>
int NetworkBufferSize { get; }

/// <summary>
/// Gets the custom greeting message sent by the server in response to the initial SMTP connection.
/// This message is returned after the client connects and before any commands are issued (e.g., "220 mail.example.com v1.0 ESMTP ready").
/// If not set, a default greeting will be used.
/// </summary>
string CustomGreetingMessage { get; }
}
}
23 changes: 22 additions & 1 deletion Src/SmtpServer/SmtpServerOptionsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public ISmtpServerOptions Build()
MaxRetryCount = 5,
MaxAuthenticationAttempts = 3,
NetworkBufferSize = 128,
CommandWaitTimeout = TimeSpan.FromMinutes(5)
CommandWaitTimeout = TimeSpan.FromMinutes(5),
CustomGreetingMessage = null
};

_setters.ForEach(setter => setter(serverOptions));
Expand Down Expand Up @@ -155,6 +156,19 @@ public SmtpServerOptionsBuilder CommandWaitTimeout(TimeSpan value)
return this;
}

/// <summary>
/// Sets the custom SMTP greeting message sent to the client upon connection,
/// typically returned as the initial "220" response.
/// </summary>
/// <param name="value">The greeting message to send to the client (e.g., "220 mail.example.com v1.0 ESMTP ready").</param>
/// <returns>An OptionsBuilder to continue building on.</returns>
public SmtpServerOptionsBuilder CustomGreetingMessage(string value)
{
_setters.Add(options => options.CustomGreetingMessage = value);

return this;
}

#region SmtpServerOptions

class SmtpServerOptions : ISmtpServerOptions
Expand Down Expand Up @@ -198,6 +212,13 @@ class SmtpServerOptions : ISmtpServerOptions
/// The size of the buffer that is read from each call to the underlying network client.
/// </summary>
public int NetworkBufferSize { get; set; }

/// <summary>
/// Gets or sets the custom greeting message sent by the server in response to the initial SMTP connection.
/// This message is returned after the client connects and before any commands are issued (e.g., "220 mail.example.com v1.0 ESMTP ready").
/// If not set, a default greeting will be used.
/// </summary>
public string CustomGreetingMessage { get; set; }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this should actually be something like

Func<ISmtpContext, string> CustomGreetingMessage

which would give the ability to make the message dynamic?

}

#endregion
Expand Down
27 changes: 17 additions & 10 deletions Src/SmtpServer/SmtpSession.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using SmtpServer.Protocol;
using System.Reflection;
using SmtpServer.ComponentModel;
using SmtpServer.IO;
using System.IO.Pipelines;
using SmtpServer.Protocol;
using SmtpServer.StateMachine;
using SmtpServer.ComponentModel;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO.Pipelines;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace SmtpServer
{
internal sealed class SmtpSession
{
const string BufferKey = "SmtpSession:Buffer";
static readonly Version AssemblyVersion = typeof(SmtpSession).GetTypeInfo().Assembly.GetName().Version;

readonly SmtpStateMachine _stateMachine;
readonly SmtpSessionContext _context;
Expand Down Expand Up @@ -187,9 +188,15 @@ static async Task<bool> ExecuteAsync(SmtpCommand command, SmtpSessionContext con
/// <returns>A task which performs the operation.</returns>
ValueTask<FlushResult> OutputGreetingAsync(CancellationToken cancellationToken)
{
var version = typeof(SmtpSession).GetTypeInfo().Assembly.GetName().Version;

_context.Pipe.Output.WriteLine($"220 {_context.ServerOptions.ServerName} v{version} ESMTP ready");
if (_context.ServerOptions.CustomGreetingMessage is null)
{
var serverVersion = AssemblyVersion;
_context.Pipe.Output.WriteLine($"220 {_context.ServerOptions.ServerName} v{serverVersion} ESMTP ready");
}
else
{
_context.Pipe.Output.WriteLine($"220 {_context.ServerOptions.ServerName} {_context.ServerOptions.CustomGreetingMessage}");
}

return _context.Pipe.Output.FlushAsync(cancellationToken);
}
Expand Down
Loading