Trying COMPRESS

This commit is contained in:
Andris Reinman 2017-04-04 16:35:56 +03:00
parent ad486b9df8
commit d551c11828
4 changed files with 72 additions and 2 deletions

View file

@ -31,6 +31,7 @@ module.exports = {
capabilities.push('QUOTA');
capabilities.push('MOVE');
capabilities.push('COMPRESS=DEFLATE');
if (this._server.options.maxMessage) {
capabilities.push('APPENDLIMIT=' + this._server.options.maxMessage);

View file

@ -0,0 +1,56 @@
'use strict';
const zlib = require('zlib');
// tag COMPRESS DEFLATE
module.exports = {
state: ['Authenticated', 'Selected'],
schema: [{
name: 'mechanism',
type: 'string'
}],
handler(command, callback) {
let mechanism = (command.attributes[0] && command.attributes[0].value || '').toString().toUpperCase().trim();
if (!mechanism) {
return callback(null, {
response: 'BAD'
});
}
if (mechanism !== 'DEFLATE') {
return callback(null, {
response: 'BAD',
code: 'CANNOT',
message: 'Unsupported compression mechanism'
});
}
setImmediate(() => {
this.compression = true;
this._deflate = zlib.createDeflateRaw();
this._inflate = zlib.createDeflateRaw();
this._deflate.once('error', err => {
this._socket.emit('error', err);
});
this._deflate.pipe(this._socket);
this.writeStream.unpipe(this._socket);
this.writeStream.pipe(this._deflate);
this._socket.unpipe(this._parser);
this._socket.pipe(this._inflate).pipe(this._parser);
});
callback(null, {
response: 'OK',
message: 'DEFLATE active'
});
}
};

View file

@ -45,7 +45,8 @@ let commands = new Map([
['ENABLE', require('./commands/enable')],
['GETQUOTAROOT', require('./commands/getquotaroot')],
['SETQUOTA', require('./commands/setquota')],
['GETQUOTA', require('./commands/getquota')]
['GETQUOTA', require('./commands/getquota')],
['COMPRESS', require('./commands/compress')]
/*eslint-enable global-require*/
]);

View file

@ -28,6 +28,10 @@ class IMAPConnection extends EventEmitter {
// Random session ID, used for logging
this.id = crypto.randomBytes(9).toString('base64');
this.compression = false;
this._deflate = false;
this._inflate = false;
this._server = server;
this._socket = socket;
@ -118,7 +122,7 @@ class IMAPConnection extends EventEmitter {
*/
send(payload, callback) {
if (this._socket && this._socket.writable) {
this._socket.write(payload + '\r\n', 'binary', callback);
(!this.compression ? this._socket : this._deflate).write(payload + '\r\n', 'binary', callback);
this._server.logger.debug('[%s] S:', this.id, payload);
}
}
@ -178,6 +182,14 @@ class IMAPConnection extends EventEmitter {
this._dataStream = null;
}
if (this._deflate) {
this._deflate = null;
}
if (this._inflate) {
this._inflate = null;
}
if (this._listenerData) {
this._listenerData.clear();
}