Skip to content

Instantly share code, notes, and snippets.

@DanielG
Created November 22, 2010 20:06
Show Gist options
  • Select an option

  • Save DanielG/710573 to your computer and use it in GitHub Desktop.

Select an option

Save DanielG/710573 to your computer and use it in GitHub Desktop.
Hacky node.js smtp server
// SMTP server in node.js (hacky)
var util = require('util');
var net = require('net');
/*
* Template
=== Trying 127.0.0.1:25...
=== Connected to 127.0.0.1.
<- 220 Dexter ESMTP Exim 4.72 Mon, 22 Nov 2010 13:59:05 +0100
-> EHLO Dexter
<- 250-Dexter Hello localhost [127.0.0.1]
<- 250-SIZE 52428800
<- 250-PIPELINING
<- 250 HELP
-> MAIL FROM:<dxld@Dexter>
<- 250 OK
-> RCPT TO:<[email protected]>
<- 250 Accepted
-> DATA
<- 354 Enter message, ending with "." on a line by itself
-> Date: Mon, 22 Nov 2010 13:59:05 +0100
-> To: [email protected]
-> From: dxld@Dexter
-> Subject: test Mon, 22 Nov 2010 13:59:05 +0100
-> X-Mailer: swaks v20100211.0 jetmore.org/john/code/swaks/
->
-> This is a test mailing
->
-> .
<- 250 OK id=1PKVz7-0001P8-CH
-> QUIT
<- 221 Dexter closing connection
*/
var lineServer = function(accept){
var server = net.createServer(function(stream){
stream.on('data', function(data){
var lines = data.toString().split('\r\n');
lines.forEach(function(line, i){
// not sure about that...
if(!line){ return; }
process.nextTick(function(){
stream.emit('line', line);
});
});
});
accept(stream);
});
return server;
}
var server = lineServer(function(stream){
var state = {
message: {
from: ''
, to: []
, data: ''
, in_transaction: false
}
};
stream.setEncoding('utf-8');
stream.on('connect', function(){
stream.write('220 mail.haxxor.net SMTP Yo Mama\r\n');
});
stream.on('line', function(line){
var cmd = line.substring(0, 4).toUpperCase();
console.log('<-', line);
if(state.message.in_transaction) {
if(line == '.') {
state.message.in_transaction = false;
OK();
}
state.message.data += line + '\r\n';
}
if(cmd == 'EHLO') {
MSG('250 ' + line);
} else if(cmd == 'MAIL') {
try {
var addr = line.match(/MAIL FROM:<([^<>\r\n]*)>/)[1];
state.message.from = addr;
OK();
} catch(e) {
ERRO(e)
}
} else if(cmd == 'RCPT') {
try {
var addr = line.match(/RCPT TO:<([^<>\r\n]*)>/)[1];
console.log('<** To:', addr);
state.message.to.push(addr);
OK();
} catch(e) {
ERRO(e);
}
} else if(cmd == 'DATA') {
console.log(line);
MSG('354 Start mail input; end with <CRLF>.<CRLF>');
state.message.in_transaction = true;
}
else if(cmd == 'QUIT') {
MSG('221 mail.haxxor.net Service closing transmission channel');
stream.end();
}
});
function MSG(msg){
var buf = new Buffer(msg + '\r\n');
console.log("-> " + buf.toString());
stream.write(buf);
}
var _ok_buf = new Buffer('250 OK\r\n');
function OK(){
stream.write(_ok_buf);
}
function ERRO(e){
throw e;
}
});
server.listen(2525, '127.0.0.2');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment