Bug 1001022 (part 2) - Update unit tests for http2 draft12. r=mcmanus
authorNicholas Hurley <hurley@todesschaf.org>
Tue, 29 Apr 2014 18:46:05 -0700
changeset 188262 b5e2228862e84b2c6437ed478648ab157434326b
parent 188261 3125aa54ca3efa8015fcae12ffb5ead3db50d215
child 188263 68e78cfc9094234eb3733e715a52995713a2b67e
push idunknown
push userunknown
push dateunknown
reviewersmcmanus
bugs1001022
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1001022 (part 2) - Update unit tests for http2 draft12. r=mcmanus
netwerk/test/unit/test_http2.js
testing/xpcshell/node-http2/HISTORY.md
testing/xpcshell/node-http2/README.md
testing/xpcshell/node-http2/lib/http.js
testing/xpcshell/node-http2/lib/index.js
testing/xpcshell/node-http2/node_modules/http2-protocol/HISTORY.md
testing/xpcshell/node-http2/node_modules/http2-protocol/README.md
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/flow.js
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/framer.js
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/index.js
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/stream.js
testing/xpcshell/node-http2/node_modules/http2-protocol/package.json
testing/xpcshell/node-http2/node_modules/http2-protocol/test/framer.js
testing/xpcshell/node-http2/package.json
--- a/netwerk/test/unit/test_http2.js
+++ b/netwerk/test/unit/test_http2.js
@@ -20,17 +20,17 @@ posts.push(generateContent(250000));
 var md5s = ['f1b708bba17f1ce948dc979f4d7092bc',
             '2ef8d3b6c8f329318eb1a119b12622b6'];
 
 var bigListenerData = generateContent(128 * 1024);
 var bigListenerMD5 = '8f607cfdd2c87d6a7eedb657dafbd836';
 
 function checkIsHttp2(request) {
   try {
-    if (request.getResponseHeader("X-Firefox-Spdy") == "h2-11") {
+    if (request.getResponseHeader("X-Firefox-Spdy") == "h2-12") {
       if (request.getResponseHeader("X-Connection-Http2") == "yes") {
         return true;
       }
       return false; // Weird case, but the server disagrees with us
     }
   } catch (e) {
     // Nothing to do here
   }
--- a/testing/xpcshell/node-http2/HISTORY.md
+++ b/testing/xpcshell/node-http2/HISTORY.md
@@ -1,11 +1,17 @@
 Version history
 ===============
 
+### 2.5.0 (2014-04-24) ###
+
+* Upgrade to the latest draft: [draft-ietf-httpbis-http2-12]
+
+[draft-ietf-httpbis-http2-12]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-12
+
 ### 2.4.0 (2014-04-16) ###
 
 * Upgrade to the latest draft: [draft-ietf-httpbis-http2-11]
 
 [draft-ietf-httpbis-http2-11]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-11
 
 ### 2.3.0 (2014-03-12) ###
 
--- a/testing/xpcshell/node-http2/README.md
+++ b/testing/xpcshell/node-http2/README.md
@@ -1,12 +1,12 @@
 node-http2
 ==========
 
-An HTTP/2 ([draft-ietf-httpbis-http2-11](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11))
+An HTTP/2 ([draft-ietf-httpbis-http2-12](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12))
 client and server implementation for node.js.
 
 Installation
 ------------
 
 ```
 npm install http2
 ```
@@ -109,22 +109,22 @@ The developer documentation is generated
 ### Running the tests ###
 
 It's easy, just run `npm test`. The tests are written in BDD style, so they are a good starting
 point to understand the code.
 
 ### Test coverage ###
 
 To generate a code coverage report, run `npm test --coverage` (which runs very slowly, be patient).
-Code coverage summary as of version 2.3.0:
+Code coverage summary as of version 2.4.0:
 ```
-Statements   : 94% ( 392/417 )
-Branches     : 80.63% ( 129/160 )
-Functions    : 93.65% ( 59/63 )
-Lines        : 94% ( 392/417 )
+Statements   : 93.19% ( 397/426 )
+Branches     : 79.88% ( 131/164 )
+Functions    : 93.75% ( 60/64 )
+Lines        : 93.19% ( 397/426 )
 ```
 
 There's a hosted version of the detailed (line-by-line) coverage report
 [here](http://molnarg.github.io/node-http2/coverage/lcov-report/lib/).
 
 ### Logging ###
 
 Logging is turned off by default. You can turn it on by passing a bunyan logger as `log` option when
--- a/testing/xpcshell/node-http2/lib/http.js
+++ b/testing/xpcshell/node-http2/lib/http.js
@@ -116,17 +116,17 @@
 //   - **request.setSocketKeepAlive([enable], [initialDelay])**
 //
 // - **Class: http2.IncomingMessage**
 //   - **Event: 'close'**
 //   - **message.setTimeout(timeout, [callback])**
 //
 // [1]: http://nodejs.org/api/https.html
 // [2]: http://nodejs.org/api/http.html
-// [3]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-8.1.3.2
+// [3]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-8.1.3.2
 // [expect-continue]: https://github.com/http2/http2-spec/issues/18
 // [connect]: https://github.com/http2/http2-spec/issues/230
 
 // Common server and client side code
 // ==================================
 
 var net = require('net');
 var url = require('url');
@@ -199,17 +199,17 @@ function IncomingMessage(stream) {
   this._lastHeadersSeen = undefined;
 
   // * Other metadata is filled in when the headers arrive.
   stream.once('headers', this._onHeaders.bind(this));
   stream.once('end', this._onEnd.bind(this));
 }
 IncomingMessage.prototype = Object.create(PassThrough.prototype, { constructor: { value: IncomingMessage } });
 
-// [Request Header Fields](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-8.1.3.1)
+// [Request Header Fields](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-8.1.3.1)
 // * `headers` argument: HTTP/2.0 request and response header fields carry information as a series
 //   of key-value pairs. This includes the target URI for the request, the status code for the
 //   response, as well as HTTP header fields.
 IncomingMessage.prototype._onHeaders = function _onHeaders(headers) {
   // * Detects malformed headers
   this._validateHeaders(headers);
 
   // * Store the _regular_ headers in `this.headers`
@@ -511,17 +511,17 @@ function createServer(options, requestLi
 // IncomingRequest class
 // ---------------------
 
 function IncomingRequest(stream) {
   IncomingMessage.call(this, stream);
 }
 IncomingRequest.prototype = Object.create(IncomingMessage.prototype, { constructor: { value: IncomingRequest } });
 
-// [Request Header Fields](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-8.1.3.1)
+// [Request Header Fields](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-8.1.3.1)
 // * `headers` argument: HTTP/2.0 request and response header fields carry information as a series
 //   of key-value pairs. This includes the target URI for the request, the status code for the
 //   response, as well as HTTP header fields.
 IncomingRequest.prototype._onHeaders = function _onHeaders(headers) {
   // * The ":method" header field includes the HTTP method
   // * The ":scheme" header field includes the scheme portion of the target URI
   // * The ":authority" header field includes the authority portion of the target URI
   // * The ":path" header field includes the path and query parts of the target URI.
@@ -942,17 +942,17 @@ OutgoingRequest.prototype._onPromise = f
 // IncomingResponse class
 // ----------------------
 
 function IncomingResponse(stream) {
   IncomingMessage.call(this, stream);
 }
 IncomingResponse.prototype = Object.create(IncomingMessage.prototype, { constructor: { value: IncomingResponse } });
 
-// [Response Header Fields](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-8.1.3.2)
+// [Response Header Fields](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-8.1.3.2)
 // * `headers` argument: HTTP/2.0 request and response header fields carry information as a series
 //   of key-value pairs. This includes the target URI for the request, the status code for the
 //   response, as well as HTTP header fields.
 IncomingResponse.prototype._onHeaders = function _onHeaders(headers) {
   // * A single ":status" header field is defined that carries the HTTP status code field. This
   //   header field MUST be included in all responses.
   // * A client MUST treat the absence of the ":status" header field, the presence of multiple
   //   values, or an invalid value as a stream error of type PROTOCOL_ERROR.
--- a/testing/xpcshell/node-http2/lib/index.js
+++ b/testing/xpcshell/node-http2/lib/index.js
@@ -1,22 +1,22 @@
-// [node-http2][homepage] is an [HTTP/2 (draft 11)][http2] implementation for [node.js][node].
+// [node-http2][homepage] is an [HTTP/2 (draft 12)][http2] implementation for [node.js][node].
 //
 // The core of the protocol is implemented by the [http2-protocol] module. This module provides
 // two important features on top of http2-protocol:
 //
 // * Implementation of different negotiation schemes that can be used to start a HTTP2 connection.
 //   These include TLS ALPN, Upgrade and Plain TCP.
 //
 // * Providing an API very similar to the standard node.js [HTTPS module API][node-https]
 //   (which is in turn very similar to the [HTTP module API][node-http]).
 //
 // [homepage]:            https://github.com/molnarg/node-http2
 // [http2-protocol]:      https://github.com/molnarg/node-http2-protocol
-// [http2]:               http://tools.ietf.org/html/draft-ietf-httpbis-http2-11
+// [http2]:               http://tools.ietf.org/html/draft-ietf-httpbis-http2-12
 // [node]:                http://nodejs.org/
 // [node-https]:          http://nodejs.org/api/https.html
 // [node-http]:           http://nodejs.org/api/http.html
 
 module.exports   = require('./http');
 
 /*
                   HTTP API
--- a/testing/xpcshell/node-http2/node_modules/http2-protocol/HISTORY.md
+++ b/testing/xpcshell/node-http2/node_modules/http2-protocol/HISTORY.md
@@ -1,11 +1,17 @@
 Version history
 ===============
 
+### 0.12.0 (2014-04-24) ###
+
+* Upgrade to the latest draft: [draft-ietf-httpbis-http2-12][draft-12]
+
+[draft-12]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-12
+
 ### 0.11.0 (2014-04-16) ###
 
 * Upgrade to the latest draft: [draft-ietf-httpbis-http2-11][draft-11]
 
 [draft-11]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-11
 
 ### 0.10.0 (2014-03-12) ###
 
--- a/testing/xpcshell/node-http2/node_modules/http2-protocol/README.md
+++ b/testing/xpcshell/node-http2/node_modules/http2-protocol/README.md
@@ -1,12 +1,12 @@
 node-http2-protocol
 ===================
 
-An HTTP/2 ([draft-ietf-httpbis-http2-11](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11))
+An HTTP/2 ([draft-ietf-httpbis-http2-12](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12))
 framing layer implementaion for node.js.
 
 Installation
 ------------
 
 ```
 npm install http2-protocol
 ```
@@ -45,22 +45,22 @@ just run `npm run-script doc`.
 ### Running the tests ###
 
 It's easy, just run `npm test`. The tests are written in BDD style, so they are a good starting
 point to understand the code.
 
 ### Test coverage ###
 
 To generate a code coverage report, run `npm test --coverage` (it may be slow, be patient).
-Code coverage summary as of version 0.9.0:
+Code coverage summary as of version 0.12.0:
 ```
-Statements   : 91.86% ( 1276/1389 )
-Branches     : 85.62% ( 524/612 )
-Functions    : 92.31% ( 144/156 )
-Lines        : 91.83% ( 1270/1383 )
+Statements   : 91.6% ( 1352/1476 )
+Branches     : 85.15% ( 562/660 )
+Functions    : 92.5% ( 148/160 )
+Lines        : 91.69% ( 1346/1468 )
 ```
 
 There's a hosted version of the detailed (line-by-line) coverage report
 [here](http://molnarg.github.io/node-http2-protocol/coverage/lcov-report/lib/).
 
 ### Logging ###
 
 Contributors
--- a/testing/xpcshell/node-http2/node_modules/http2-protocol/lib/flow.js
+++ b/testing/xpcshell/node-http2/node_modules/http2-protocol/lib/flow.js
@@ -14,17 +14,17 @@ exports.Flow = Flow;
 // Public API
 // ----------
 
 // * **Event: 'error' (type)**: signals an error
 //
 // * **setInitialWindow(size)**: the initial flow control window size can be changed *any time*
 //   ([as described in the standard][1]) using this method
 //
-// [1]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-6.9.2
+// [1]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-6.9.2
 
 // API for child classes
 // ---------------------
 
 // * **new Flow([flowControlId])**: creating a new flow that will listen for WINDOW_UPDATES frames
 //   with the given `flowControlId` (or every update frame if not given)
 //
 // * **_send()**: called when more frames should be pushed. The child class is expected to override
--- a/testing/xpcshell/node-http2/node_modules/http2-protocol/lib/framer.js
+++ b/testing/xpcshell/node-http2/node_modules/http2-protocol/lib/framer.js
@@ -143,17 +143,17 @@ Deserializer.prototype._transform = func
       }
       this._next(COMMON_HEADER_SIZE);
     }
   }
 
   done();
 };
 
-// [Frame Header](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-4.1)
+// [Frame Header](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-4.1)
 // --------------------------------------------------------------
 //
 // HTTP/2.0 frames share a common base format consisting of an 8-byte header followed by 0 to 65535
 // bytes of data.
 //
 // Additional size limits can be set by specific application uses. HTTP limits the frame size to
 // 16,383 octets.
 //
@@ -257,41 +257,43 @@ Deserializer.commonHeader = function rea
 
 // Every frame type is registered in the following places:
 //
 // * `frameTypes`: a register of frame type codes (used by `commonHeader()`)
 // * `frameFlags`: a register of valid flags for frame types (used by `commonHeader()`)
 // * `typeSpecificAttributes`: a register of frame specific frame object attributes (used by
 //   logging code and also serves as documentation for frame objects)
 
-// [DATA Frames](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-6.1)
+// [DATA Frames](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-6.1)
 // ------------------------------------------------------------
 //
 // DATA frames (type=0x0) convey arbitrary, variable-length sequences of octets associated with a
 // stream.
 //
 // The DATA frame defines the following flags:
 //
 // * END_STREAM (0x1):
 //   Bit 1 being set indicates that this frame is the last that the endpoint will send for the
 //   identified stream.
 // * END_SEGMENT (0x2):
 //   Bit 2 being set indicates that this frame is the last for the current segment. Intermediaries
 //   MUST NOT coalesce frames across a segment boundary and MUST preserve segment boundaries when
 //   forwarding frames.
 // * PAD_LOW (0x08):
-//   Bit 5 being set indicates that the Pad Low field is present.
+//   Bit 4 being set indicates that the Pad Low field is present.
 // * PAD_HIGH (0x10):
-//   Bit 6 being set indicates that the Pad High field is present. This bit MUST NOT be set unless
+//   Bit 5 being set indicates that the Pad High field is present. This bit MUST NOT be set unless
 //   the PAD_LOW flag is also set. Endpoints that receive a frame with PAD_HIGH set and PAD_LOW
 //   cleared MUST treat this as a connection error of type PROTOCOL_ERROR.
+// * COMPRESSED (0x20):
+//   Bit 6 being set indicates that the data in the frame has been compressed with GZIP compression.
 
 frameTypes[0x0] = 'DATA';
 
-frameFlags.DATA = ['END_STREAM', 'END_SEGMENT', 'RESERVED4', 'PAD_LOW', 'PAD_HIGH'];
+frameFlags.DATA = ['END_STREAM', 'END_SEGMENT', 'RESERVED4', 'PAD_LOW', 'PAD_HIGH', 'COMPRESSED'];
 
 typeSpecificAttributes.DATA = ['data'];
 
 Serializer.DATA = function writeData(frame, buffers) {
   buffers.push(frame.data);
 };
 
 Deserializer.DATA = function readData(buffer, frame) {
@@ -302,24 +304,29 @@ Deserializer.DATA = function readData(bu
       paddingLength = (buffer.readUInt8(dataOffset) & 0xff) * 256;
       dataOffset += 1;
     }
     paddingLength += (buffer.readUInt8(dataOffset) & 0xff);
     dataOffset += 1;
   } else if (frame.flags.PAD_HIGH) {
     return 'DATA frame got PAD_HIGH without PAD_LOW';
   }
+
+  if (frame.flags.COMPRESSED) {
+    return 'DATA frame received COMPRESSED data (unsupported)';
+  }
+
   if (paddingLength) {
     frame.data = buffer.slice(dataOffset, -1 * paddingLength);
   } else {
     frame.data = buffer.slice(dataOffset);
   }
 };
 
-// [HEADERS](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-6.2)
+// [HEADERS](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-6.2)
 // --------------------------------------------------------------
 //
 // The HEADERS frame (type=0x1) allows the sender to create a stream.
 //
 // The HEADERS frame defines the following flags:
 //
 // * END_STREAM (0x1):
 //   Bit 1 being set indicates that this frame is the last that the endpoint will send for the
@@ -335,53 +342,46 @@ Deserializer.DATA = function readData(bu
 //   Bit 5 being set indicates that the Pad Low field is present.
 // * PAD_HIGH (0x10):
 //   Bit 6 being set indicates that the Pad High field is present. This bit MUST NOT be set unless
 //   the PAD_LOW flag is also set. Endpoints that receive a frame with PAD_HIGH set and PAD_LOW
 //   cleared MUST treat this as a connection error of type PROTOCOL_ERROR.
 
 frameTypes[0x1] = 'HEADERS';
 
-frameFlags.HEADERS = ['END_STREAM', 'END_SEGMENT', 'END_HEADERS', 'PAD_LOW', 'PAD_HIGH', 'PRIORITY_GROUP', 'PRIORITY_DEPENDENCY'];
+frameFlags.HEADERS = ['END_STREAM', 'END_SEGMENT', 'END_HEADERS', 'PAD_LOW', 'PAD_HIGH', 'PRIORITY'];
 
-typeSpecificAttributes.HEADERS = ['priorityGroup', 'groupWeight', 'priorityDependency', 'exclusiveDependency', 'headers', 'data'];
+typeSpecificAttributes.HEADERS = ['priorityDependency', 'priorityWeight', 'exclusiveDependency', 'headers', 'data'];
 
 //      0                   1                   2                   3
 //      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 //     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 //     | Pad High? (8) |  Pad Low? (8) |
 //     +-+-------------+---------------+-------------------------------+
-//     |R|              Priority Group Identifier? (31)                |
+//     |E|                 Stream Dependency? (31)                     |
 //     +-+-------------+-----------------------------------------------+
 //     |  Weight? (8)  |
 //     +-+-------------+-----------------------------------------------+
-//     |E|                 Stream Dependency? (31)                     |
-//     +-+-------------------------------------------------------------+
 //     |                   Header Block Fragment (*)                 ...
 //     +---------------------------------------------------------------+
 //     |                           Padding (*)                       ...
 //     +---------------------------------------------------------------+
 //
 // The payload of a HEADERS frame contains a Headers Block
 
 Serializer.HEADERS = function writeHeadersPriority(frame, buffers) {
-  if (frame.flags.PRIORITY_GROUP) {
+  if (frame.flags.PRIORITY) {
     var buffer = new Buffer(5);
-    assert((0 <= frame.priorityGroup) && (frame.priorityGroup <= 0x7fffffff), frame.priorityGroup);
-    buffer.writeUInt32BE(frame.priorityGroup, 0);
-    assert((0 <= frame.groupWeight) && (frame.groupWeight <= 0xff), frame.groupWeight);
-    buffer.writeUInt8(frame.groupWeight, 4);
-    buffers.push(buffer);
-  } else if (frame.flags.PRIORITY_DEPENDENCY) {
-    var buffer = new Buffer(4);
     assert((0 <= frame.priorityDependency) && (frame.priorityDependency <= 0x7fffffff), frame.priorityDependency);
     buffer.writeUInt32BE(frame.priorityDependency, 0);
     if (frame.exclusiveDependency) {
       buffer[0] |= 0x80;
     }
+    assert((0 <= frame.priorityWeight) && (frame.priorityWeight <= 0xff), frame.priorityWeight);
+    buffer.writeUInt8(frame.priorityWeight, 4);
     buffers.push(buffer);
   }
   buffers.push(frame.data);
 };
 
 Deserializer.HEADERS = function readHeadersPriority(buffer, frame) {
   var dataOffset = 0;
   var paddingLength = 0;
@@ -391,109 +391,80 @@ Deserializer.HEADERS = function readHead
       dataOffset += 1;
     }
     paddingLength += (buffer.readUInt8(dataOffset) & 0xff);
     dataOffset += 1;
   } else if (frame.flags.PAD_HIGH) {
     return 'HEADERS frame got PAD_HIGH without PAD_LOW';
   }
 
-  if (frame.flags.PRIORITY_GROUP) {
-    if (frame.flags.PRIORITY_DEPENDENCY) {
-      return 'HEADERS frame got both PRIORITY_GROUP and PRIORITY_DEPENDENCY';
-    }
-    frame.priorityGroup = buffer.readUInt32BE(dataOffset) & 0x7fffffff;
-    dataOffset += 4;
-    frame.groupWeight = buffer.readUInt8(dataOffset);
-    dataOffset += 1;
-  } else if (frame.flags.PRIORITY_DEPENDENCY) {
+  if (frame.flags.PRIORITY) {
     var dependencyData = new Buffer(4);
     buffer.copy(dependencyData, 0, dataOffset, dataOffset + 4);
     dataOffset += 4;
     frame.exclusiveDependency = !!(dependencyData[0] & 0x80);
     dependencyData[0] &= 0x7f;
     frame.priorityDependency = dependencyData.readUInt32BE(0);
+    frame.priorityWeight = buffer.readUInt8(dataOffset);
+    dataOffset += 1;
   }
 
   if (paddingLength) {
     frame.data = buffer.slice(dataOffset, -1 * paddingLength);
   } else {
     frame.data = buffer.slice(dataOffset);
   }
 };
 
-// [PRIORITY](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-6.3)
+// [PRIORITY](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-6.3)
 // -------------------------------------------------------
 //
 // The PRIORITY frame (type=0x2) specifies the sender-advised priority of a stream.
 //
 // The PRIORITY frame does not define any flags.
 
 frameTypes[0x2] = 'PRIORITY';
 
-frameFlags.PRIORITY = ['RESERVED1', 'RESERVED2', 'RESERVED4', 'RESERVED8', 'RESERVED16', 'PRIORITY_GROUP', 'PRIORITY_DEPENDENCY'];
+frameFlags.PRIORITY = [];
 
-typeSpecificAttributes.PRIORITY = ['priorityGroup', 'groupWeight', 'priorityDependency', 'exclusiveDependency'];
+typeSpecificAttributes.PRIORITY = ['priorityDependency', 'priorityWeight', 'exclusiveDependency'];
 
 //      0                   1                   2                   3
 //      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 //     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//     |R|              Priority Group Identifier? (31)                |
+//     |E|                 Stream Dependency? (31)                     |
 //     +-+-------------+-----------------------------------------------+
 //     |  Weight? (8)  |
-//     +-+-------------+-----------------------------------------------+
-//     |E|                 Stream Dependency? (31)                     |
-//     +-+-------------------------------------------------------------+
+//     +-+-------------+
 //
-// The payload of a PRIORITY frame contains a single reserved bit and a 31-bit priority.
+// The payload of a PRIORITY frame contains an exclusive bit, a 31-bit dependency, and an 8-bit weight
 
 Serializer.PRIORITY = function writePriority(frame, buffers) {
-  var buffer;
-
-  assert((frame.flags.PRIORITY_GROUP || frame.flags.PRIORITY_DEPENDENCY) &&
-          !(frame.flags.PRIORITY_GROUP && frame.flags.PRIORITY_DEPENDENCY),
-         frame.flags.PRIORITY_GROUP && frame.flags.PRIORITY_DEPENDENCY);
-
-  if (frame.flags.PRIORITY_GROUP) {
-    buffer = new Buffer(5);
-    assert((0 <= frame.priorityGroup) && (frame.priorityGroup <= 0x7fffffff), frame.priorityGroup);
-    buffer.writeUInt32BE(frame.priorityGroup, 0);
-    assert((0 <= frame.groupWeight) && (frame.groupWeight <= 0xff), frame.groupWeight);
-    buffer.writeUInt8(frame.groupWeight, 4);
-  } else { // frame.flags.PRIORITY_DEPENDENCY
-    buffer = new Buffer(4);
-    assert((0 <= frame.priorityDependency) && (frame.priorityDependency <= 0x7fffffff), frame.priorityDependency);
-    buffer.writeUInt32BE(frame.priorityDependency, 0);
-    if (frame.exclusiveDependency) {
-      buffer[0] |= 0x80;
-    }
+  var buffer = new Buffer(5);
+  assert((0 <= frame.priorityDependency) && (frame.priorityDependency <= 0x7fffffff), frame.priorityDependency);
+  buffer.writeUInt32BE(frame.priorityDependency, 0);
+  if (frame.exclusiveDependency) {
+    buffer[0] |= 0x80;
   }
+  assert((0 <= frame.priorityWeight) && (frame.priorityWeight <= 0xff), frame.priorityWeight);
+  buffer.writeUInt8(frame.priorityWeight, 4);
 
   buffers.push(buffer);
 };
 
 Deserializer.PRIORITY = function readPriority(buffer, frame) {
-  if (frame.flags.PRIORITY_GROUP) {
-    if (frame.flags.PRIORITY_DEPENDENCY) {
-      return 'PRIORITY frame got both PRIORITY_GROUP and PRIORITY_DEPENDENCY';
-    }
-    frame.priorityGroup = buffer.readUInt32BE(0) & 0x7fffffff;
-    frame.groupWeight = buffer.readUInt8(4);
-  } else if (frame.flags.PRIORITY_DEPENDENCY) {
-    var dependencyData = new Buffer(4);
-    buffer.copy(dependencyData, 0, 0, 4);
-    frame.exclusiveDependency = !!(dependencyData[0] & 0x80);
-    dependencyData[0] &= 0x7f;
-    frame.priorityDependency = dependencyData.readUInt32BE(0);
-  } else {
-    return 'PRIORITY frame got neither PRIORITY_GROUP nor PRIORITY_DEPENDENCY';
-  }
+  var dependencyData = new Buffer(4);
+  buffer.copy(dependencyData, 0, 0, 4);
+  frame.exclusiveDependency = !!(dependencyData[0] & 0x80);
+  dependencyData[0] &= 0x7f;
+  frame.priorityDependency = dependencyData.readUInt32BE(0);
+  frame.priorityWeight = buffer.readUInt8(4);
 };
 
-// [RST_STREAM](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-6.4)
+// [RST_STREAM](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-6.4)
 // -----------------------------------------------------------
 //
 // The RST_STREAM frame (type=0x3) allows for abnormal termination of a stream.
 //
 // No type-flags are defined.
 
 frameTypes[0x3] = 'RST_STREAM';
 
@@ -517,17 +488,17 @@ Serializer.RST_STREAM = function writeRs
   buffer.writeUInt32BE(code, 0);
   buffers.push(buffer);
 };
 
 Deserializer.RST_STREAM = function readRstStream(buffer, frame) {
   frame.error = errorCodes[buffer.readUInt32BE(0)];
 };
 
-// [SETTINGS](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-6.5)
+// [SETTINGS](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-6.5)
 // -------------------------------------------------------
 //
 // The SETTINGS frame (type=0x4) conveys configuration parameters that affect how endpoints
 // communicate.
 //
 // The SETTINGS frame defines the following flag:
 
 // * ACK (0x1):
@@ -615,25 +586,31 @@ var definedSettings = [];
 definedSettings[1] = { name: 'SETTINGS_HEADER_TABLE_SIZE', flag: false };
 
 // * SETTINGS_ENABLE_PUSH (2):
 //   This setting can be use to disable server push. An endpoint MUST NOT send a PUSH_PROMISE frame
 //   if it receives this setting set to a value of 0. The default value is 1, which indicates that
 //   push is permitted.
 definedSettings[2] = { name: 'SETTINGS_ENABLE_PUSH', flag: true };
 
-// * SETTINGS_MAX_CONCURRENT_STREAMS (4):
+// * SETTINGS_MAX_CONCURRENT_STREAMS (3):
 //   indicates the maximum number of concurrent streams that the sender will allow.
 definedSettings[3] = { name: 'SETTINGS_MAX_CONCURRENT_STREAMS', flag: false };
 
-// * SETTINGS_INITIAL_WINDOW_SIZE (7):
+// * SETTINGS_INITIAL_WINDOW_SIZE (4):
 //   indicates the sender's initial stream window size (in bytes) for new streams.
 definedSettings[4] = { name: 'SETTINGS_INITIAL_WINDOW_SIZE', flag: false };
 
-// [PUSH_PROMISE](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-6.6)
+// * SETTINGS_COMPRESS_DATA (5):
+//   this setting is used to enable GZip compression of DATA frames. A value of 1 indicates that
+//   DATA frames MAY be compressed. A value of 0 indicates that compression is not permitted.
+//   The initial value is 0.
+definedSettings[5] = { name: 'SETTINGS_COMPRESS_DATA', flag: true };
+
+// [PUSH_PROMISE](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-6.6)
 // ---------------------------------------------------------------
 //
 // The PUSH_PROMISE frame (type=0x5) is used to notify the peer endpoint in advance of streams the
 // sender intends to initiate.
 //
 // The PUSH_PROMISE frame defines the following flags:
 //
 // * END_PUSH_PROMISE (0x4):
@@ -686,17 +663,17 @@ Deserializer.PUSH_PROMISE = function rea
   dataOffset += 4;
   if (paddingLength) {
     frame.data = buffer.slice(dataOffset, -1 * paddingLength);
   } else {
     frame.data = buffer.slice(dataOffset);
   }
 };
 
-// [PING](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-6.7)
+// [PING](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-6.7)
 // -----------------------------------------------
 //
 // The PING frame (type=0x6) is a mechanism for measuring a minimal round-trip time from the
 // sender, as well as determining whether an idle connection is still functional.
 //
 // The PING frame defines one type-specific flag:
 //
 // * ACK (0x1):
@@ -716,17 +693,17 @@ Serializer.PING = function writePing(fra
 
 Deserializer.PING = function readPing(buffer, frame) {
   if (buffer.length !== 8) {
     return 'FRAME_SIZE_ERROR';
   }
   frame.data = buffer;
 };
 
-// [GOAWAY](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-6.8)
+// [GOAWAY](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-6.8)
 // ---------------------------------------------------
 //
 // The GOAWAY frame (type=0x7) informs the remote peer to stop creating streams on this connection.
 //
 // The GOAWAY frame does not define any flags.
 
 frameTypes[0x7] = 'GOAWAY';
 
@@ -763,17 +740,17 @@ Serializer.GOAWAY = function writeGoaway
   buffers.push(buffer);
 };
 
 Deserializer.GOAWAY = function readGoaway(buffer, frame) {
   frame.last_stream = buffer.readUInt32BE(0) & 0x7fffffff;
   frame.error = errorCodes[buffer.readUInt32BE(4)];
 };
 
-// [WINDOW_UPDATE](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-6.9)
+// [WINDOW_UPDATE](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-6.9)
 // -----------------------------------------------------------------
 //
 // The WINDOW_UPDATE frame (type=0x8) is used to implement flow control.
 //
 // The WINDOW_UPDATE frame does not define any flags.
 
 frameTypes[0x8] = 'WINDOW_UPDATE';
 
@@ -798,17 +775,17 @@ Serializer.WINDOW_UPDATE = function writ
 
 Deserializer.WINDOW_UPDATE = function readWindowUpdate(buffer, frame) {
   if (buffer.length !== WINDOW_UPDATE_PAYLOAD_SIZE) {
     return 'FRAME_SIZE_ERROR';
   }
   frame.window_size = buffer.readUInt32BE(0) & 0x7fffffff;
 };
 
-// [CONTINUATION](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-6.10)
+// [CONTINUATION](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-6.10)
 // ------------------------------------------------------------
 //
 // The CONTINUATION frame (type=0x9) is used to continue a sequence of header block fragments.
 //
 // The CONTINUATION frame defines the following flag:
 //
 // * END_HEADERS (0x4):
 //   The END_HEADERS bit indicates that this frame ends the sequence of header block fragments
@@ -845,17 +822,17 @@ Deserializer.CONTINUATION = function rea
   }
   if (paddingLength) {
     frame.data = buffer.slice(dataOffset, -1 * paddingLength);
   } else {
     frame.data = buffer.slice(dataOffset);
   }
 };
 
-// [ALTSVC](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-6.11)
+// [ALTSVC](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-6.11)
 // ------------------------------------------------------------
 //
 // The ALTSVC frame (type=0xA) advertises the availability of an alternative service to the client.
 //
 // The ALTSVC frame does not define any flags.
 
 frameTypes[0xA] = 'ALTSVC';
 
@@ -934,17 +911,37 @@ Deserializer.ALTSVC = function readAltSv
   frame.port = buffer.readUInt16BE(4);
   var pidLength = buffer.readUInt8(7);
   frame.protocolID = buffer.toString('ascii', 8, 8 + pidLength);
   var hostLength = buffer.readUInt8(8 + pidLength);
   frame.host = buffer.toString('ascii', 9 + pidLength, 9 + pidLength + hostLength);
   frame.origin = buffer.toString('ascii', 9 + pidLength + hostLength);
 };
 
-// [Error Codes](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-7)
+// [BLOCKED](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-6.12)
+// ------------------------------------------------------------
+//
+// The BLOCKED frame (type=0xB) indicates that the sender is unable to send data
+// due to a closed flow control window.
+//
+// The BLOCKED frame does not define any flags and contains no payload.
+
+frameTypes[0xB] = 'BLOCKED';
+
+frameFlags.BLOCKED = [];
+
+typeSpecificAttributes.BLOCKED = [];
+
+Serializer.BLOCKED = function writeBlocked(frame, buffers) {
+};
+
+Deserializer.BLOCKED = function readBlocked(buffer, frame) {
+};
+
+// [Error Codes](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-7)
 // ------------------------------------------------------------
 
 var errorCodes = [
   'NO_ERROR',
   'PROTOCOL_ERROR',
   'INTERNAL_ERROR',
   'FLOW_CONTROL_ERROR',
   'SETTINGS_TIMEOUT',
--- a/testing/xpcshell/node-http2/node_modules/http2-protocol/lib/index.js
+++ b/testing/xpcshell/node-http2/node_modules/http2-protocol/lib/index.js
@@ -1,9 +1,9 @@
-// [node-http2-protocol][homepage] is an implementation of the [HTTP/2 (draft 11)][http2]
+// [node-http2-protocol][homepage] is an implementation of the [HTTP/2 (draft 12)][http2]
 // framing layer for [node.js][node].
 //
 // The main building blocks are [node.js streams][node-stream] that are connected through pipes.
 //
 // The main components are:
 //
 // * [Endpoint](endpoint.html): represents an HTTP/2 endpoint (client or server). It's
 //   responsible for the the first part of the handshake process (sending/receiving the
@@ -23,26 +23,26 @@
 //
 // * [Compressor and Decompressor](compressor.html): compression and decompression of HEADER and
 //   PUSH_PROMISE frames
 //
 // * [Serializer and Deserializer](framer.html): the lowest layer in the stack that transforms
 //   between the binary and the JavaScript object representation of HTTP/2 frames
 //
 // [homepage]:            https://github.com/molnarg/node-http2
-// [http2]:               http://tools.ietf.org/html/draft-ietf-httpbis-http2-11
-// [http2-connheader]:    http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-3.5
-// [http2-stream]:        http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-5
-// [http2-streamstate]:   http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-5.1
+// [http2]:               http://tools.ietf.org/html/draft-ietf-httpbis-http2-12
+// [http2-connheader]:    http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-3.5
+// [http2-stream]:        http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-5
+// [http2-streamstate]:   http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-5.1
 // [node]:                http://nodejs.org/
 // [node-stream]:         http://nodejs.org/api/stream.html
 // [node-https]:          http://nodejs.org/api/https.html
 // [node-http]:           http://nodejs.org/api/http.html
 
-exports.ImplementedVersion = 'h2-11';
+exports.ImplementedVersion = 'h2-12';
 
 exports.Endpoint = require('./endpoint').Endpoint;
 
 /* Bunyan serializers exported by submodules that are worth adding when creating a logger. */
 exports.serializers = {};
 var modules = ['./framer', './compressor', './flow', './connection', './stream', './endpoint'];
 modules.map(require).forEach(function(module) {
   for (var name in module.serializers) {
--- a/testing/xpcshell/node-http2/node_modules/http2-protocol/lib/stream.js
+++ b/testing/xpcshell/node-http2/node_modules/http2-protocol/lib/stream.js
@@ -222,16 +222,18 @@ Stream.prototype._writeUpstream = functi
   if (frame.type === 'HEADERS') {
     this._onHeaders(frame);
   } else if (frame.type === 'PUSH_PROMISE') {
     this._onPromise(frame);
   } else if (frame.type === 'PRIORITY') {
     this._onPriority(frame);
   } else if (frame.type === 'ALTSVC') {
     // TODO
+  } else if (frame.type === 'BLOCKED') {
+    // TODO
   }
 
   // * If it's an invalid stream level frame, emit error
   else if ((frame.type !== 'DATA') &&
            (frame.type !== 'WINDOW_UPDATE') &&
            (frame.type !== 'RST_STREAM')) {
     this._log.error({ frame: frame }, 'Invalid stream level frame');
     this.emit('error', 'PROTOCOL_ERROR');
@@ -319,17 +321,17 @@ Stream.prototype._finishing = function _
     this._log.debug({ frame: lastFrame }, 'Marking last frame with END_STREAM flag.');
     lastFrame.flags.END_STREAM = true;
     this._transition(true, endFrame);
   } else {
     this._pushUpstream(endFrame);
   }
 };
 
-// [Stream States](http://tools.ietf.org/html/draft-ietf-httpbis-http2-11#section-5.1)
+// [Stream States](http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-5.1)
 // ----------------
 //
 //                           +--------+
 //                     PP    |        |    PP
 //                  ,--------|  idle  |--------.
 //                 /         |        |         \
 //                v          +--------+          v
 //         +----------+          |           +----------+
@@ -379,26 +381,27 @@ function activeState(state) {
 // `_transition` is called every time there's an incoming or outgoing frame. It manages state
 // transitions, and detects stream errors. A stream error is always caused by a frame that is not
 // allowed in the current state.
 Stream.prototype._transition = function transition(sending, frame) {
   var receiving = !sending;
   var connectionError;
   var streamError;
 
-  var DATA = false, HEADERS = false, PRIORITY = false, ALTSVC = false;
+  var DATA = false, HEADERS = false, PRIORITY = false, ALTSVC = false, BLOCKED = false;
   var RST_STREAM = false, PUSH_PROMISE = false, WINDOW_UPDATE = false;
   switch(frame.type) {
     case 'DATA'         : DATA          = true; break;
     case 'HEADERS'      : HEADERS       = true; break;
     case 'PRIORITY'     : PRIORITY      = true; break;
     case 'RST_STREAM'   : RST_STREAM    = true; break;
     case 'PUSH_PROMISE' : PUSH_PROMISE  = true; break;
     case 'WINDOW_UPDATE': WINDOW_UPDATE = true; break;
     case 'ALTSVC'       : ALTSVC        = true; break;
+    case 'BLOCKED'      : BLOCKED       = true; break;
   }
 
   var previousState = this.state;
 
   switch (this.state) {
     // All streams start in the **idle** state. In this state, no frames have been exchanged.
     //
     // * Sending or receiving a HEADERS frame causes the stream to become "open".
@@ -446,17 +449,17 @@ Stream.prototype._transition = function 
     // * Receiving a HEADERS frame causes the stream to transition to "half closed (local)".
     // * An endpoint MAY send PRIORITY frames in this state to reprioritize the stream.
     // * Receiving any other type of frame MUST be treated as a stream error of type PROTOCOL_ERROR.
     case 'RESERVED_REMOTE':
       if (RST_STREAM) {
         this._setState('CLOSED');
       } else if (receiving && HEADERS) {
         this._setState('HALF_CLOSED_LOCAL');
-      } else if (sending && PRIORITY) {
+      } else if (BLOCKED || (sending && PRIORITY)) {
         /* No state change */
       } else {
         connectionError = 'PROTOCOL_ERROR';
       }
       break;
 
     // The **open** state is where both peers can send frames. In this state, sending peers observe
     // advertised stream level flow control limits.
@@ -481,17 +484,17 @@ Stream.prototype._transition = function 
     //
     // * A stream transitions from this state to "closed" when a frame that contains a END_STREAM
     //   flag is received, or when either peer sends a RST_STREAM frame.
     // * An endpoint MAY send or receive PRIORITY frames in this state to reprioritize the stream.
     // * WINDOW_UPDATE can be sent by a peer that has sent a frame bearing the END_STREAM flag.
     case 'HALF_CLOSED_LOCAL':
       if (RST_STREAM || (receiving && frame.flags.END_STREAM)) {
         this._setState('CLOSED');
-      } else if (receiving || (sending && (PRIORITY || WINDOW_UPDATE))) {
+      } else if (BLOCKED || ALTSVC ||receiving || (sending && (PRIORITY || WINDOW_UPDATE))) {
         /* No state change */
       } else {
         connectionError = 'PROTOCOL_ERROR';
       }
       break;
 
     // A stream that is **half closed (remote)** is no longer being used by the peer to send frames.
     // In this state, an endpoint is no longer obligated to maintain a receiver flow control window
@@ -501,17 +504,17 @@ Stream.prototype._transition = function 
     //   respond with a stream error of type STREAM_CLOSED.
     // * A stream can transition from this state to "closed" by sending a frame that contains a
     //   END_STREAM flag, or when either peer sends a RST_STREAM frame.
     // * An endpoint MAY send or receive PRIORITY frames in this state to reprioritize the stream.
     // * A receiver MAY receive a WINDOW_UPDATE frame on a "half closed (remote)" stream.
     case 'HALF_CLOSED_REMOTE':
       if (RST_STREAM || (sending && frame.flags.END_STREAM)) {
         this._setState('CLOSED');
-      } else if (sending || (receiving && (WINDOW_UPDATE || PRIORITY))) {
+      } else if (BLOCKED || ALTSVC ||sending || (receiving && (WINDOW_UPDATE || PRIORITY))) {
         /* No state change */
       } else {
         connectionError = 'PROTOCOL_ERROR';
       }
       break;
 
     // The **closed** state is the terminal state.
     //
--- a/testing/xpcshell/node-http2/node_modules/http2-protocol/package.json
+++ b/testing/xpcshell/node-http2/node_modules/http2-protocol/package.json
@@ -1,11 +1,11 @@
 {
   "name": "http2-protocol",
-  "version": "0.11.0",
+  "version": "0.12.0",
   "description": "A JavaScript implementation of the HTTP/2 framing layer",
   "main": "lib/index.js",
   "engines" : {
     "node" : "0.10.x"
   },
   "devDependencies": {
     "istanbul": "*",
     "chai": "*",
--- a/testing/xpcshell/node-http2/node_modules/http2-protocol/test/framer.js
+++ b/testing/xpcshell/node-http2/node_modules/http2-protocol/test/framer.js
@@ -17,116 +17,87 @@ var frame_types = {
   WINDOW_UPDATE: ['window_size'],
   CONTINUATION:  ['data']
 };
 
 var test_frames = [{
   frame: {
     type: 'DATA',
     flags: { END_STREAM: false, END_SEGMENT: false, RESERVED4: false,
-             PAD_LOW: false, PAD_HIGH: false },
+             PAD_LOW: false, PAD_HIGH: false, COMPRESSED: false },
     stream: 10,
 
     data: new Buffer('12345678', 'hex')
   },
   // length + type + flags + stream +   content
   buffer: new Buffer('0004' + '00' + '00' + '0000000A' +   '12345678', 'hex')
 
 }, {
   frame: {
     type: 'HEADERS',
     flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
-             PAD_LOW: false, PAD_HIGH: false, PRIORITY_GROUP: false,
-             PRIORITY_DEPENDENCY: false },
+             PAD_LOW: false, PAD_HIGH: false, PRIORITY: false },
     stream: 15,
 
     data: new Buffer('12345678', 'hex')
   },
   buffer: new Buffer('0004' + '01' + '00' + '0000000F' +   '12345678', 'hex')
 
 }, {
   frame: {
     type: 'HEADERS',
     flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
-             PAD_LOW: false, PAD_HIGH: false, PRIORITY_GROUP: true,
-             PRIORITY_DEPENDENCY: false },
+             PAD_LOW: false, PAD_HIGH: false, PRIORITY: true },
     stream: 15,
-    priorityGroup: 23,
-    groupWeight: 5,
-
-    data: new Buffer('12345678', 'hex')
-  },
-  buffer: new Buffer('0009' + '01' + '20' + '0000000F' + '00000017' + '05' + '12345678', 'hex')
-
-}, {
-  frame: {
-    type: 'HEADERS',
-    flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
-             PAD_LOW: false, PAD_HIGH: false, PRIORITY_GROUP: false,
-             PRIORITY_DEPENDENCY: true },
-    stream: 15,
-    priorityDependency: 23,
+    priorityDependency: 10,
+    priorityWeight: 5,
     exclusiveDependency: false,
 
     data: new Buffer('12345678', 'hex')
   },
-  buffer: new Buffer('0008' + '01' + '40' + '0000000F' + '00000017' + '12345678', 'hex')
+  buffer: new Buffer('0009' + '01' + '20' + '0000000F' + '0000000A' + '05' + '12345678', 'hex')
+
 
 }, {
   frame: {
     type: 'HEADERS',
     flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
-             PAD_LOW: false, PAD_HIGH: false, PRIORITY_GROUP: false,
-             PRIORITY_DEPENDENCY: true },
+             PAD_LOW: false, PAD_HIGH: false, PRIORITY: true },
     stream: 15,
-    priorityDependency: 23,
+    priorityDependency: 10,
+    priorityWeight: 5,
     exclusiveDependency: true,
 
     data: new Buffer('12345678', 'hex')
   },
-  buffer: new Buffer('0008' + '01' + '40' + '0000000F' + '80000017' + '12345678', 'hex')
+  buffer: new Buffer('0009' + '01' + '20' + '0000000F' + '8000000A' + '05' + '12345678', 'hex')
 
 }, {
   frame: {
     type: 'PRIORITY',
-    flags: { RESERVED1: false, RESERVED2: false, RESERVED4: false,
-             RESERVED8: false, RESERVED16: false, PRIORITY_GROUP: true,
-             PRIORITY_DEPENDENCY: false },
+    flags: { },
     stream: 10,
 
-    priorityGroup: 23,
-    groupWeight: 5
+    priorityDependency: 9,
+    priorityWeight: 5,
+    exclusiveDependency: false
   },
-  buffer: new Buffer('0005' + '02' + '20' + '0000000A' + '00000017' + '05', 'hex')
+  buffer: new Buffer('0005' + '02' + '00' + '0000000A' + '00000009' + '05', 'hex')
 
 }, {
   frame: {
     type: 'PRIORITY',
-    flags: { RESERVED1: false, RESERVED2: false, RESERVED4: false,
-             RESERVED8: false, RESERVED16: false, PRIORITY_GROUP: false,
-             PRIORITY_DEPENDENCY: true },
+    flags: { },
     stream: 10,
 
-    priorityDependency: 23,
-    exclusiveDependency: false
-  },
-  buffer: new Buffer('0004' + '02' + '40' + '0000000A' + '00000017', 'hex')
-
-}, {
-  frame: {
-    type: 'PRIORITY',
-    flags: { RESERVED1: false, RESERVED2: false, RESERVED4: false,
-             RESERVED8: false, RESERVED16: false, PRIORITY_GROUP: false,
-             PRIORITY_DEPENDENCY: true },
-    stream: 10,
-
-    priorityDependency: 23,
+    priorityDependency: 9,
+    priorityWeight: 5,
     exclusiveDependency: true
   },
-  buffer: new Buffer('0004' + '02' + '40' + '0000000A' + '80000017', 'hex')
+  buffer: new Buffer('0005' + '02' + '00' + '0000000A' + '80000009' + '05', 'hex')
 
 }, {
   frame: {
     type: 'RST_STREAM',
     flags: { },
     stream: 10,
 
     error: 'INTERNAL_ERROR'
@@ -138,23 +109,25 @@ var test_frames = [{
     type: 'SETTINGS',
     flags: { ACK: false },
     stream: 10,
 
     settings: {
       SETTINGS_HEADER_TABLE_SIZE: 0x12345678,
       SETTINGS_ENABLE_PUSH: true,
       SETTINGS_MAX_CONCURRENT_STREAMS: 0x01234567,
-      SETTINGS_INITIAL_WINDOW_SIZE:    0x89ABCDEF
+      SETTINGS_INITIAL_WINDOW_SIZE:    0x89ABCDEF,
+      SETTINGS_COMPRESS_DATA: true
     }
   },
-  buffer: new Buffer('0014' + '04' + '00' + '0000000A' +   '01' + '12345678' +
+  buffer: new Buffer('0019' + '04' + '00' + '0000000A' +   '01' + '12345678' +
                                                            '02' + '00000001' +
                                                            '03' + '01234567' +
-                                                           '04' + '89ABCDEF', 'hex')
+                                                           '04' + '89ABCDEF' +
+                                                           '05' + '00000001', 'hex')
 
 }, {
   frame: {
     type: 'PUSH_PROMISE',
     flags: { RESERVED1: false, RESERVED2: false, END_PUSH_PROMISE: false,
              PAD_LOW: false, PAD_HIGH: false },
     stream: 15,
 
@@ -225,87 +198,79 @@ var test_frames = [{
 
     maxAge: 31536000,
     port: 4443,
     protocolID: "h2",
     host: "altsvc.example.com",
     origin: "https://onlyme.example.com"
   },
   buffer: new Buffer('0037' + '0A' + '00' + '00000000' + '01E13380' + '115B' + '00' + '02' + '6832' + '12' + '616C747376632E6578616D706C652E636F6D' + '68747470733A2F2F6F6E6C796D652E6578616D706C652E636F6D', 'hex')
+
+}, {
+  frame: {
+    type: 'BLOCKED',
+    flags: { },
+    stream: 10
+  },
+  buffer: new Buffer('0000' + '0B' + '00' + '0000000A', 'hex')
 }];
 
 var deserializer_test_frames = test_frames.slice(0);
 var padded_test_frames = [{
   frame: {
     type: 'DATA',
     flags: { END_STREAM: false, END_SEGMENT: false, RESERVED4: false,
-             PAD_LOW: true, PAD_HIGH: false },
+             PAD_LOW: true, PAD_HIGH: false, COMPRESSED: false },
     stream: 10,
     data: new Buffer('12345678', 'hex')
   },
   // length + type + flags + stream + pad_low control + content + padding
   buffer: new Buffer('000B' + '00' + '08' + '0000000A' + '06' + '12345678' + '000000000000', 'hex')
 
 }, {
   frame: {
     type: 'HEADERS',
     flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
-             PAD_LOW: true, PAD_HIGH: false, PRIORITY_GROUP: false,
-             PRIORITY_DEPENDENCY: false },
+             PAD_LOW: true, PAD_HIGH: false, PRIORITY: false },
     stream: 15,
 
     data: new Buffer('12345678', 'hex')
   },
   // length + type + flags + stream + pad_low control + data + padding
   buffer: new Buffer('000B' + '01' + '08' + '0000000F' + '06' + '12345678' + '000000000000', 'hex')
 
 }, {
   frame: {
     type: 'HEADERS',
     flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
-             PAD_LOW: true, PAD_HIGH: false, PRIORITY_GROUP: true,
-             PRIORITY_DEPENDENCY: false },
+             PAD_LOW: true, PAD_HIGH: false, PRIORITY: true },
     stream: 15,
-    priorityGroup: 23,
-    groupWeight: 5,
+    priorityDependency: 10,
+    priorityWeight: 5,
+    exclusiveDependency: false,
 
     data: new Buffer('12345678', 'hex')
   },
-  // length + type + flags + stream + pad_low control + priority group + group weight + data + padding
-  buffer: new Buffer('0010' + '01' + '28' + '0000000F' + '06' + '00000017' + '05' + '12345678' + '000000000000', 'hex')
+  // length + type + flags + stream + pad_low control + priority dependency + priority weight + data + padding
+  buffer: new Buffer('0010' + '01' + '28' + '0000000F' + '06' + '0000000A' + '05' + '12345678' + '000000000000', 'hex')
 
 }, {
   frame: {
     type: 'HEADERS',
     flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
-             PAD_LOW: true, PAD_HIGH: false, PRIORITY_GROUP: false,
-             PRIORITY_DEPENDENCY: true },
+             PAD_LOW: true, PAD_HIGH: false, PRIORITY: true },
     stream: 15,
-    priorityDependency: 23,
-    exclusiveDependency: false,
-
-    data: new Buffer('12345678', 'hex')
-  },
-  // length + type + flags + stream + pad_low control + priority dependency + data + padding
-  buffer: new Buffer('000F' + '01' + '48' + '0000000F' + '06' + '00000017' + '12345678' + '000000000000', 'hex')
-
-}, {
-  frame: {
-    type: 'HEADERS',
-    flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
-             PAD_LOW: true, PAD_HIGH: false, PRIORITY_GROUP: false,
-             PRIORITY_DEPENDENCY: true },
-    stream: 15,
-    priorityDependency: 23,
+    priorityDependency: 10,
+    priorityWeight: 5,
     exclusiveDependency: true,
 
     data: new Buffer('12345678', 'hex')
   },
-  // length + type + flags + stream + pad_low control + priority dependency + data + padding
-  buffer: new Buffer('000F' + '01' + '48' + '0000000F' + '06' + '80000017' + '12345678' + '000000000000', 'hex')
+  // length + type + flags + stream + pad_low control + priority dependency + priority weight + data + padding
+  buffer: new Buffer('0010' + '01' + '28' + '0000000F' + '06' + '8000000A' + '05' + '12345678' + '000000000000', 'hex')
 
 }, {
   frame: {
     type: 'CONTINUATION',
     flags: { RESERVED1: false, RESERVED2: false, END_HEADERS: true,
              PAD_LOW: true, PAD_HIGH: false },
     stream: 10,
 
--- a/testing/xpcshell/node-http2/package.json
+++ b/testing/xpcshell/node-http2/package.json
@@ -1,18 +1,18 @@
 {
   "name": "http2",
-  "version": "2.3.0",
+  "version": "2.5.0",
   "description": "An HTTP/2 client and server implementation",
   "main": "lib/index.js",
   "engines" : {
     "node" : ">=0.10.19"
   },
   "dependencies": {
-    "http2-protocol": "0.11.x"
+    "http2-protocol": "0.12.x"
   },
   "devDependencies": {
     "istanbul": "*",
     "chai": "*",
     "mocha": "*",
     "docco": "*",
     "bunyan": "*"
   },