89 lines
3.8 KiB
C#
89 lines
3.8 KiB
C#
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using e_suite.Service.Mail.Helper;
|
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
|
|
|
namespace eSuite.API.HealthChecks;
|
|
|
|
/// <summary>
|
|
/// Health check used to perform a basic check to see that the smtp server is available.
|
|
/// </summary>
|
|
public class SmtpHealthCheck
|
|
{
|
|
/// <summary>
|
|
/// Returns Health check result for if the smtp server is up and available to connect too.
|
|
/// </summary>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="socketFactory"></param>
|
|
/// <returns></returns>
|
|
public static HealthCheckResult Healthy(IConfiguration configuration, ISocketFactory socketFactory)
|
|
{
|
|
//failure to be able to send an email should result in degraded.
|
|
|
|
var host = configuration.GetConfigValue("MAIL_SERVER", "Smtp:Server", "defaultmailserver");
|
|
var port = configuration.GetConfigValue("MAIL_PORT", "Smtp:Port", 25);
|
|
//var fromAddress = configuration.GetConfigValue("MAIL_ADDRESS", "Smtp:FromAddress", "defaultfromaddress");
|
|
//var fromDisplayName = configuration.GetConfigValue("MAIL_NAME", "Smtp:FromDisplayName", "MailService");
|
|
//var username = configuration.GetConfigValue("MAIL_USERNAME", "Smtp:Username", string.Empty);
|
|
//var password = configuration.GetConfigValue("MAIL_PASSWORD", "Smtp:Password", string.Empty);
|
|
//var enableSsl = configuration.GetConfigValue("MAIL_ENABLE_SSL", "Smtp:EnableSSL", false);
|
|
//client.Timeout = _configuration.GetConfigValue("MAIL_TIMEOUT", "Smtp:timeout", 30000);
|
|
var isServerOk = TestConnection(host!, port, socketFactory);
|
|
if (!isServerOk)
|
|
return HealthCheckResult.Unhealthy("Unable to connect to SMTP Server");
|
|
|
|
return HealthCheckResult.Healthy();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Performs the test to connect to the smtp server to see that the server is functional.
|
|
/// </summary>
|
|
/// <param name="smtpServerAddress"></param>
|
|
/// <param name="port"></param>
|
|
/// <param name="socketFactory"></param>
|
|
/// <returns></returns>
|
|
public static bool TestConnection(string smtpServerAddress, int port, ISocketFactory socketFactory)
|
|
{
|
|
var hostEntry = Dns.GetHostEntry(smtpServerAddress);
|
|
var endPoint = new IPEndPoint(hostEntry.AddressList[0], port);
|
|
using (var tcpSocket = socketFactory.CreateSocket( endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
|
|
{
|
|
//try to connect and test the rsponse for code 220 = success
|
|
tcpSocket.Connect(endPoint);
|
|
if (!CheckResponse(tcpSocket, 220))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// send HELO and test the response for code 250 = proper response
|
|
SendData(tcpSocket, $"HELO {Dns.GetHostName()}\r\n");
|
|
if (!CheckResponse(tcpSocket, 250))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// if we got here it's that we can connect to the smtp server
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private static void SendData(ISocketFacade socket, string data)
|
|
{
|
|
var dataArray = Encoding.ASCII.GetBytes(data);
|
|
socket.Send(dataArray, 0, dataArray.Length, SocketFlags.None);
|
|
}
|
|
|
|
private static bool CheckResponse(ISocketFacade socket, int expectedCode)
|
|
{
|
|
while (socket.Available == 0)
|
|
{
|
|
Thread.Sleep(100);
|
|
}
|
|
var responseArray = new byte[1024];
|
|
socket.Receive(responseArray, 0, socket.Available, SocketFlags.None);
|
|
var responseData = Encoding.ASCII.GetString(responseArray);
|
|
var responseCode = Convert.ToInt32(responseData.Substring(0, 3));
|
|
return responseCode == expectedCode;
|
|
}
|
|
} |