This commit is contained in:
2025-05-22 09:22:55 +00:00
parent a4353b10bb
commit d584f3584c
7 changed files with 727 additions and 44 deletions

View File

@ -9,6 +9,7 @@ import type { ISmtpSession, IEnvelopeRecipient } from './interfaces.js';
import type { ICommandHandler, ISessionManager, IDataHandler, ITlsHandler, ISecurityHandler } from './interfaces.js';
import { SmtpCommand, SmtpResponseCode, SMTP_DEFAULTS, SMTP_EXTENSIONS } from './constants.js';
import { SmtpLogger } from './utils/logging.js';
import { adaptiveLogger } from './utils/adaptive-logging.js';
import { extractCommandName, extractCommandArgs, formatMultilineResponse } from './utils/helpers.js';
import { validateEhlo, validateMailFrom, validateRcptTo, isValidCommandSequence } from './utils/validation.js';
@ -100,7 +101,32 @@ export class CommandHandler implements ICommandHandler {
return;
}
// Handle data state differently - pass to data handler
// Handle raw data chunks from connection manager during DATA mode
if (commandLine.startsWith('__RAW_DATA__')) {
const rawData = commandLine.substring('__RAW_DATA__'.length);
if (this.dataHandler) {
// Let the data handler process the raw chunk
this.dataHandler.handleDataReceived(socket, rawData)
.catch(error => {
SmtpLogger.error(`Error processing raw email data: ${error.message}`, {
sessionId: session.id,
error
});
this.sendResponse(socket, `${SmtpResponseCode.LOCAL_ERROR} Error processing email data: ${error.message}`);
this.resetSession(session);
});
} else {
// No data handler available
SmtpLogger.error('Data handler not available for raw data', { sessionId: session.id });
this.sendResponse(socket, `${SmtpResponseCode.LOCAL_ERROR} Internal server error - data handler not available`);
this.resetSession(session);
}
return;
}
// Handle data state differently - pass to data handler (legacy line-based processing)
if (session.state === SmtpState.DATA_RECEIVING) {
// Check if this looks like an SMTP command - during DATA mode all input should be treated as message content
const looksLikeCommand = /^[A-Z]{4,}( |:)/i.test(commandLine.trim());
@ -115,7 +141,7 @@ export class CommandHandler implements ICommandHandler {
}
if (this.dataHandler) {
// Let the data handler process the line
// Let the data handler process the line (legacy mode)
this.dataHandler.processEmailData(socket, commandLine)
.catch(error => {
SmtpLogger.error(`Error processing email data: ${error.message}`, {
@ -155,8 +181,8 @@ export class CommandHandler implements ICommandHandler {
}
}
// Log received command (single command case)
SmtpLogger.logCommand(commandLine, socket, session);
// Log received command using adaptive logger
adaptiveLogger.logCommand(commandLine, socket, session);
// Extract command and arguments
const command = extractCommandName(commandLine);
@ -283,7 +309,7 @@ export class CommandHandler implements ICommandHandler {
public sendResponse(socket: plugins.net.Socket | plugins.tls.TLSSocket, response: string): void {
try {
socket.write(`${response}${SMTP_DEFAULTS.CRLF}`);
SmtpLogger.logResponse(response, socket);
adaptiveLogger.logResponse(response, socket);
} catch (error) {
// Attempt to recover from known transient errors
if (this.isRecoverableSocketError(error)) {