wildduck/imap-core/lib/commands/compress.js

108 lines
2.8 KiB
JavaScript
Raw Normal View History

2017-04-04 21:35:56 +08:00
'use strict';
const zlib = require('zlib');
// tag COMPRESS DEFLATE
module.exports = {
state: ['Authenticated', 'Selected'],
2017-06-03 14:51:58 +08:00
schema: [
{
name: 'mechanism',
type: 'string'
}
],
2017-04-04 21:35:56 +08:00
handler(command, callback) {
let mechanism = ((command.attributes[0] && command.attributes[0].value) || '')
.toString()
.toUpperCase()
.trim();
2017-04-04 21:35:56 +08:00
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;
2017-04-04 22:09:39 +08:00
this._deflate = zlib.createDeflateRaw({
windowBits: 15
});
2017-04-04 21:38:44 +08:00
this._inflate = zlib.createInflateRaw();
2017-04-04 21:35:56 +08:00
this._deflate.once('error', err => {
2017-06-03 14:51:58 +08:00
this._server.logger.debug(
{
err,
tnx: 'deflate',
cid: this.id
},
'[%s] Deflate error %s',
this.id,
err.message
);
2017-04-04 22:09:39 +08:00
this.close();
2017-04-04 21:35:56 +08:00
});
2017-04-04 22:09:39 +08:00
this._inflate.once('error', err => {
2017-06-03 14:51:58 +08:00
this._server.logger.debug(
{
err,
tnx: 'inflate',
cid: this.id
},
'[%s] Inflate error %s',
this.id,
err.message
);
2017-04-04 22:09:39 +08:00
this.close();
});
2017-04-04 21:35:56 +08:00
this.writeStream.unpipe(this._socket);
2017-04-04 22:09:39 +08:00
this._deflate.pipe(this._socket);
let reading = false;
2017-04-04 22:09:39 +08:00
let readNext = () => {
reading = true;
2017-04-04 22:09:39 +08:00
let chunk;
while ((chunk = this.writeStream.read()) !== null) {
if (this._deflate && this._deflate.write(chunk) === false) {
2017-04-04 22:09:39 +08:00
return this._deflate.once('drain', readNext);
}
}
2017-05-16 18:57:04 +08:00
2017-04-04 22:09:39 +08:00
// flush data to socket
if (this._deflate) {
this._deflate.flush();
}
reading = false;
2017-04-04 22:09:39 +08:00
};
this.writeStream.on('readable', () => {
if (!reading) {
readNext();
}
});
2017-04-04 21:35:56 +08:00
this._socket.unpipe(this._parser);
this._socket.pipe(this._inflate).pipe(this._parser);
});
callback(null, {
response: 'OK',
message: 'DEFLATE active'
});
}
};