mirror of
https://github.com/nodemailer/wildduck.git
synced 2025-01-07 16:38:17 +08:00
107 lines
2.8 KiB
JavaScript
107 lines
2.8 KiB
JavaScript
'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({
|
|
windowBits: 15
|
|
});
|
|
this._inflate = zlib.createInflateRaw();
|
|
|
|
this._deflate.once('error', err => {
|
|
this._server.logger.debug(
|
|
{
|
|
err,
|
|
tnx: 'deflate',
|
|
cid: this.id
|
|
},
|
|
'[%s] Deflate error %s',
|
|
this.id,
|
|
err.message
|
|
);
|
|
this.close();
|
|
});
|
|
|
|
this._inflate.once('error', err => {
|
|
this._server.logger.debug(
|
|
{
|
|
err,
|
|
tnx: 'inflate',
|
|
cid: this.id
|
|
},
|
|
'[%s] Inflate error %s',
|
|
this.id,
|
|
err.message
|
|
);
|
|
this.close();
|
|
});
|
|
|
|
this.writeStream.unpipe(this._socket);
|
|
this._deflate.pipe(this._socket);
|
|
let reading = false;
|
|
let readNext = () => {
|
|
reading = true;
|
|
|
|
let chunk;
|
|
while ((chunk = this.writeStream.read()) !== null) {
|
|
if (this._deflate && this._deflate.write(chunk) === false) {
|
|
return this._deflate.once('drain', readNext);
|
|
}
|
|
}
|
|
|
|
// flush data to socket
|
|
if (this._deflate) {
|
|
this._deflate.flush();
|
|
}
|
|
|
|
reading = false;
|
|
};
|
|
this.writeStream.on('readable', () => {
|
|
if (!reading) {
|
|
readNext();
|
|
}
|
|
});
|
|
|
|
this._socket.unpipe(this._parser);
|
|
this._socket.pipe(this._inflate).pipe(this._parser);
|
|
});
|
|
|
|
callback(null, {
|
|
response: 'OK',
|
|
message: 'DEFLATE active'
|
|
});
|
|
}
|
|
};
|