func (this *SmtpWorker) Process_DATA(streamInput string) (mailitem.MailHeader, mailitem.MailBody, error) {
	header := mailitem.MailHeader{}
	body := mailitem.MailBody{}
	commandCheck := strings.Index(strings.ToLower(streamInput), "data")
	if commandCheck < 0 {
		return header, body, errors.New("Invalid command for DATA")
	}
	this.Writer.SendDataResponse()
	entireMailContents := this.Reader.ReadDataBlock()
	header.Parse(entireMailContents)
	body.Parse(entireMailContents, header.ContentType, header.Boundary, header.ContentTransferEncoding)
	this.Writer.SendOkResponse()
	return header, body, nil
}
/*
Function to process the DATA command (constant DATA). When a client sends the DATA
command there are three parts to the transmission content. Before this data
can be processed this function will tell the client how to terminate the DATA block.
We are asking clients to terminate with "\r\n.\r\n".

The first part is a set of header lines. Each header line is a header key (name), followed
by a colon, followed by the value for that header key. For example a header key might
be "Subject" with a value of "Testing Mail!".

After the header section there should be two sets of carriage return/line feed characters.
This signals the end of the header block and the start of the message body.

Finally when the client sends the "\r\n.\r\n" the DATA transmission portion is complete.
This function will return the following items.

1. Headers (MailHeader)
2. Body breakdown (MailBody)
3. error structure
package server
import (
	"errors"
	"log"
	"net"
	"strings"
	"time"
	"github.com/adampresley/sanitizer"
	"github.com/mailslurper/libmailslurper/model/attachment"
	"github.com/mailslurper/libmailslurper/model/mailitem"
	"github.com/mailslurper/libmailslurper/model/sanitization"
	"github.com/mailslurper/libmailslurper/smtpconstants"
	"github.com/mailslurper/libmailslurper/smtpio"
)
type SmtpWorker struct {
	Connection             net.Conn
	EmailValidationService sanitization.EmailValidationProvider
	Mail                   mailitem.MailItem
	Reader                 smtpio.SmtpReader
	Receiver               chan mailitem.MailItem
	State                  smtpconstants.SmtpWorkerState
	WorkerId               int
	Writer                 smtpio.SmtpWriter
	XSSService             sanitizer.XSSServiceProvider
	pool ServerPool
}
func (this *SmtpWorker) ExecuteCommand(command smtpconstants.SmtpCommand, streamInput string) error {
	var err error
	var response string
	var headers mailitem.MailHeader
	var body mailitem.MailBody
	streamInput = strings.TrimSpace(streamInput)
	switch command {
	case smtpconstants.HELO:
		err = this.Process_HELO(streamInput)
	case smtpconstants.MAIL:
		response, err := this.Process_MAIL(streamInput)
		if err != nil {
			log.Println("libmailslurper: ERROR - Problem calling Process_MAIL -", err)
		} else {
			if !this.EmailValidationService.IsValidEmail(response) {
				log.Println("libmailslurper: ERROR - The provided email FROM is invalid:", response)
				this.Mail.FromAddress = "Invalid address"
			} else {
				this.Mail.FromAddress = response
				log.Println("libmailslurper: INFO - Mail from", response)
			}
		}
	case smtpconstants.RCPT:
		response, err = this.Process_RCPT(streamInput)
		if err != nil {
			log.Println("libmailslurper: ERROR - Problem calling Process_RCPT -", err)
		} else {
			if !this.EmailValidationService.IsValidEmail(response) {
				log.Println("libmailslurper: ERROR - The provided email RCPT is invalid:", response)
			} else {
				this.Mail.ToAddresses = append(this.Mail.ToAddresses, response)
			}
		}
	case smtpconstants.DATA:
		headers, body, err = this.Process_DATA(streamInput)
		if err != nil {
			log.Println("libmailslurper: ERROR - Problem calling Process_DATA -", err)
		} else {
			if len(strings.TrimSpace(body.HTMLBody)) <= 0 {
				this.Mail.Body = this.XSSService.SanitizeString(body.TextBody)
			} else {
				this.Mail.Body = this.XSSService.SanitizeString(body.HTMLBody)
			}
			this.Mail.Subject = this.XSSService.SanitizeString(headers.Subject)
			this.Mail.DateSent = headers.Date
			this.Mail.XMailer = this.XSSService.SanitizeString(headers.XMailer)
			this.Mail.ContentType = this.XSSService.SanitizeString(headers.ContentType)
			this.Mail.Boundary = headers.Boundary
			this.Mail.Attachments = body.Attachments
		}
	default:
		err = nil
	}
	return err
}
func (this *SmtpWorker) InitializeMailItem() {
	this.Mail.ToAddresses = make([]string, 0)
	this.Mail.Attachments = make([]*attachment.Attachment, 0)
	id, _ := mailitem.GenerateId()
	this.Mail.Id = id
}
func NewSmtpWorker(
	workerID int,
	pool ServerPool,
	emailValidationService sanitization.EmailValidationProvider,
	xssService sanitizer.XSSServiceProvider,
) *SmtpWorker {
	return &SmtpWorker{
		EmailValidationService: emailValidationService,
		WorkerId:               workerID,
		State:                  smtpconstants.SMTP_WORKER_IDLE,
		XSSService:             xssService,
		pool: pool,
	}
}
func (this *SmtpWorker) Prepare(
	connection net.Conn,
	receiver chan mailitem.MailItem,
	reader smtpio.SmtpReader,
	writer smtpio.SmtpWriter,
) {
	this.State = smtpconstants.SMTP_WORKER_WORKING
	this.Connection = connection
	this.Receiver = receiver
	this.Reader = reader
	this.Writer = writer
}