Permalink
Browse files

[STYLE] Tab to space conversion.

  • Loading branch information...
1 parent 388b078 commit 5a70896e52321903e0a1fb10ccbfb94b45f20d80 @miksago committed Jan 18, 2010
Showing with 300 additions and 348 deletions.
  1. +12 −12 examples/example-client.js
  2. +198 −199 lib/smtp/client.js
  3. +13 −13 lib/smtp/errors.js
  4. +41 −86 lib/smtp/packetHandler.js
  5. +36 −38 lib/vendor/Pump.js
View
24 examples/example-client.js
@@ -1,10 +1,10 @@
/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil -*- */
/*===============================================
- File: example-client.js
-
- Author: Micheil Smith
- Description:
- Demonstration of the smtp library.
+ File: example-client.js
+
+ Author: Micheil Smith
+ Description:
+ Demonstration of the smtp library.
===============================================*/
var config = require("./config");
var smtp = require("../lib/smtp");
@@ -21,11 +21,11 @@ Your's Truly,\n\
SMTP Client.";
client.connect(config.port, config.host).addCallback(function(){
- client.mail(config.from).addCallback(function(){
- client.rcpt(config.to).addCallback(function(){
- client.data(message).addCallback(function(){
- client.quit();
- });
- });
- });
+ client.mail(config.from).addCallback(function(){
+ client.rcpt(config.to).addCallback(function(){
+ client.data(message).addCallback(function(){
+ client.quit();
+ });
+ });
+ });
});
View
397 lib/smtp/client.js
@@ -1,24 +1,24 @@
/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil -*- */
/*===============================================
- File: client.js
- Author: Micheil Smith
-
- Description:
- This files implements the raw protocol
- that is SMTP. The version of SMTP used
- is as defined in RFC2821.
-
- Implements:
- - SMTP: RFC821
- - ESMTP: RFC2821
- - SMTP Authentication: RFC4954
- - SMTP 8Bit-Mime: RFC1652
- - SMTP over SSL/TLS: RFC2487
-
- Issues:
- - SMTP over SSL/TLS does not work,
- due to lack of TCP Client SSL/TLS
- negotiation within node.js
+ File: client.js
+ Author: Micheil Smith
+
+ Description:
+ This files implements the raw protocol
+ that is SMTP. The version of SMTP used
+ is as defined in RFC2821.
+
+ Implements:
+ - SMTP: RFC821
+ - ESMTP: RFC2821
+ - SMTP Authentication: RFC4954
+ - SMTP 8Bit-Mime: RFC1652
+ - SMTP over SSL/TLS: RFC2487
+
+ Issues:
+ - SMTP over SSL/TLS does not work,
+ due to lack of TCP Client SSL/TLS
+ negotiation within node.js
===============================================*/
// Global
@@ -31,227 +31,226 @@ var PacketHandler = require("./packetHandler").PacketHandler;
/*-----------------------------------------------
- SMTP Client
+ SMTP Client
-----------------------------------------------*/
var Client = function(){
- var client = this;
- this.socket = null;
- this.packetHandler = new PacketHandler();
-
- this.esmtp = false;
- this.capabilities = {};
-
- this.started = false;
- this.waiting = false;
-
- this.debug = true;
-
- this.packetHandler.addListener("packet", function(packet){
- sys.puts(JSON.stringify(packet));
- });
+ var client = this;
+
+ this.socket = null;
+ this.packetHandler = new PacketHandler();
+
+ this.esmtp = false;
+ this.capabilities = {};
+
+ this.debug = true;
+
+ this.packetHandler.addListener("packet", function(packet){
+ if(client.debug){
+ sys.puts("\033[0;33m>> "+packet.status+" "+packet.data.join(" ")+"\033[0m");
+ }
+ })
};
process.inherits(Client, process.EventEmitter);
Client.prototype.connect = function(port, host){
- var client = this;
- var promise = new process.Promise();
-
- this.port = port;
- this.host = host;
-
- this.socket = new tcp.createConnection(this.port, this.host);
- this.socket.setEncoding("ascii");
-
- this.packetHandler.addListener("packet", function(packet){
- client.packetHandler.removeListener("packet", arguments.callee);
- if(packet.status == "220"){
- if(/ESMTP/i.test(packet.data)){
- client.esmtp = true;
- }
- client.handshake().addCallback(function(){
- promise.emitSuccess(packet);
- });
- } else {
- promise.emitError(packet);
- }
- });
-
- this.socket.addListener("receive", function(data){
- if(client.debug){
- sys.puts("\033[0;33m>> "+data.replace(/[\r\n]/gi, "")+"\033[0m")
- }
- client.packetHandler.receive(data);
- });
-
- return promise;
+ var client = this;
+ var promise = new process.Promise();
+
+ this.port = port;
+ this.host = host;
+
+ this.socket = new tcp.createConnection(this.port, this.host);
+ this.socket.setEncoding("ascii");
+
+ this.packetHandler.addListener("packet", function(packet){
+ client.packetHandler.removeListener("packet", arguments.callee);
+ if(packet.status == "220"){
+ if(/ESMTP/i.test(packet.data)){
+ client.esmtp = true;
+ }
+ client.handshake().addCallback(function(){
+ promise.emitSuccess(packet);
+ });
+ } else {
+ promise.emitError(packet);
+ }
+ });
+
+ this.socket.addListener("receive", function(data){
+ if(client.debug){
+ sys.puts("\033[0;33m>> "+data.replace(/[\r\n]/gi, "")+"\033[0m")
+ }
+ client.packetHandler.receive(data);
+ });
+
+ return promise;
};
Client.prototype.writeline = function(line){
- if(this.debug){
- sys.puts("\033[0;32m>> "+line+"\033[0m");
- }
- this.socket.send(line+"\r\n");
+ if(this.debug){
+ sys.puts("\033[0;32m>> "+line+"\033[0m");
+ }
+ this.socket.send(line+"\r\n");
};
// Legacy Support:
Client.prototype.get = function(data, callback){
- var client = this;
-
- this.waiting = true;
-
- this.packetHandler.addOnce("packet", function(){
- callback.apply(this, arguments);
- client.waiting = false;
- });
- this.writeline(data);
+ var client = this;
+
+ this.waiting = true;
+
+ this.packetHandler.addListener("packet", function(){
+ client.packetHandler.removeListener("packet", arguments.callee);
+ callback.apply(this, arguments);
+ client.waiting = false;
+ });
+ this.writeline(data);
};
// New Evented Send:
Client.prototype.send = function(){
- var client = this;
- var promise = new process.Promise();
-
- this.waiting = true;
- this.packetHandler.addListener("packet", function(){
- sys.puts("send got packet back!");
-
- client.packetHandler.removeListener("packet", arguments.callee);
-
- promise.emitSuccess.apply(promise, arguments);
- client.waiting = false;
- });
-
- this.writeline(Array.prototype.join.call(arguments, " "));
-
- return promise;
+ var client = this;
+ var promise = new process.Promise();
+
+ this.waiting = true;
+ this.packetHandler.addListener("packet", function(){
+ client.packetHandler.removeListener("packet", arguments.callee);
+
+ promise.emitSuccess.apply(promise, arguments);
+ client.waiting = false;
+ });
+
+ this.writeline(Array.prototype.join.call(arguments, " "));
+
+ return promise;
}
/*-----------------------------------------------
- Handshaking
+ Handshaking
-----------------------------------------------*/
Client.prototype.handshake = function(){
- if(this.esmtp){
- return this.ehlo();
- } else {
- return this.helo();
- }
+ if(this.esmtp){
+ return this.ehlo();
+ } else {
+ return this.helo();
+ }
};
Client.prototype.parseCapabilities = function(data){
- for(var i=1, j=data.length, item; i<j; ++i){
- item = data[i].split(" ");
- this.capabilities[item[0]] = item.length > 1 ? item.join(" ") : true;
- }
+ for(var i=1, j=data.length, item; i<j; ++i){
+ item = data[i].split(" ");
+ this.capabilities[item[0]] = item.length > 1 ? item.join(" ") : true;
+ }
};
Client.prototype.helo = function(){
- var client = this;
- var promise = new process.Promise();
-
- this.send("HELO", this.host).addCallback(function(packet){
- if(packet.status == "250"){
- client.parseCapabilities(packet.data);
- client.connected = true;
-
- promise.emitSuccess(packet);
- } else {
- promise.emitError(packet);
- }
- });
-
- return promise;
+ var client = this;
+ var promise = new process.Promise();
+
+ this.send("HELO", this.host).addCallback(function(packet){
+ if(packet.status == "250"){
+ client.parseCapabilities(packet.data);
+ client.connected = true;
+
+ promise.emitSuccess(packet);
+ } else {
+ promise.emitError(packet);
+ }
+ });
+
+ return promise;
};
Client.prototype.ehlo = function(){
- var client = this;
- var promise = new process.Promise();
-
- this.send("EHLO", this.host).addCallback(function(packet){
- sys.puts(JSON.stringify(packet));
- if(packet.status == "250"){
- client.parseCapabilities(packet.data);
- client.connected = true;
-
- promise.emitSuccess(packet);
- } else {
- promise.emitError(packet);
- }
- });
-
- return promise;
+ var client = this;
+ var promise = new process.Promise();
+
+ this.send("EHLO", this.host).addCallback(function(packet){
+ sys.puts(JSON.stringify(packet));
+ if(packet.status == "250"){
+ client.parseCapabilities(packet.data);
+ client.connected = true;
+
+ promise.emitSuccess(packet);
+ } else {
+ promise.emitError(packet);
+ }
+ });
+
+ return promise;
};
/*-----------------------------------------------
- Authentication
+ Authentication
-----------------------------------------------*/
Client.prototype.auth = function(){};
Client.prototype.auth_methods = {
- plain: function(){},
- login: function(){},
- cram_md5: function(){}
+ plain: function(){},
+ login: function(){},
+ cram_md5: function(){}
};
/*-----------------------------------------------
- Sending mail
+ Sending mail
-----------------------------------------------*/
Client.prototype.mail = function(address){
- var client = this;
- var promise = new process.Promise();
-
- address = "<"+address+">";
-
- this.send("MAIL", "FROM:", address).addCallback(function(packet){
- if(packet.status == "250"){
- promise.emitSuccess(packet);
- } else {
- promise.emitError(packet);
- }
- });
-
- return promise;
+ var client = this;
+ var promise = new process.Promise();
+
+ address = "<"+address+">";
+
+ this.send("MAIL", "FROM:", address).addCallback(function(packet){
+ if(packet.status == "250"){
+ promise.emitSuccess(packet);
+ } else {
+ promise.emitError(packet);
+ }
+ });
+
+ return promise;
};
Client.prototype.rcpt = function(address){
- var client = this;
- var promise = new process.Promise();
-
- address = "<"+address+">";
-
- this.send("RCPT","TO:", address).addCallback(function(packet){
- if(packet.status == "250"){
- promise.emitSuccess(packet);
- } else {
- promise.emitError(packet);
- }
- });
-
- return promise;
+ var client = this;
+ var promise = new process.Promise();
+
+ address = "<"+address+">";
+
+ this.send("RCPT","TO:", address).addCallback(function(packet){
+ if(packet.status == "250"){
+ promise.emitSuccess(packet);
+ } else {
+ promise.emitError(packet);
+ }
+ });
+
+ return promise;
};
Client.prototype.data = function(data){
- var client = this;
- var promise = new process.Promise();
-
- this.send("DATA").addCallback(function(packet){
- if(packet.status == "354"){
- client.send(data+"\r\n.").addCallback(function(packet){
- if(packet.status == "250"){
- promise.emitSuccess();
- } else {
- promise.emitError(packet);
- }
- });
- }
- });
-
- return promise;
+ var client = this;
+ var promise = new process.Promise();
+
+ this.send("DATA").addCallback(function(packet){
+ if(packet.status == "354"){
+ client.send(data+"\r\n.").addCallback(function(packet){
+ if(packet.status == "250"){
+ promise.emitSuccess();
+ } else {
+ promise.emitError(packet);
+ }
+ });
+ }
+ });
+
+ return promise;
};
/*-----------------------------------------------
- Other Commands
+ Other Commands
-----------------------------------------------*/
Client.prototype.rset = function(){};
Client.prototype.vrfy = function(){};
@@ -260,21 +259,21 @@ Client.prototype.help = function(){};
Client.prototype.noop = function(){};
/*-----------------------------------------------
- Quit Command
+ Quit Command
-----------------------------------------------*/
Client.prototype.quit = function(){
- var client = this;
- var promise = new process.Promise();
- this.send("QUIT").addCallback(function(packet){
- if(packet.status == "221"){
- client.socket.close();
- promise.emitSuccess();
- } else {
- promise.emitError();
- }
- });
-
- return promise;
+ var client = this;
+ var promise = new process.Promise();
+ this.send("QUIT").addCallback(function(packet){
+ if(packet.status == "221"){
+ client.socket.close();
+ promise.emitSuccess();
+ } else {
+ promise.emitError();
+ }
+ });
+
+ return promise;
};
View
26 lib/smtp/errors.js
@@ -1,21 +1,21 @@
/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil -*- */
/*===============================================
- File: errors.js
- Author: Micheil Smith
-
- Description:
- Defines all the different client and
- server error codes to translate them
- to human text.
+ File: errors.js
+ Author: Micheil Smith
+
+ Description:
+ Defines all the different client and
+ server error codes to translate them
+ to human text.
===============================================*/
var SMTPErrors = exports;
SMTPErrors.client = {
- "unhandled": new Error("Received an unhandled status code"),
- // numeric:
- "503": Error("Bad sequence of commands"),
- "504": new Error("Command parameter not implemented"),
- "550": new Error("Requested action not taken: mailbox unavailable"),
- "554": new Error("Transaction failed (Or, in the case of a connection-opening response, \"No SMTP service here\")")
+ "unhandled": new Error("Received an unhandled status code"),
+ // numeric:
+ "503": Error("Bad sequence of commands"),
+ "504": new Error("Command parameter not implemented"),
+ "550": new Error("Requested action not taken: mailbox unavailable"),
+ "554": new Error("Transaction failed (Or, in the case of a connection-opening response, \"No SMTP service here\")")
};
View
127 lib/smtp/packetHandler.js
@@ -1,15 +1,15 @@
/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil -*- */
/*===============================================
- File: PacketHandler.js
-
- Author: Micheil Smith
- Description:
- Handles the parsing and processing of
- incoming SMTP packets.
-
- We use the vendor Queue runner,
- although, we replace certain parts to
- make it's use cleaner.
+ File: PacketHandler.js
+
+ Author: Micheil Smith
+ Description:
+ Handles the parsing and processing of
+ incoming SMTP packets.
+
+ We use the vendor Queue runner,
+ although, we replace certain parts to
+ make it's use cleaner.
===============================================*/
// Global
var sys = require("sys");
@@ -18,92 +18,47 @@ var EventEmitter = require("../vendor/eventEmitter");
var Pump = require("../vendor/Pump").Pump;
/*-----------------------------------------------
- PacketHandler
+ PacketHandler
-----------------------------------------------*/
exports.PacketHandler = function(){
- var self = this;
- this.pump = new Pump(this._PumpProcess, this);
- this.pump.addListener("drain", function(){
- self._drain.call(self)
- });
- this.pump.addListener("data", function(data){
- sys.puts(">>> "+data);
- });
- return this;
+ var self = this;
+ this.pump = new Pump(this._PumpProcess, this);
+
+ this.pump.addListener("drain", function(){
+ self._drain.call(self)
+ });
+
+ return this;
};
process.inherits(exports.PacketHandler, process.EventEmitter);
-
exports.PacketHandler.prototype.receive = function(data){
- var lines = data.split("\r\n");
-
- while(lines.length && (line = lines.shift())){
- this.pump.push(line);
- }
+ var lines = data.split("\r\n");
+
+ while(lines.length && (line = lines.shift())){
+ this.pump.push(line);
+ }
};
exports.PacketHandler.prototype._PumpProcess = function(pump){
- var pStatus = null, pContinues = true, pData = [], line;
-
- while(pContinues && pump._stream.length && (line = pump._stream.shift())){
- var packet = /([0-9]{3})([\ \-]{1})(.*)/.exec(line);
-
- pStatus = packet[1];
- pData.push(packet[3]);
-
- pContinues = (packet[2] == "-");
- }
-
- this.emit("packet", {
- status: pStatus,
- data: pData
- });
+ var pStatus = null, pContinues = true, pData = [], line;
+
+ while(pContinues && pump._stream.length && (line = pump._stream.shift())){
+ var packet = /([0-9]{3})([\ \-]{1})(.*)/.exec(line);
+
+ pStatus = packet[1];
+ pData.push(packet[3]);
+
+ pContinues = (packet[2] == "-");
+ }
+
+ this.emit("packet", {
+ status: pStatus,
+ data: pData
+ });
};
exports.PacketHandler.prototype._drain = function(){
- sys.puts("drain");
- this.emit("drain");
-};
-
-
-
-//exports.PacketHandler.prototype = new Queue();
-/*
-exports.PacketHandler.prototype.push = function(data){
- var packets = data.split("\r\n");
- while(packets.length && (packet = packets.shift())){
- this._stack.push(packet);
- }
-
- if( !this._processing ){
- this._processor();
- }
-};
-
-exports.PacketHandler.prototype.process = function(){
- var status = 0, data = [], continued = false;
-
- for(var continued = false; this._stack.length && (packet = this._stack.shift());){
- if( !continued ){
- status = packet.substr(0,3); // not a number, strings are easier to work with as status codes.
- }
-
- data.push(packet.substr(4));
-
- if( ! (continued = (/[0-9]{3}\-/i.test(packet))) ){
- break;
- }
- }
-
- this.emit("packet", {
- status: status,
- data: data
- });
-
- if(this._stack.length == 0){
- this.emit("drain");
- }
-
-};
-*/
+ this.emit("drain");
+};
View
74 lib/vendor/Pump.js
@@ -1,54 +1,52 @@
/*===============================================
- File: Pump.js
-
- Author: Micheil Smith
- Description:
- A simple data pump
+ File: Pump.js
+
+ Author: Micheil Smith
+ Description:
+ A simple data pump
===============================================*/
-var sys = require("sys");
-
var Pump = exports.Pump = function(/*Function*/ handler, /*Scope*/ scope){
- this._stream = [];
- this.process = handler || this.defaultProcess;
- this.scope = scope;
-
- var pump = this;
- this.addListener("push", function(){
- pump._process();
- });
+ this._stream = [];
+ this.process = handler || this.defaultProcess;
+ this.scope = scope;
+
+ var pump = this;
+ this.addListener("push", function(){
+ pump._process();
+ });
};
process.inherits(Pump, process.EventEmitter);
Pump.prototype.push = function(/*Mixed*/ data){
- clearTimeout(this._bufTimer);
- this._stream.push(data);
-
- var scope = this;
-
- this._bufTimer = setTimeout(function(){
- scope.emit("push", data);
- }, 100);
+ clearTimeout(this._bufTimer);
+ this._stream.push(data);
+
+ var scope = this;
+ // We use a timer here as a fake buffer.
+ this._bufTimer = setTimeout(function(){
+ scope.emit("push", data);
+ }, 10);
};
Pump.prototype._process = function(ignore){
- if( ! this.running){
- while(this._stream && this._stream.length > 0){
- this.running = true;
- this.process.call(this.scope, this);
- }
-
- if (this._stream && !(this._stream.length > 0)) {
- this.emit("drain");
- }
-
- this.running = false;
- }
+ if( ! this.running){
+ while(this._stream && this._stream.length > 0){
+ this.running = true;
+ this.process.call(this.scope, this);
+ }
+
+ if (this._stream && !(this._stream.length > 0)) {
+ this.emit("drain");
+ }
+
+ this.running = false;
+ }
};
Pump.prototype.defaultProcess = function(/*Scope*/ pump){
- while(pump._stream.length && (packet = pump._stream.shift())){
- pump.emit("data", pump._stream.shift());
- }
+ while(pump._stream.length && (packet = pump._stream.shift())){
+ pump.emit("data", pump._stream.shift());
+ }
};

0 comments on commit 5a70896

Please sign in to comment.