141 lines
3.3 KiB
JavaScript
141 lines
3.3 KiB
JavaScript
var spdy = require('../spdy'),
|
|
utils = exports;
|
|
|
|
var stream = require('stream'),
|
|
zlib = require('zlib'),
|
|
Buffer = require('buffer').Buffer;
|
|
|
|
// Export streams related stuff
|
|
utils.isLegacy = !stream.Duplex;
|
|
if (utils.isLegacy)
|
|
utils.DuplexStream = stream;
|
|
else
|
|
utils.DuplexStream = stream.Duplex;
|
|
|
|
//
|
|
// ### function createDeflate (version, compression)
|
|
// #### @version {Number} SPDY version
|
|
// #### @compression {Boolean} whether to enable compression
|
|
// Creates deflate stream with SPDY dictionary
|
|
//
|
|
utils.createDeflate = function createDeflate(version, compression) {
|
|
var deflate = zlib.createDeflate({
|
|
dictionary: spdy.protocol.dictionary[version],
|
|
flush: zlib.Z_SYNC_FLUSH,
|
|
windowBits: 11,
|
|
level: compression ? zlib.Z_DEFAULT_COMPRESSION : zlib.Z_NO_COMPRESSION
|
|
});
|
|
|
|
// Define lock information early
|
|
deflate.locked = false;
|
|
deflate.lockQueue = [];
|
|
if (spdy.utils.isLegacy)
|
|
deflate._flush = zlib.Z_SYNC_FLUSH;
|
|
|
|
return deflate;
|
|
};
|
|
|
|
//
|
|
// ### function createInflate (version)
|
|
// #### @version {Number} SPDY version
|
|
// Creates inflate stream with SPDY dictionary
|
|
//
|
|
utils.createInflate = function createInflate(version) {
|
|
var inflate = zlib.createInflate({
|
|
dictionary: spdy.protocol.dictionary[version],
|
|
flush: zlib.Z_SYNC_FLUSH,
|
|
windowBits: 15
|
|
});
|
|
|
|
// Define lock information early
|
|
inflate.locked = false;
|
|
inflate.lockQueue = [];
|
|
if (spdy.utils.isLegacy)
|
|
inflate._flush = zlib.Z_SYNC_FLUSH;
|
|
|
|
return inflate;
|
|
};
|
|
|
|
//
|
|
// ### function resetZlibStream (stream)
|
|
// #### @stream {zlib.Stream} stream
|
|
// Resets zlib stream and associated locks
|
|
//
|
|
utils.resetZlibStream = function resetZlibStream(stream, callback) {
|
|
if (stream.locked) {
|
|
stream.lockQueue.push(function() {
|
|
resetZlibStream(stream, callback);
|
|
});
|
|
return;
|
|
}
|
|
|
|
stream.reset();
|
|
stream.lockQueue = [];
|
|
|
|
callback(null);
|
|
};
|
|
|
|
var delta = 0;
|
|
//
|
|
// ### function zstream (stream, buffer, callback)
|
|
// #### @stream {Deflate|Inflate} One of streams above
|
|
// #### @buffer {Buffer} Input data (to compress or to decompress)
|
|
// #### @callback {Function} Continuation to callback
|
|
// Compress/decompress data and pass it to callback
|
|
//
|
|
utils.zstream = function zstream(stream, buffer, callback) {
|
|
var chunks = [],
|
|
total = 0;
|
|
|
|
if (stream.locked) {
|
|
stream.lockQueue.push(function() {
|
|
zstream(stream, buffer, callback);
|
|
});
|
|
return;
|
|
}
|
|
stream.locked = true;
|
|
|
|
function collect(chunk) {
|
|
chunks.push(chunk);
|
|
total += chunk.length;
|
|
}
|
|
stream.on('data', collect);
|
|
|
|
stream.write(buffer, done);
|
|
|
|
function done() {
|
|
stream.removeAllListeners('data');
|
|
stream.removeAllListeners('error');
|
|
|
|
if (callback)
|
|
callback(null, chunks, total);
|
|
|
|
stream.locked = false;
|
|
var deferred = stream.lockQueue.shift();
|
|
if (deferred)
|
|
deferred();
|
|
};
|
|
|
|
stream.once('error', function(err) {
|
|
stream.removeAllListeners('data');
|
|
callback(err);
|
|
callback = null;
|
|
});
|
|
};
|
|
|
|
//
|
|
// ### function zwrap (stream)
|
|
// #### @stream {zlib.Stream} stream to wrap
|
|
// Wraps stream within function to allow simple deflate/inflate
|
|
//
|
|
utils.zwrap = function zwrap(stream) {
|
|
return function(data, callback) {
|
|
utils.zstream(stream, data, callback);
|
|
};
|
|
};
|
|
|
|
if (typeof setImmediate === 'undefined')
|
|
utils.nextTick = process.nextTick.bind(process);
|
|
else
|
|
utils.nextTick = setImmediate;
|