permessage-deflate
Advanced tools
Comparing version 0.1.0 to 0.1.1
@@ -6,2 +6,4 @@ 'use strict'; | ||
var VERSION = process.version.match(/\d+/g).map(function(n) { return parseInt(n, 10) }); | ||
var Session = function(options) { | ||
@@ -16,2 +18,5 @@ this._level = common.fetch(options, 'level', zlib.Z_DEFAULT_LEVEL); | ||
this._requestMaxWindowBits = common.fetch(options, 'requestMaxWindowBits', undefined); | ||
this._queueIn = []; | ||
this._queueOut = []; | ||
}; | ||
@@ -21,12 +26,43 @@ | ||
if (!message.rsv1) return callback(null, message); | ||
if (this._lockIn) return this._queueIn.push([message, callback]); | ||
var inflate = this._getInflate(), | ||
chunks = [message.data, new Buffer([0x00, 0x00, 0xff, 0xff])], | ||
chunks = [], | ||
length = 0, | ||
self = this; | ||
this._processMessage(inflate, chunks, function(error, data) { | ||
if (this._inflate) this._lockIn = true; | ||
var return_ = function(error, message) { | ||
return_ = function() {}; | ||
inflate.removeListener('data', onData); | ||
inflate.removeListener('error', onError); | ||
if (!self._inflate && inflate.close) inflate.close(); | ||
if (error) return callback(error, null); | ||
message.data = data; | ||
callback(null, message); | ||
self._lockIn = false; | ||
var next = self._queueIn.shift(); | ||
if (next) self.processIncomingMessage.apply(self, next); | ||
callback(error, message); | ||
}; | ||
var onData = function(data) { | ||
chunks.push(data); | ||
length += data.length; | ||
}; | ||
var onError = function(error) { | ||
return_(error, null); | ||
}; | ||
inflate.on('data', onData); | ||
inflate.on('error', onError); | ||
inflate.write(message.data); | ||
inflate.write(new Buffer([0x00, 0x00, 0xff, 0xff])); | ||
inflate.flush(function() { | ||
message.data = common.concat(chunks, length); | ||
return_(null, message); | ||
}); | ||
@@ -36,12 +72,50 @@ }; | ||
Session.prototype.processOutgoingMessage = function(message, callback) { | ||
if (this._lockOut) return this._queueOut.push([message, callback]); | ||
var deflate = this._getDeflate(), | ||
chunks = [], | ||
length = 0, | ||
self = this; | ||
this._processMessage(deflate, [message.data], function(error, data) { | ||
if (this._deflate) this._lockOut = true; | ||
var return_ = function(error, message) { | ||
return_ = function() {}; | ||
deflate.removeListener('data', onData); | ||
deflate.removeListener('error', onError); | ||
if (!self._deflate && deflate.close) deflate.close(); | ||
if (error) return callback(error, null); | ||
message.rsv1 = true; | ||
message.data = data.slice(0, data.length - 4); | ||
callback(null, message); | ||
}); | ||
self._lockOut = false; | ||
var next = self._queueOut.shift(); | ||
if (next) self.processOutgoingMessage.apply(self, next); | ||
callback(error, message); | ||
}; | ||
var onData = function(data) { | ||
var tail = data.slice(Math.max(data.length - 4, 0), data.length), | ||
isEnd = (tail[0] === 0x00 && tail[1] === 0x00 && tail[2] === 0xff && tail[3] === 0xff); | ||
if (isEnd) data = data.slice(0, data.length - 4); | ||
chunks.push(data); | ||
length += data.length; | ||
if (isEnd) { | ||
message.rsv1 = true; | ||
message.data = common.concat(chunks, length); | ||
return_(null, message); | ||
} | ||
}; | ||
var onError = function(error) { | ||
return_(error, null); | ||
}; | ||
deflate.on('data', onData); | ||
deflate.on('error', onError); | ||
deflate.write(message.data); | ||
if (VERSION[0] === 0 && VERSION[1] < 10) deflate.flush(); | ||
}; | ||
@@ -68,2 +142,3 @@ | ||
var deflate = zlib.createDeflateRaw({ | ||
flush: zlib.Z_SYNC_FLUSH, | ||
windowBits: this._ownWindowBits, | ||
@@ -78,32 +153,2 @@ level: this._level, | ||
Session.prototype._processMessage = function(codec, data, callback) { | ||
var chunks = [], | ||
length = 0; | ||
var return_ = function(error, result) { | ||
return_ = function() {}; | ||
codec.removeListener('data', onData); | ||
codec.removeListener('error', onError); | ||
codec = null; | ||
callback(error, result); | ||
}; | ||
var onData = function(chunk) { | ||
chunks.push(chunk); | ||
length += chunk.length; | ||
}; | ||
var onError = function(error) { | ||
return_(error, null); | ||
}; | ||
codec.on('data', onData); | ||
codec.on('error', onError); | ||
data.forEach(function(c) { codec.write(c) }); | ||
codec.flush(function() { | ||
return_(null, common.concat(chunks, length)); | ||
}); | ||
}; | ||
module.exports = Session; |
@@ -8,3 +8,3 @@ { "name" : "permessage-deflate" | ||
, "version" : "0.1.0" | ||
, "version" : "0.1.1" | ||
, "engines" : {"node": ">=0.6.0"} | ||
@@ -11,0 +11,0 @@ , "main" : "./lib/permessage_deflate" |
@@ -44,3 +44,3 @@ # permessage-deflate [![Build status](https://secure.travis-ci.org/faye/permessage-deflate-node.svg)](http://travis-ci.org/faye/permessage-deflate-node) | ||
session's compressor for outgoing messages and do not need to be communicated to | ||
the peer, and those that are negoatiated as part of the protocol. The settings | ||
the peer, and those that are negotiated as part of the protocol. The settings | ||
only affecting the compressor are described fully in the [zlib | ||
@@ -50,3 +50,3 @@ documentation](http://nodejs.org/api/zlib.html#zlib_options): | ||
* `level`: sets the compression level, can be an integer from `0` to `9`, or one | ||
of the contants `zlib.Z_NO_COMPRESSION`, `zlib.Z_BEST_SPEED`, | ||
of the constants `zlib.Z_NO_COMPRESSION`, `zlib.Z_BEST_SPEED`, | ||
`zlib.Z_BEST_COMPRESSION`, or `zlib.Z_DEFAULT_COMPRESSION` | ||
@@ -53,0 +53,0 @@ * `memLevel`: sets how much memory the compressor allocates, can be an integer |
15879
8
289