Permalink
Browse files

Merge branch 'master' of github.com:jbaylina/simplesmtp into jbaylina…

…-master
  • Loading branch information...
2 parents e8ff335 + ee4b1de commit 5153e18d1c05b37fd5fd83e080bb088d760d0051 @andris9 committed Feb 26, 2014
Showing with 44 additions and 6 deletions.
  1. +1 −0 README.md
  2. +43 −6 lib/client.js
View
@@ -140,6 +140,7 @@ The following connection options can be used with `simplesmtp.connect`:
* **connectionTimeout** (system default if not set) - Time to wait in ms until the socket is opened to the server
* **rejectUnathorized** (defaults to false) - if set to true accepts only valid server certificates. You can override this option with the `tls` option, this is just a shorthand
* **dsn** - An object with methods `success`, `failure` and `delay`. If any of these are set to true, DSN will be used
+ * **disableDotEscaping** set to true if you want to bypass the dot escaping at the begining of each line. Default to false
### Connection events
View
@@ -59,6 +59,8 @@ function SMTPClient(port, host, options){
this.options.secureConnection = !!this.options.secureConnection;
this.options.auth = this.options.auth || false;
this.options.maxConnections = this.options.maxConnections || 5;
+ this.options.disableDotEscaping = this.options.disableDotEscaping || false;
+
if(!this.options.name){
// defaul hostname is machine hostname or [IP]
@@ -130,6 +132,9 @@ SMTPClient.prototype._init = function(){
* @private
*/
this._lastDataBytes = new Buffer(2);
+ this._lastDataBytes[0] = 0x0D;
+ this._lastDataBytes[1] = 0x0A;
+
/**
* Function to run if a data chunk comes from the server
@@ -425,12 +430,16 @@ SMTPClient.prototype.write = function(chunk){
chunk = new Buffer(chunk, "utf-8");
}
- if(chunk.length > 2){
- this._lastDataBytes[0] = chunk[chunk.length-2];
- this._lastDataBytes[1] = chunk[chunk.length-1];
- }else if(chunk.length == 1){
- this._lastDataBytes[0] = this._lastDataBytes[1];
- this._lastDataBytes[1] = chunk[0];
+ if (this.options.disableDotEscaping) {
+ if (chunk.length>=2) {
+ this._lastDataBytes[0] = chunk[chunk.length-2];
+ this._lastDataBytes[1] = chunk[chunk.length-1];
+ } else if (chunk.length==1) {
+ this._lastDataBytes[0] = this._lastDataBytes[1]
+ this._lastDataBytes[1] = chunk[0];
+ }
+ } else {
+ chunk = this._escapeDot(chunk);
}
if(this.options.debug){
@@ -476,6 +485,9 @@ SMTPClient.prototype.end = function(chunk){
}else{
this.socket.write(new Buffer("\r\n.\r\n"));
}
+ this._lastDataBytes[0] = 0x0D;
+ this._lastDataBytes[1] = 0x0A;
+
// end data mode
this._dataMode = false;
@@ -1076,3 +1088,28 @@ SMTPClient.prototype.log = function(str) {
}
});
};
+
+/**
+ * <p>Inserts an extra dot at the begining of a line if it starts with a dot
+ * See RFC 2821 Section 4.5.2</p>
+ *
+ * @param {Buffer} chunk The chunk that will be send.
+ */
+SMTPClient.prototype._escapeDot = function(chunk) {
+ var pos, OutBuff, i;
+ OutBuff = new Buffer(chunk.length * 2);
+ pos = 0;
+
+ for (i=0; i<chunk.length; i++) {
+ if (this._lastDataBytes[0] == 0x0D && this._lastDataBytes[1] == 0x0A && chunk[i] == 0x2E) {
+ OutBuff[pos] = 0x2E;
+ pos +=1;
+ }
+ OutBuff[pos] = chunk[i];
+ pos += 1;
+ this._lastDataBytes[0] = this._lastDataBytes[1];
+ this._lastDataBytes[1] = chunk[i];
+ }
+
+ return OutBuff.slice(0,pos);
+}

0 comments on commit 5153e18

Please sign in to comment.