Tuesday, June 14, 2011

Quick Data Compression Cleanup in node-spdy

‹prev | My Chain | next›

Tonight I hope to knock off a bit of housekeeping. I had gotten SPDY data compression working in node-spdy a few days ago, but have not submitted a pull request because the code was a bit of a mess.

After using git-format-patch and patch -p1 to dump the other day's work and re-apply it against the latest master of node-spdy, I am ready. First, I make sure that everything still working. Sure enough, the data responses are still compressed (as seen by the 0x02 flag value):
               +----------------------------------+
00 00 00 03 |C| Stream-ID (31bits) |
+----------------------------------+
02 00 00 dd | Flags (8) | Length (24 bits) |
+----------------------------------+
78 9c 64 8f | Data |
d1 6e c3 20 +----------------------------------+
0c 45 df f3
15 96 a2 49
...
Cool.

In SPDY, header compression uses a ZLib context with a dictionary set. Data compression on the other hand uses a separate zlib context without a dictionary. (note to self: find out why). In both cases, there are separate Zlib contexts for inbound traffic and outbound traffic. Unless my calculations are off, that makes for 4 different Zlib context per session (inbound & outbound header Zlib contexts and inbound and outbound data Zlib contexts).

The header Zlib contexts are already being created thusly:
    c.zlib = createZLib();
I would rather not change that signature to support data compression. Instead, I would like to supply an optional object literal to drive data compression behavior:
  this.stream_compressor = createZLib({use_dictionary: false});
In the createZLib() function, I simply pass that object literal directly on to the ZLib constructor:
exports.createZLib = function() {
if (arguments.length > 0) {
return new ZLib(arguments[0]);
}
else {
return new ZLib();
}
};
And in the constructor, I build a default options object literal if one is not supplied:
var ZLib = exports.ZLib = function() {
var options = arguments[0] || { use_dictionary: true };

this.context = options.use_dictionary ?
new ZLibContext(flatDict) : new ZLibContext();
};
Checking this out in Wireshark, I find that this still works. So I think I am ready to submit this back to the main node-spdy.

That is a good place to stop for the night. Up tomorrow, I think that I will investigate stream IDs in the context of multiple clients.


Day #51

No comments:

Post a Comment