mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
Bug 1046892 part 2 - HTTP/2 draft 14 test updates r=mcmanus
This commit is contained in:
parent
8446acda81
commit
41eb41171a
@ -25,7 +25,7 @@ var bigListenerMD5 = '8f607cfdd2c87d6a7eedb657dafbd836';
|
||||
|
||||
function checkIsHttp2(request) {
|
||||
try {
|
||||
if (request.getResponseHeader("X-Firefox-Spdy") == "h2-13") {
|
||||
if (request.getResponseHeader("X-Firefox-Spdy") == "h2-14") {
|
||||
if (request.getResponseHeader("X-Connection-Http2") == "yes") {
|
||||
return true;
|
||||
}
|
||||
|
5
testing/xpcshell/node-http2/.travis.yml
Normal file
5
testing/xpcshell/node-http2/.travis.yml
Normal file
@ -0,0 +1,5 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.11"
|
||||
- "0.10"
|
||||
|
@ -1,6 +1,16 @@
|
||||
Version history
|
||||
===============
|
||||
|
||||
### 2.7.1 (2014-08-01) ###
|
||||
|
||||
* Require protocol 0.14.1 (bugfix release)
|
||||
|
||||
### 2.7.0 (2014-07-31) ###
|
||||
|
||||
* Upgrade to the latest draft: [draft-ietf-httpbis-http2-14]
|
||||
|
||||
[draft-ietf-httpbis-http2-14]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-14
|
||||
|
||||
### 2.6.0 (2014-06-18) ###
|
||||
|
||||
* Upgrade to the latest draft: [draft-ietf-httpbis-http2-13]
|
||||
|
@ -1,9 +1,11 @@
|
||||
node-http2
|
||||
==========
|
||||
|
||||
An HTTP/2 ([draft-ietf-httpbis-http2-13](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13))
|
||||
An HTTP/2 ([draft-ietf-httpbis-http2-14](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14))
|
||||
client and server implementation for node.js.
|
||||
|
||||
![Travis CI status](https://travis-ci.org/molnarg/node-http2.svg?branch=master)
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
@ -114,12 +116,12 @@ 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.5.3:
|
||||
Code coverage summary as of version 2.7.0:
|
||||
```
|
||||
Statements : 92.64% ( 403/435 )
|
||||
Branches : 79.41% ( 135/170 )
|
||||
Statements : 92.68% ( 405/437 )
|
||||
Branches : 79.65% ( 137/172 )
|
||||
Functions : 92.31% ( 60/65 )
|
||||
Lines : 92.64% ( 403/435 )
|
||||
Lines : 92.68% ( 405/437 )
|
||||
```
|
||||
|
||||
There's a hosted version of the detailed (line-by-line) coverage report
|
||||
|
@ -121,7 +121,7 @@
|
||||
//
|
||||
// [1]: http://nodejs.org/api/https.html
|
||||
// [2]: http://nodejs.org/api/http.html
|
||||
// [3]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-8.1.3.2
|
||||
// [3]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-8.1.3.2
|
||||
// [expect-continue]: https://github.com/http2/http2-spec/issues/18
|
||||
// [connect]: https://github.com/http2/http2-spec/issues/230
|
||||
|
||||
@ -246,7 +246,7 @@ function IncomingMessage(stream) {
|
||||
}
|
||||
IncomingMessage.prototype = Object.create(PassThrough.prototype, { constructor: { value: IncomingMessage } });
|
||||
|
||||
// [Request Header Fields](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-8.1.3.1)
|
||||
// [Request Header Fields](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#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.
|
||||
@ -560,7 +560,7 @@ function IncomingRequest(stream) {
|
||||
}
|
||||
IncomingRequest.prototype = Object.create(IncomingMessage.prototype, { constructor: { value: IncomingRequest } });
|
||||
|
||||
// [Request Header Fields](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-8.1.3.1)
|
||||
// [Request Header Fields](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#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.
|
||||
@ -609,6 +609,10 @@ function OutgoingResponse(stream) {
|
||||
OutgoingResponse.prototype = Object.create(OutgoingMessage.prototype, { constructor: { value: OutgoingResponse } });
|
||||
|
||||
OutgoingResponse.prototype.writeHead = function writeHead(statusCode, reasonPhrase, headers) {
|
||||
if (this.headersSent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof reasonPhrase === 'string') {
|
||||
this._log.warn('Reason phrase argument was present but ignored by the writeHead method');
|
||||
} else {
|
||||
@ -999,7 +1003,7 @@ function IncomingResponse(stream) {
|
||||
}
|
||||
IncomingResponse.prototype = Object.create(IncomingMessage.prototype, { constructor: { value: IncomingResponse } });
|
||||
|
||||
// [Response Header Fields](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-8.1.3.2)
|
||||
// [Response Header Fields](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#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.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// [node-http2][homepage] is an [HTTP/2 (draft 13)][http2] implementation for [node.js][node].
|
||||
// [node-http2][homepage] is an [HTTP/2 (draft 14)][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:
|
||||
@ -11,7 +11,7 @@
|
||||
//
|
||||
// [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-13
|
||||
// [http2]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-14
|
||||
// [node]: http://nodejs.org/
|
||||
// [node-https]: http://nodejs.org/api/https.html
|
||||
// [node-http]: http://nodejs.org/api/http.html
|
||||
|
10
testing/xpcshell/node-http2/node_modules/http2-protocol/HISTORY.md
generated
vendored
10
testing/xpcshell/node-http2/node_modules/http2-protocol/HISTORY.md
generated
vendored
@ -1,6 +1,16 @@
|
||||
Version history
|
||||
===============
|
||||
|
||||
### 0.14.1 (2014-08-01) ###
|
||||
|
||||
* Fixed an error that caused us to send :-headers after non-:-headers
|
||||
|
||||
### 0.14.0 (2014-07-31) ###
|
||||
|
||||
* Upgrade to the latest draft: [draft-ietf-httpbis-http2-14][draft-14]
|
||||
|
||||
[draft-14]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-14
|
||||
|
||||
### 0.13.0 (2014-06-18) ###
|
||||
|
||||
* Upgrade to the latest draft: [draft-ietf-httpbis-http2-13][draft-13]
|
||||
|
4
testing/xpcshell/node-http2/node_modules/http2-protocol/README.md
generated
vendored
4
testing/xpcshell/node-http2/node_modules/http2-protocol/README.md
generated
vendored
@ -1,9 +1,11 @@
|
||||
node-http2-protocol
|
||||
===================
|
||||
|
||||
An HTTP/2 ([draft-ietf-httpbis-http2-13](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13))
|
||||
An HTTP/2 ([draft-ietf-httpbis-http2-14](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14))
|
||||
framing layer implementaion for node.js.
|
||||
|
||||
![Travis CI status](https://travis-ci.org/molnarg/node-http2-protocol.svg?branch=master)
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
|
257
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/compressor.js
generated
vendored
257
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/compressor.js
generated
vendored
@ -49,37 +49,8 @@ function HeaderTable(log, limit) {
|
||||
return self;
|
||||
}
|
||||
|
||||
// There are few more sets that are needed for the compression/decompression process that are all
|
||||
// subsets of the Header Table, and are implemented as flags on header table entries:
|
||||
//
|
||||
// * [Reference Set][referenceset]: contains a group of headers used as a reference for the
|
||||
// differential encoding of a new set of headers. (`reference` flag)
|
||||
// * Emitted headers: the headers that are already emitted as part of the current decompression
|
||||
// process (not part of the spec, `emitted` flag)
|
||||
// * Headers to be kept: headers that should not be removed as the last step of the encoding process
|
||||
// (not part of the spec, `keep` flag)
|
||||
//
|
||||
// [referenceset]: http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#section-3.1.3
|
||||
//
|
||||
// Relations of the sets:
|
||||
//
|
||||
// ,----------------------------------.
|
||||
// | Header Table |
|
||||
// | |
|
||||
// | ,----------------------------. |
|
||||
// | | Reference Set | |
|
||||
// | | | |
|
||||
// | | ,---------. ,---------. | |
|
||||
// | | | Keep | | Emitted | | |
|
||||
// | | | | | | | |
|
||||
// | | `---------' `---------' | |
|
||||
// | `----------------------------' |
|
||||
// `----------------------------------'
|
||||
function entryFromPair(pair) {
|
||||
var entry = pair.slice();
|
||||
entry.reference = false;
|
||||
entry.emitted = false;
|
||||
entry.keep = false;
|
||||
entry._size = size(entry);
|
||||
return entry;
|
||||
}
|
||||
@ -108,22 +79,20 @@ function size(entry) {
|
||||
// `(this._limit - entry.size)`, or until the table is empty.
|
||||
//
|
||||
// <---------- Index Address Space ---------->
|
||||
// <-- Header Table --> <-- Static Table -->
|
||||
// <-- Static Table --> <-- Header Table -->
|
||||
// +---+-----------+---+ +---+-----------+---+
|
||||
// | 0 | ... | k | |k+1| ... | n |
|
||||
// +---+-----------+---+ +---+-----------+---+
|
||||
// ^ |
|
||||
// | V
|
||||
// Insertion Point Drop Point
|
||||
// ^ |
|
||||
// | V
|
||||
// Insertion Point Drop Point
|
||||
|
||||
HeaderTable.prototype._enforceLimit = function _enforceLimit(limit) {
|
||||
var droppedEntries = [];
|
||||
var dropPoint = this.length - this._staticLength;
|
||||
while ((this._size > limit) && (dropPoint > 0)) {
|
||||
dropPoint -= 1;
|
||||
var dropped = this.splice(dropPoint, 1)[0];
|
||||
while ((this._size > 0) && (this._size > limit)) {
|
||||
var dropped = this.pop();
|
||||
this._size -= dropped._size;
|
||||
droppedEntries[dropPoint] = dropped;
|
||||
droppedEntries.unshift(dropped);
|
||||
}
|
||||
return droppedEntries;
|
||||
};
|
||||
@ -133,7 +102,7 @@ HeaderTable.prototype.add = function(entry) {
|
||||
var droppedEntries = this._enforceLimit(limit);
|
||||
|
||||
if (this._size <= limit) {
|
||||
this.unshift(entry);
|
||||
this.splice(this._staticLength, 0, entry);
|
||||
this._size += entry._size;
|
||||
}
|
||||
|
||||
@ -262,7 +231,6 @@ HeaderSetDecompressor.prototype._transform = function _transform(chunk, encoding
|
||||
//
|
||||
// Indexed:
|
||||
// { name: 2 , value: 2 , index: false }
|
||||
// { name: -1 , value: -1 , index: false } // reference set emptying
|
||||
// Literal:
|
||||
// { name: 2 , value: 'X', index: false } // without indexing
|
||||
// { name: 2 , value: 'Y', index: true } // with indexing
|
||||
@ -274,48 +242,17 @@ HeaderSetDecompressor.prototype._execute = function _execute(rep) {
|
||||
var entry, pair;
|
||||
|
||||
if (rep.contextUpdate) {
|
||||
if (rep.clearReferenceSet) {
|
||||
for (var i = 0; i < this._table.length; i++) {
|
||||
this._table[i].reference = false;
|
||||
}
|
||||
} else {
|
||||
this.setTableSizeLimit(rep.newMaxSize);
|
||||
}
|
||||
this.setTableSizeLimit(rep.newMaxSize);
|
||||
}
|
||||
|
||||
// * An _indexed representation_ corresponding to an entry _present_ in the reference set
|
||||
// entails the following actions:
|
||||
// * The entry is removed from the reference set.
|
||||
// * An _indexed representation_ corresponding to an entry _not present_ in the reference set
|
||||
// entails the following actions:
|
||||
// * If referencing an element of the static table:
|
||||
// * The header field corresponding to the referenced entry is emitted
|
||||
// * The referenced static entry is added to the header table
|
||||
// * A reference to this new header table entry is added to the reference set (except if
|
||||
// this new entry didn't fit in the header table)
|
||||
// * If referencing an element of the header table:
|
||||
// * The header field corresponding to the referenced entry is emitted
|
||||
// * The referenced header table entry is added to the reference set
|
||||
// * An _indexed representation_ entails the following actions:
|
||||
// * The header field corresponding to the referenced entry is emitted
|
||||
else if (typeof rep.value === 'number') {
|
||||
var index = rep.value;
|
||||
entry = this._table[index];
|
||||
|
||||
if (entry.reference) {
|
||||
entry.reference = false;
|
||||
}
|
||||
|
||||
else {
|
||||
pair = entry.slice();
|
||||
this.push(pair);
|
||||
|
||||
if (index >= this._table.length - this._table._staticLength) {
|
||||
entry = entryFromPair(pair);
|
||||
this._table.add(entry);
|
||||
}
|
||||
|
||||
entry.reference = true;
|
||||
entry.emitted = true;
|
||||
}
|
||||
pair = entry.slice();
|
||||
this.push(pair);
|
||||
}
|
||||
|
||||
// * A _literal representation_ that is _not added_ to the header table entails the following
|
||||
@ -324,7 +261,7 @@ HeaderSetDecompressor.prototype._execute = function _execute(rep) {
|
||||
// * A _literal representation_ that is _added_ to the header table entails the following further
|
||||
// actions:
|
||||
// * The header is added to the header table.
|
||||
// * The new entry is added to the reference set.
|
||||
// * The header is emitted.
|
||||
else {
|
||||
if (typeof rep.name === 'number') {
|
||||
pair = [this._table[rep.name][0], rep.value];
|
||||
@ -334,8 +271,6 @@ HeaderSetDecompressor.prototype._execute = function _execute(rep) {
|
||||
|
||||
if (rep.index) {
|
||||
entry = entryFromPair(pair);
|
||||
entry.reference = true;
|
||||
entry.emitted = true;
|
||||
this._table.add(entry);
|
||||
}
|
||||
|
||||
@ -356,15 +291,6 @@ HeaderSetDecompressor.prototype._flush = function _flush(callback) {
|
||||
this._execute(HeaderSetDecompressor.header(buffer));
|
||||
}
|
||||
|
||||
// * [emits the reference set](http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#section-3.2.2)
|
||||
for (var index = 0; index < this._table.length; index++) {
|
||||
var entry = this._table[index];
|
||||
if (entry.reference && !entry.emitted) {
|
||||
this.push(entry.slice());
|
||||
}
|
||||
entry.emitted = false;
|
||||
}
|
||||
|
||||
callback();
|
||||
};
|
||||
|
||||
@ -421,83 +347,22 @@ HeaderSetCompressor.prototype._transform = function _transform(pair, encoding, c
|
||||
}
|
||||
}
|
||||
|
||||
var mustNeverIndex = (name === 'cookie' || name === 'set-cookie' || name === 'authorization');
|
||||
var mustNeverIndex = ((name === 'cookie' && value.length < 20) ||
|
||||
(name === 'set-cookie' && value.length < 20) ||
|
||||
name === 'authorization');
|
||||
|
||||
// * if there's full match, it will be an indexed representation (or more than one) depending
|
||||
// on its presence in the reference, the emitted and the keep set:
|
||||
//
|
||||
// * If the entry is outside the reference set, then a single indexed representation puts the
|
||||
// entry into it and emits the header. Note that if the matched entry is in the static table,
|
||||
// then it has to be added to the header table.
|
||||
//
|
||||
// * If it's already in the keep set, then 4 indexed representations are needed:
|
||||
//
|
||||
// 1. removes it from the reference set
|
||||
// 2. puts it back in the reference set and emits the header once
|
||||
// 3. removes it again
|
||||
// 4. puts it back and emits it again for the second time
|
||||
//
|
||||
// It won't be emitted at the end of the decoding process since it's now in the emitted set.
|
||||
//
|
||||
// * If it's in the emitted set, then 2 indexed representations are needed:
|
||||
//
|
||||
// 1. removes it from the reference set
|
||||
// 2. puts it back in the reference set and emits the header once
|
||||
//
|
||||
// * If it's in the reference set, but outside the keep set and the emitted set, then this
|
||||
// header is common with the previous header set, and is still untouched. We mark it to keep
|
||||
// in the reference set (that means don't remove at the end of the encoding process).
|
||||
if (fullMatch !== -1 && !mustNeverIndex) {
|
||||
rep = { name: fullMatch, value: fullMatch, index: false };
|
||||
|
||||
if (!entry.reference) {
|
||||
if (fullMatch >= this._table.length - this._table._staticLength) {
|
||||
entry = entryFromPair(pair);
|
||||
this._table.add(entry);
|
||||
}
|
||||
this.send(rep);
|
||||
entry.reference = true;
|
||||
entry.emitted = true;
|
||||
}
|
||||
|
||||
else if (entry.keep) {
|
||||
this.send(rep);
|
||||
this.send(rep);
|
||||
this.send(rep);
|
||||
this.send(rep);
|
||||
entry.keep = false;
|
||||
entry.emitted = true;
|
||||
}
|
||||
|
||||
else if (entry.emitted) {
|
||||
this.send(rep);
|
||||
this.send(rep);
|
||||
}
|
||||
|
||||
else {
|
||||
entry.keep = true;
|
||||
}
|
||||
this.send({ name: fullMatch, value: fullMatch, index: false });
|
||||
}
|
||||
|
||||
// * otherwise, it will be a literal representation (with a name index if there's a name match)
|
||||
else {
|
||||
entry = entryFromPair(pair);
|
||||
entry.emitted = true;
|
||||
|
||||
var indexing = (entry._size < this._table._limit / 2) && !mustNeverIndex;
|
||||
|
||||
if (indexing) {
|
||||
entry.reference = true;
|
||||
var droppedEntries = this._table.add(entry);
|
||||
for (droppedIndex in droppedEntries) {
|
||||
droppedIndex = Number(droppedIndex)
|
||||
var dropped = droppedEntries[droppedIndex];
|
||||
if (dropped.keep) {
|
||||
rep = { name: droppedIndex, value: droppedIndex, index: false };
|
||||
this.send(rep);
|
||||
this.send(rep);
|
||||
}
|
||||
}
|
||||
this._table.add(entry);
|
||||
}
|
||||
|
||||
this.send({ name: (nameMatch !== -1) ? nameMatch : name, value: value, index: indexing, mustNeverIndex: mustNeverIndex, contextUpdate: false });
|
||||
@ -510,17 +375,6 @@ HeaderSetCompressor.prototype._transform = function _transform(pair, encoding, c
|
||||
// TransformStream class. It gets called when there's no more header to compress. The final step:
|
||||
// [_flush]: http://nodejs.org/api/stream.html#stream_transform_flush_callback
|
||||
HeaderSetCompressor.prototype._flush = function _flush(callback) {
|
||||
// * removing entries from the header set that are not marked to be kept or emitted
|
||||
for (var index = 0; index < this._table.length; index++) {
|
||||
var entry = this._table[index];
|
||||
if (entry.reference && !entry.keep && !entry.emitted) {
|
||||
this.send({ name: index, value: index, index: false });
|
||||
entry.reference = false;
|
||||
}
|
||||
entry.keep = false;
|
||||
entry.emitted = false;
|
||||
}
|
||||
|
||||
callback();
|
||||
};
|
||||
|
||||
@ -1135,12 +989,7 @@ HeaderSetCompressor.header = function writeHeader(header) {
|
||||
}
|
||||
|
||||
if (representation === representations.contextUpdate) {
|
||||
if (header.clearReferenceSet) {
|
||||
var buffer = new Buffer('10', 'hex');
|
||||
buffers.push([buffer]);
|
||||
} else {
|
||||
buffers.push(HeaderSetCompressor.integer(header.newMaxSize, 4));
|
||||
}
|
||||
buffers.push(HeaderSetCompressor.integer(header.newMaxSize, 5));
|
||||
}
|
||||
|
||||
else if (representation === representations.indexed) {
|
||||
@ -1181,18 +1030,12 @@ HeaderSetDecompressor.header = function readHeader(buffer) {
|
||||
header.value = header.name = -1;
|
||||
header.index = false;
|
||||
header.contextUpdate = false;
|
||||
header.clearReferenceSet = false;
|
||||
header.newMaxSize = 0;
|
||||
header.mustNeverIndex = false;
|
||||
|
||||
if (representation === representations.contextUpdate) {
|
||||
header.contextUpdate = true;
|
||||
if (firstByte & 0x10) {
|
||||
header.clearReferenceSet = true;
|
||||
buffer.cursor += 1;
|
||||
} else {
|
||||
header.newMaxSize = HeaderSetDecompressor.integer(buffer, 4);
|
||||
}
|
||||
header.newMaxSize = HeaderSetDecompressor.integer(buffer, 5);
|
||||
}
|
||||
|
||||
else if (representation === representations.indexed) {
|
||||
@ -1234,7 +1077,7 @@ HeaderSetDecompressor.header = function readHeader(buffer) {
|
||||
//
|
||||
// There are possibly several binary frame that belong to a single non-binary frame.
|
||||
|
||||
var MAX_HTTP_PAYLOAD_SIZE = 16383;
|
||||
var MAX_HTTP_PAYLOAD_SIZE = 16384;
|
||||
|
||||
// The Compressor class
|
||||
// --------------------
|
||||
@ -1260,7 +1103,19 @@ Compressor.prototype.setTableSizeLimit = function setTableSizeLimit(size) {
|
||||
// but the API becomes simpler.
|
||||
Compressor.prototype.compress = function compress(headers) {
|
||||
var compressor = new HeaderSetCompressor(this._log, this._table);
|
||||
var colonHeaders = [];
|
||||
var nonColonHeaders = [];
|
||||
|
||||
// To ensure we send colon headers first
|
||||
for (var name in headers) {
|
||||
if (name.trim()[0] === ':') {
|
||||
colonHeaders.push(name);
|
||||
} else {
|
||||
nonColonHeaders.push(name);
|
||||
}
|
||||
}
|
||||
|
||||
function compressHeader(name) {
|
||||
var value = headers[name];
|
||||
name = String(name).toLowerCase();
|
||||
|
||||
@ -1275,16 +1130,6 @@ Compressor.prototype.compress = function compress(headers) {
|
||||
}));
|
||||
}
|
||||
|
||||
// * To preserve the order of a comma-separated list, the ordered values for a single header
|
||||
// field name appearing in different header fields are concatenated into a single value.
|
||||
// A zero-valued octet (0x0) is used to delimit multiple values.
|
||||
// * Header fields containing multiple values MUST be concatenated into a single value unless
|
||||
// the ordering of that header field is known to be not significant.
|
||||
// * Currently, only the Cookie header is considered to be order-insensitive.
|
||||
if ((value instanceof Array) && (name !== 'cookie')) {
|
||||
value = value.join('\0');
|
||||
}
|
||||
|
||||
if (value instanceof Array) {
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
compressor.write([name, String(value[i])]);
|
||||
@ -1293,6 +1138,14 @@ Compressor.prototype.compress = function compress(headers) {
|
||||
compressor.write([name, String(value)]);
|
||||
}
|
||||
}
|
||||
|
||||
for (var idx = 0; idx < colonHeaders.length; idx++) {
|
||||
compressHeader(colonHeaders[idx]);
|
||||
}
|
||||
for (var idx = 0; idx < nonColonHeaders.length; idx++) {
|
||||
compressHeader(nonColonHeaders[idx]);
|
||||
}
|
||||
|
||||
compressor.end();
|
||||
|
||||
var chunk, chunks = [];
|
||||
@ -1380,24 +1233,26 @@ Decompressor.prototype.decompress = function decompress(block) {
|
||||
var decompressor = new HeaderSetDecompressor(this._log, this._table);
|
||||
decompressor.end(block);
|
||||
|
||||
var seenNonColonHeader = false;
|
||||
var headers = {};
|
||||
var pair;
|
||||
while (pair = decompressor.read()) {
|
||||
var name = pair[0];
|
||||
// * After decompression, header fields that have values containing zero octets (0x0) MUST be
|
||||
// split into multiple header fields before being processed.
|
||||
var values = pair[1].split('\0');
|
||||
for (var i = 0; i < values.length; i++) {
|
||||
var value = values[i];
|
||||
if (name in headers) {
|
||||
if (headers[name] instanceof Array) {
|
||||
headers[name].push(value);
|
||||
} else {
|
||||
headers[name] = [headers[name], value];
|
||||
}
|
||||
var value = pair[1];
|
||||
var isColonHeader = (name.trim()[0] === ':');
|
||||
if (seenNonColonHeader && isColonHeader) {
|
||||
this.emit('error', 'PROTOCOL_ERROR');
|
||||
return headers;
|
||||
}
|
||||
seenNonColonHeader = !isColonHeader;
|
||||
if (name in headers) {
|
||||
if (headers[name] instanceof Array) {
|
||||
headers[name].push(value);
|
||||
} else {
|
||||
headers[name] = value;
|
||||
headers[name] = [headers[name], value];
|
||||
}
|
||||
} else {
|
||||
headers[name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
8
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/connection.js
generated
vendored
8
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/connection.js
generated
vendored
@ -392,6 +392,7 @@ Connection.prototype._initializeSettingsManagement = function _initializeSetting
|
||||
|
||||
// * Forwarding SETTINGS frames to the `_receiveSettings` method
|
||||
this.on('SETTINGS', this._receiveSettings);
|
||||
this.on('RECEIVING_SETTINGS_MAX_FRAME_SIZE', this._sanityCheckMaxFrameSize);
|
||||
};
|
||||
|
||||
// * Checking that the first frame the other endpoint sends is SETTINGS
|
||||
@ -430,6 +431,13 @@ Connection.prototype._receiveSettings = function _receiveSettings(frame) {
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype._sanityCheckMaxFrameSize = function _sanityCheckMaxFrameSize(value) {
|
||||
if ((value < 0x4000) || (value >= 0x01000000)) {
|
||||
this._log.fatal('Received invalid value for max frame size: ' + value);
|
||||
this.emit('error');
|
||||
}
|
||||
};
|
||||
|
||||
// Changing one or more settings value and sending out a SETTINGS frame
|
||||
Connection.prototype.set = function set(settings, callback) {
|
||||
// * Calling the callback and emitting event when the change is acknowledges
|
||||
|
10
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/endpoint.js
generated
vendored
10
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/endpoint.js
generated
vendored
@ -167,8 +167,6 @@ function pipeAndFilter(stream1, stream2, filter) {
|
||||
}
|
||||
}
|
||||
|
||||
var MAX_HTTP_PAYLOAD_SIZE = 16383;
|
||||
|
||||
Endpoint.prototype._initializeDataFlow = function _initializeDataFlow(role, settings, filters) {
|
||||
var firstStreamId, compressorRole, decompressorRole;
|
||||
if (role === 'CLIENT') {
|
||||
@ -181,8 +179,8 @@ Endpoint.prototype._initializeDataFlow = function _initializeDataFlow(role, sett
|
||||
decompressorRole = 'REQUEST';
|
||||
}
|
||||
|
||||
this._serializer = new Serializer(this._log, MAX_HTTP_PAYLOAD_SIZE);
|
||||
this._deserializer = new Deserializer(this._log, MAX_HTTP_PAYLOAD_SIZE);
|
||||
this._serializer = new Serializer(this._log);
|
||||
this._deserializer = new Deserializer(this._log);
|
||||
this._compressor = new Compressor(this._log, compressorRole);
|
||||
this._decompressor = new Decompressor(this._log, decompressorRole);
|
||||
this._connection = new Connection(this._log, firstStreamId, settings);
|
||||
@ -193,9 +191,9 @@ Endpoint.prototype._initializeDataFlow = function _initializeDataFlow(role, sett
|
||||
pipeAndFilter(this._decompressor, this._connection, filters.afterDecompression);
|
||||
|
||||
this._connection.on('ACKNOWLEDGED_SETTINGS_HEADER_TABLE_SIZE',
|
||||
this._decompressor.setTableSizeLimit.bind(this._decompressor))
|
||||
this._decompressor.setTableSizeLimit.bind(this._decompressor));
|
||||
this._connection.on('RECEIVING_SETTINGS_HEADER_TABLE_SIZE',
|
||||
this._compressor.setTableSizeLimit.bind(this._compressor))
|
||||
this._compressor.setTableSizeLimit.bind(this._compressor));
|
||||
};
|
||||
|
||||
var noread = {};
|
||||
|
2
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/flow.js
generated
vendored
2
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/flow.js
generated
vendored
@ -19,7 +19,7 @@ exports.Flow = Flow;
|
||||
// * **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-13#section-6.9.2
|
||||
// [1]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-6.9.2
|
||||
|
||||
// API for child classes
|
||||
// ---------------------
|
||||
|
104
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/framer.js
generated
vendored
104
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/framer.js
generated
vendored
@ -11,7 +11,7 @@ exports.Deserializer = Deserializer;
|
||||
|
||||
var logData = Boolean(process.env.HTTP2_LOG_DATA);
|
||||
|
||||
var MAX_PAYLOAD_SIZE = 16383;
|
||||
var MAX_PAYLOAD_SIZE = 16384;
|
||||
var WINDOW_UPDATE_PAYLOAD_SIZE = 4;
|
||||
|
||||
// Serializer
|
||||
@ -25,9 +25,8 @@ var WINDOW_UPDATE_PAYLOAD_SIZE = 4;
|
||||
// empty adds payload adds header
|
||||
// array buffers buffer
|
||||
|
||||
function Serializer(log, sizeLimit) {
|
||||
function Serializer(log) {
|
||||
this._log = log.child({ component: 'serializer' });
|
||||
this._sizeLimit = sizeLimit || MAX_PAYLOAD_SIZE;
|
||||
Transform.call(this, { objectMode: true });
|
||||
}
|
||||
Serializer.prototype = Object.create(Transform.prototype, { constructor: { value: Serializer } });
|
||||
@ -42,9 +41,9 @@ Serializer.prototype._transform = function _transform(frame, encoding, done) {
|
||||
|
||||
var buffers = [];
|
||||
Serializer[frame.type](frame, buffers);
|
||||
Serializer.commonHeader(frame, buffers);
|
||||
var length = Serializer.commonHeader(frame, buffers);
|
||||
|
||||
assert(buffers[0].readUInt16BE(0) <= this._sizeLimit, 'Frame too large!');
|
||||
assert(length <= MAX_PAYLOAD_SIZE, 'Frame too large!');
|
||||
|
||||
for (var i = 0; i < buffers.length; i++) {
|
||||
if (logData) {
|
||||
@ -67,10 +66,9 @@ Serializer.prototype._transform = function _transform(frame, encoding, done) {
|
||||
// empty adds parsed adds parsed
|
||||
// object header properties payload properties
|
||||
|
||||
function Deserializer(log, sizeLimit, role) {
|
||||
function Deserializer(log, role) {
|
||||
this._role = role;
|
||||
this._log = log.child({ component: 'deserializer' });
|
||||
this._sizeLimit = sizeLimit || MAX_PAYLOAD_SIZE;
|
||||
Transform.call(this, { objectMode: true });
|
||||
this._next(COMMON_HEADER_SIZE);
|
||||
}
|
||||
@ -114,7 +112,7 @@ Deserializer.prototype._transform = function _transform(chunk, encoding, done) {
|
||||
// deserializer waits for the specified length payload.
|
||||
if ((this._cursor === this._buffer.length) && this._waitingForHeader) {
|
||||
var payloadSize = Deserializer.commonHeader(this._buffer, this._frame);
|
||||
if (payloadSize <= this._sizeLimit) {
|
||||
if (payloadSize <= MAX_PAYLOAD_SIZE) {
|
||||
this._next(payloadSize);
|
||||
} else {
|
||||
this.emit('error', 'FRAME_SIZE_ERROR');
|
||||
@ -148,20 +146,22 @@ Deserializer.prototype._transform = function _transform(chunk, encoding, done) {
|
||||
done();
|
||||
};
|
||||
|
||||
// [Frame Header](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-4.1)
|
||||
// [Frame Header](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-4.1)
|
||||
// --------------------------------------------------------------
|
||||
//
|
||||
// HTTP/2.0 frames share a common base format consisting of an 8-byte header followed by 0 to 65535
|
||||
// HTTP/2.0 frames share a common base format consisting of a 9-byte header followed by 0 to 2^24 - 1
|
||||
// bytes of data.
|
||||
//
|
||||
// Additional size limits can be set by specific application uses. HTTP limits the frame size to
|
||||
// 16,383 octets.
|
||||
// 16,384 octets by default, though this can be increased by a receiver.
|
||||
//
|
||||
// 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 | Length (14) | Type (8) | Flags (8) |
|
||||
// +-+-+---------------------------+---------------+---------------+
|
||||
// | Length (24) |
|
||||
// +---------------+---------------+---------------+
|
||||
// | Type (8) | Flags (8) |
|
||||
// +-+-----------------------------+---------------+---------------+
|
||||
// |R| Stream Identifier (31) |
|
||||
// +-+-------------------------------------------------------------+
|
||||
// | Frame Data (0...) ...
|
||||
@ -169,12 +169,8 @@ Deserializer.prototype._transform = function _transform(chunk, encoding, done) {
|
||||
//
|
||||
// The fields of the frame header are defined as:
|
||||
//
|
||||
// * R:
|
||||
// A reserved 2-bit field. The semantics of these bits are undefined and the bits MUST remain
|
||||
// unset (0) when sending and MUST be ignored when receiving.
|
||||
//
|
||||
// * Length:
|
||||
// The length of the frame data expressed as an unsigned 14-bit integer. The 8 bytes of the frame
|
||||
// The length of the frame data expressed as an unsigned 24-bit integer. The 9 bytes of the frame
|
||||
// header are not included in this value.
|
||||
//
|
||||
// * Type:
|
||||
@ -197,7 +193,7 @@ Deserializer.prototype._transform = function _transform(chunk, encoding, done) {
|
||||
//
|
||||
// The structure and content of the remaining frame data is dependent entirely on the frame type.
|
||||
|
||||
var COMMON_HEADER_SIZE = 8;
|
||||
var COMMON_HEADER_SIZE = 9;
|
||||
|
||||
var frameTypes = [];
|
||||
|
||||
@ -214,10 +210,11 @@ Serializer.commonHeader = function writeCommonHeader(frame, buffers) {
|
||||
for (var i = 0; i < buffers.length; i++) {
|
||||
size += buffers[i].length;
|
||||
}
|
||||
headerBuffer.writeUInt16BE(size, 0);
|
||||
headerBuffer.writeUInt8(0, 0);
|
||||
headerBuffer.writeUInt16BE(size, 1);
|
||||
|
||||
var typeId = frameTypes.indexOf(frame.type); // If we are here then the type is valid for sure
|
||||
headerBuffer.writeUInt8(typeId, 2);
|
||||
headerBuffer.writeUInt8(typeId, 3);
|
||||
|
||||
var flagByte = 0;
|
||||
for (var flag in frame.flags) {
|
||||
@ -227,31 +224,37 @@ Serializer.commonHeader = function writeCommonHeader(frame, buffers) {
|
||||
flagByte |= (1 << position);
|
||||
}
|
||||
}
|
||||
headerBuffer.writeUInt8(flagByte, 3);
|
||||
headerBuffer.writeUInt8(flagByte, 4);
|
||||
|
||||
assert((0 <= frame.stream) && (frame.stream < 0x7fffffff), frame.stream);
|
||||
headerBuffer.writeUInt32BE(frame.stream || 0, 4);
|
||||
headerBuffer.writeUInt32BE(frame.stream || 0, 5);
|
||||
|
||||
buffers.unshift(headerBuffer);
|
||||
|
||||
return size;
|
||||
};
|
||||
|
||||
Deserializer.commonHeader = function readCommonHeader(buffer, frame) {
|
||||
var length = buffer.readUInt16BE(0);
|
||||
var totallyWastedByte = buffer.readUInt8(0);
|
||||
var length = buffer.readUInt16BE(1);
|
||||
// We do this just for sanity checking later on, to make sure no one sent us a
|
||||
// frame that's super large.
|
||||
length += totallyWastedByte << 16;
|
||||
|
||||
frame.type = frameTypes[buffer.readUInt8(2)];
|
||||
frame.type = frameTypes[buffer.readUInt8(3)];
|
||||
if (!frame.type) {
|
||||
// We are required to ignore unknown frame types
|
||||
return length;
|
||||
}
|
||||
|
||||
frame.flags = {};
|
||||
var flagByte = buffer.readUInt8(3);
|
||||
var flagByte = buffer.readUInt8(4);
|
||||
var definedFlags = frameFlags[frame.type];
|
||||
for (var i = 0; i < definedFlags.length; i++) {
|
||||
frame.flags[definedFlags[i]] = Boolean(flagByte & (1 << i));
|
||||
}
|
||||
|
||||
frame.stream = buffer.readUInt32BE(4) & 0x7fffffff;
|
||||
frame.stream = buffer.readUInt32BE(5) & 0x7fffffff;
|
||||
|
||||
return length;
|
||||
};
|
||||
@ -266,7 +269,7 @@ Deserializer.commonHeader = function readCommonHeader(buffer, frame) {
|
||||
// * `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-13#section-6.1)
|
||||
// [DATA Frames](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-6.1)
|
||||
// ------------------------------------------------------------
|
||||
//
|
||||
// DATA frames (type=0x0) convey arbitrary, variable-length sequences of octets associated with a
|
||||
@ -277,16 +280,12 @@ Deserializer.commonHeader = function readCommonHeader(buffer, frame) {
|
||||
// * 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.
|
||||
// * PADDED (0x08):
|
||||
// Bit 4 being set indicates that the Pad Length field is present.
|
||||
|
||||
frameTypes[0x0] = 'DATA';
|
||||
|
||||
frameFlags.DATA = ['END_STREAM', 'END_SEGMENT', 'RESERVED4', 'PADDED'];
|
||||
frameFlags.DATA = ['END_STREAM', 'RESERVED2', 'RESERVED4', 'PADDED'];
|
||||
|
||||
typeSpecificAttributes.DATA = ['data'];
|
||||
|
||||
@ -309,7 +308,7 @@ Deserializer.DATA = function readData(buffer, frame) {
|
||||
}
|
||||
};
|
||||
|
||||
// [HEADERS](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-6.2)
|
||||
// [HEADERS](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-6.2)
|
||||
// --------------------------------------------------------------
|
||||
//
|
||||
// The HEADERS frame (type=0x1) allows the sender to create a stream.
|
||||
@ -319,10 +318,6 @@ Deserializer.DATA = function readData(buffer, frame) {
|
||||
// * 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.
|
||||
// * END_HEADERS (0x4):
|
||||
// The END_HEADERS bit indicates that this frame contains the entire payload necessary to provide
|
||||
// a complete set of headers.
|
||||
@ -334,7 +329,7 @@ Deserializer.DATA = function readData(buffer, frame) {
|
||||
|
||||
frameTypes[0x1] = 'HEADERS';
|
||||
|
||||
frameFlags.HEADERS = ['END_STREAM', 'END_SEGMENT', 'END_HEADERS', 'PADDED', 'RESERVED5', 'PRIORITY'];
|
||||
frameFlags.HEADERS = ['END_STREAM', 'RESERVED2', 'END_HEADERS', 'PADDED', 'RESERVED5', 'PRIORITY'];
|
||||
|
||||
typeSpecificAttributes.HEADERS = ['priorityDependency', 'priorityWeight', 'exclusiveDependency', 'headers', 'data'];
|
||||
|
||||
@ -395,7 +390,7 @@ Deserializer.HEADERS = function readHeadersPriority(buffer, frame) {
|
||||
}
|
||||
};
|
||||
|
||||
// [PRIORITY](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-6.3)
|
||||
// [PRIORITY](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-6.3)
|
||||
// -------------------------------------------------------
|
||||
//
|
||||
// The PRIORITY frame (type=0x2) specifies the sender-advised priority of a stream.
|
||||
@ -440,7 +435,7 @@ Deserializer.PRIORITY = function readPriority(buffer, frame) {
|
||||
frame.priorityWeight = buffer.readUInt8(4);
|
||||
};
|
||||
|
||||
// [RST_STREAM](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-6.4)
|
||||
// [RST_STREAM](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-6.4)
|
||||
// -----------------------------------------------------------
|
||||
//
|
||||
// The RST_STREAM frame (type=0x3) allows for abnormal termination of a stream.
|
||||
@ -478,7 +473,7 @@ Deserializer.RST_STREAM = function readRstStream(buffer, frame) {
|
||||
}
|
||||
};
|
||||
|
||||
// [SETTINGS](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-6.5)
|
||||
// [SETTINGS](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-6.5)
|
||||
// -------------------------------------------------------
|
||||
//
|
||||
// The SETTINGS frame (type=0x4) conveys configuration parameters that affect how endpoints
|
||||
@ -581,7 +576,11 @@ definedSettings[3] = { name: 'SETTINGS_MAX_CONCURRENT_STREAMS', flag: false };
|
||||
// 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-13#section-6.6)
|
||||
// * SETTINGS_MAX_FRAME_SIZE (5):
|
||||
// indicates the maximum size of a frame the receiver will allow.
|
||||
definedSettings[5] = { name: 'SETTINGS_MAX_FRAME_SIZE', flag: false };
|
||||
|
||||
// [PUSH_PROMISE](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-6.6)
|
||||
// ---------------------------------------------------------------
|
||||
//
|
||||
// The PUSH_PROMISE frame (type=0x5) is used to notify the peer endpoint in advance of streams the
|
||||
@ -642,7 +641,7 @@ Deserializer.PUSH_PROMISE = function readPushPromise(buffer, frame) {
|
||||
}
|
||||
};
|
||||
|
||||
// [PING](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-6.7)
|
||||
// [PING](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-6.7)
|
||||
// -----------------------------------------------
|
||||
//
|
||||
// The PING frame (type=0x6) is a mechanism for measuring a minimal round-trip time from the
|
||||
@ -672,7 +671,7 @@ Deserializer.PING = function readPing(buffer, frame) {
|
||||
frame.data = buffer;
|
||||
};
|
||||
|
||||
// [GOAWAY](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-6.8)
|
||||
// [GOAWAY](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-6.8)
|
||||
// ---------------------------------------------------
|
||||
//
|
||||
// The GOAWAY frame (type=0x7) informs the remote peer to stop creating streams on this connection.
|
||||
@ -723,7 +722,7 @@ Deserializer.GOAWAY = function readGoaway(buffer, frame) {
|
||||
}
|
||||
};
|
||||
|
||||
// [WINDOW_UPDATE](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-6.9)
|
||||
// [WINDOW_UPDATE](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-6.9)
|
||||
// -----------------------------------------------------------------
|
||||
//
|
||||
// The WINDOW_UPDATE frame (type=0x8) is used to implement flow control.
|
||||
@ -745,7 +744,7 @@ Serializer.WINDOW_UPDATE = function writeWindowUpdate(frame, buffers) {
|
||||
var buffer = new Buffer(4);
|
||||
|
||||
var window_size = frame.window_size;
|
||||
assert((0 <= window_size) && (window_size <= 0x7fffffff), window_size);
|
||||
assert((0 < window_size) && (window_size <= 0x7fffffff), window_size);
|
||||
buffer.writeUInt32BE(window_size, 0);
|
||||
|
||||
buffers.push(buffer);
|
||||
@ -756,9 +755,12 @@ Deserializer.WINDOW_UPDATE = function readWindowUpdate(buffer, frame) {
|
||||
return 'FRAME_SIZE_ERROR';
|
||||
}
|
||||
frame.window_size = buffer.readUInt32BE(0) & 0x7fffffff;
|
||||
if (frame.window_size === 0) {
|
||||
return 'PROTOCOL_ERROR';
|
||||
}
|
||||
};
|
||||
|
||||
// [CONTINUATION](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-6.10)
|
||||
// [CONTINUATION](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-6.10)
|
||||
// ------------------------------------------------------------
|
||||
//
|
||||
// The CONTINUATION frame (type=0x9) is used to continue a sequence of header block fragments.
|
||||
@ -783,7 +785,7 @@ Deserializer.CONTINUATION = function readContinuation(buffer, frame) {
|
||||
frame.data = buffer;
|
||||
};
|
||||
|
||||
// [ALTSVC](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-6.11)
|
||||
// [ALTSVC](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-6.11)
|
||||
// ------------------------------------------------------------
|
||||
//
|
||||
// The ALTSVC frame (type=0xA) advertises the availability of an alternative service to the client.
|
||||
@ -872,7 +874,7 @@ Deserializer.ALTSVC = function readAltSvc(buffer, frame) {
|
||||
frame.origin = buffer.toString('ascii', 9 + pidLength + hostLength);
|
||||
};
|
||||
|
||||
// [BLOCKED](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-6.12)
|
||||
// [BLOCKED](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-6.12)
|
||||
// ------------------------------------------------------------
|
||||
//
|
||||
// The BLOCKED frame (type=0xB) indicates that the sender is unable to send data
|
||||
@ -892,7 +894,7 @@ Serializer.BLOCKED = function writeBlocked(frame, buffers) {
|
||||
Deserializer.BLOCKED = function readBlocked(buffer, frame) {
|
||||
};
|
||||
|
||||
// [Error Codes](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-7)
|
||||
// [Error Codes](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-7)
|
||||
// ------------------------------------------------------------
|
||||
|
||||
var errorCodes = [
|
||||
|
12
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/index.js
generated
vendored
12
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/index.js
generated
vendored
@ -1,4 +1,4 @@
|
||||
// [node-http2-protocol][homepage] is an implementation of the [HTTP/2 (draft 13)][http2]
|
||||
// [node-http2-protocol][homepage] is an implementation of the [HTTP/2 (draft 14)][http2]
|
||||
// framing layer for [node.js][node].
|
||||
//
|
||||
// The main building blocks are [node.js streams][node-stream] that are connected through pipes.
|
||||
@ -28,16 +28,16 @@
|
||||
// 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-13
|
||||
// [http2-connheader]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-3.5
|
||||
// [http2-stream]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-5
|
||||
// [http2-streamstate]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-5.1
|
||||
// [http2]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-14
|
||||
// [http2-connheader]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-3.5
|
||||
// [http2-stream]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-5
|
||||
// [http2-streamstate]: http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#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-13';
|
||||
exports.ImplementedVersion = 'h2-14';
|
||||
|
||||
exports.Endpoint = require('./endpoint').Endpoint;
|
||||
|
||||
|
7
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/stream.js
generated
vendored
7
testing/xpcshell/node-http2/node_modules/http2-protocol/lib/stream.js
generated
vendored
@ -240,6 +240,10 @@ Stream.prototype._writeUpstream = function _writeUpstream(frame) {
|
||||
|
||||
// * If it's a control frame. Call the appropriate handler method.
|
||||
if (frame.type === 'HEADERS') {
|
||||
if (this._processedHeaders && !frame.flags['END_STREAM']) {
|
||||
this.emit('error', 'PROTOCOL_ERROR');
|
||||
}
|
||||
this._processedHeaders = true;
|
||||
this._onHeaders(frame);
|
||||
} else if (frame.type === 'PUSH_PROMISE') {
|
||||
this._onPromise(frame);
|
||||
@ -346,7 +350,7 @@ Stream.prototype._finishing = function _finishing() {
|
||||
}
|
||||
};
|
||||
|
||||
// [Stream States](http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-5.1)
|
||||
// [Stream States](http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-5.1)
|
||||
// ----------------
|
||||
//
|
||||
// +--------+
|
||||
@ -381,6 +385,7 @@ Stream.prototype._initializeState = function _initializeState() {
|
||||
this._initiated = undefined;
|
||||
this._closedByUs = undefined;
|
||||
this._closedWithRst = undefined;
|
||||
this._processedHeaders = false;
|
||||
};
|
||||
|
||||
// Only `_setState` should change `this.state` directly. It also logs the state change and notifies
|
||||
|
2
testing/xpcshell/node-http2/node_modules/http2-protocol/package.json
generated
vendored
2
testing/xpcshell/node-http2/node_modules/http2-protocol/package.json
generated
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "http2-protocol",
|
||||
"version": "0.13.0",
|
||||
"version": "0.14.1",
|
||||
"description": "A JavaScript implementation of the HTTP/2 framing layer",
|
||||
"main": "lib/index.js",
|
||||
"engines" : {
|
||||
|
334
testing/xpcshell/node-http2/node_modules/http2-protocol/test/compressor.js
generated
vendored
334
testing/xpcshell/node-http2/node_modules/http2-protocol/test/compressor.js
generated
vendored
@ -76,149 +76,60 @@ ax-age=3600; version=1': '94e783f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
|
||||
};
|
||||
|
||||
var test_headers = [{
|
||||
// literal w/index, name index
|
||||
// index
|
||||
header: {
|
||||
name: 1,
|
||||
value: 'GET',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('42' + '03474554', 'hex')
|
||||
}, {
|
||||
// literal w/index, name index
|
||||
header: {
|
||||
name: 6,
|
||||
value: 'http',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('47' + '839d29af', 'hex')
|
||||
}, {
|
||||
// literal w/index, name index
|
||||
header: {
|
||||
name: 5,
|
||||
value: '/',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('46' + '012F', 'hex')
|
||||
}, {
|
||||
// literal w/index, name index
|
||||
header: {
|
||||
name: 3,
|
||||
value: 'www.foo.com',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('44' + '89f1e3c2f29ceb90f4ff', 'hex')
|
||||
}, {
|
||||
// literal w/index, name index
|
||||
header: {
|
||||
name: 2,
|
||||
value: 'https',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('43' + '849d29ad1f', 'hex')
|
||||
}, {
|
||||
// literal w/index, name index
|
||||
header: {
|
||||
name: 1,
|
||||
value: 'www.bar.com',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('42' + '89f1e3c2f18ec5c87a7f', 'hex')
|
||||
}, {
|
||||
// literal w/index, name index
|
||||
header: {
|
||||
name: 29,
|
||||
value: 'no-cache',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('5e' + '86a8eb10649cbf', 'hex')
|
||||
}, {
|
||||
// indexed
|
||||
header: {
|
||||
name: 3,
|
||||
value: 3,
|
||||
value: 1,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('84', 'hex')
|
||||
buffer: new Buffer('82', 'hex')
|
||||
}, {
|
||||
// indexed
|
||||
// index
|
||||
header: {
|
||||
name: 5,
|
||||
value: 5,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('86', 'hex')
|
||||
}, {
|
||||
// literal w/index, name index
|
||||
// index
|
||||
header: {
|
||||
name: 4,
|
||||
value: '/custom-path.css',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('45' + '8b6096a127a56ac699d72211', 'hex')
|
||||
}, {
|
||||
// literal w/index, new name & value
|
||||
header: {
|
||||
name: 'custom-key',
|
||||
value: 'custom-value',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('40' + '8825a849e95ba97d7f' + '8925a849e95bb8e8b4bf', 'hex')
|
||||
}, {
|
||||
// indexed
|
||||
header: {
|
||||
name: 2,
|
||||
value: 2,
|
||||
name: 3,
|
||||
value: 3,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('83', 'hex')
|
||||
buffer: new Buffer('84', 'hex')
|
||||
}, {
|
||||
// literal w/index, name index
|
||||
header: {
|
||||
name: 0,
|
||||
value: 'www.foo.com',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('41' + '89f1e3c2f29ceb90f4ff', 'hex')
|
||||
}, {
|
||||
// indexed
|
||||
header: {
|
||||
name: 1,
|
||||
value: 1,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('82', 'hex')
|
||||
}, {
|
||||
// indexed
|
||||
header: {
|
||||
@ -227,10 +138,163 @@ var test_headers = [{
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('87', 'hex')
|
||||
}, {
|
||||
// indexed
|
||||
header: {
|
||||
name: 3,
|
||||
value: 3,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('84', 'hex')
|
||||
}, {
|
||||
// literal w/index, name index
|
||||
header: {
|
||||
name: 0,
|
||||
value: 'www.bar.com',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('41' + '89f1e3c2f18ec5c87a7f', 'hex')
|
||||
}, {
|
||||
// literal w/index, name index
|
||||
header: {
|
||||
name: 23,
|
||||
value: 'no-cache',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('58' + '86a8eb10649cbf', 'hex')
|
||||
}, {
|
||||
// index
|
||||
header: {
|
||||
name: 1,
|
||||
value: 1,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('82', 'hex')
|
||||
}, {
|
||||
// index
|
||||
header: {
|
||||
name: 6,
|
||||
value: 6,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('87', 'hex')
|
||||
}, {
|
||||
// literal w/index, name index
|
||||
header: {
|
||||
name: 3,
|
||||
value: '/custom-path.css',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('44' + '8b6096a127a56ac699d72211', 'hex')
|
||||
}, {
|
||||
// index
|
||||
header: {
|
||||
name: 63,
|
||||
value: 63,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('C0', 'hex')
|
||||
}, {
|
||||
// literal w/index, new name & value
|
||||
header: {
|
||||
name: 'custom-key',
|
||||
value: 'custom-value',
|
||||
index: true,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('40' + '8825a849e95ba97d7f' + '8925a849e95bb8e8b4bf', 'hex')
|
||||
}, {
|
||||
// index
|
||||
header: {
|
||||
name: 1,
|
||||
value: 1,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('82', 'hex')
|
||||
}, {
|
||||
// index
|
||||
header: {
|
||||
name: 6,
|
||||
value: 6,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('87', 'hex')
|
||||
}, {
|
||||
// index
|
||||
header: {
|
||||
name: 62,
|
||||
value: 62,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('BF', 'hex')
|
||||
}, {
|
||||
// index
|
||||
header: {
|
||||
name: 65,
|
||||
value: 65,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('C2', 'hex')
|
||||
}, {
|
||||
// index
|
||||
header: {
|
||||
name: 64,
|
||||
value: 64,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('C1', 'hex')
|
||||
}, {
|
||||
// index
|
||||
header: {
|
||||
name: 61,
|
||||
value: 61,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('BE', 'hex')
|
||||
}, {
|
||||
// Literal w/o index, name index
|
||||
header: {
|
||||
@ -239,7 +303,6 @@ var test_headers = [{
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('07' + '86f138d25ee5b3', 'hex')
|
||||
@ -251,7 +314,6 @@ var test_headers = [{
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('00' + '8294e7' + '03626172', 'hex')
|
||||
@ -263,7 +325,6 @@ var test_headers = [{
|
||||
index: false,
|
||||
mustNeverIndex: true,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('17' + '86f138d25ee5b3', 'hex')
|
||||
@ -275,7 +336,6 @@ var test_headers = [{
|
||||
index: false,
|
||||
mustNeverIndex: true,
|
||||
contextUpdate: false,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('10' + '8294e7' + '03626172', 'hex')
|
||||
@ -286,21 +346,9 @@ var test_headers = [{
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: true,
|
||||
clearReferenceSet: true,
|
||||
newMaxSize: 0
|
||||
},
|
||||
buffer: new Buffer('30', 'hex')
|
||||
}, {
|
||||
header: {
|
||||
name: -1,
|
||||
value: -1,
|
||||
index: false,
|
||||
mustNeverIndex: false,
|
||||
contextUpdate: true,
|
||||
clearReferenceSet: false,
|
||||
newMaxSize: 100
|
||||
},
|
||||
buffer: new Buffer('2F55', 'hex')
|
||||
buffer: new Buffer('3F45', 'hex')
|
||||
}];
|
||||
|
||||
var test_header_sets = [{
|
||||
@ -328,7 +376,7 @@ var test_header_sets = [{
|
||||
':authority': 'www.bar.com',
|
||||
'custom-key': 'custom-value'
|
||||
},
|
||||
buffer: util.concat(test_headers.slice(9, 13).map(function(test) { return test.buffer; }))
|
||||
buffer: util.concat(test_headers.slice(9, 14).map(function(test) { return test.buffer; }))
|
||||
}, {
|
||||
headers: {
|
||||
':method': 'GET',
|
||||
@ -337,15 +385,7 @@ var test_header_sets = [{
|
||||
':authority': ['www.foo.com', 'www.bar.com'],
|
||||
'custom-key': 'custom-value'
|
||||
},
|
||||
buffer: test_headers[3].buffer
|
||||
}, {
|
||||
headers: {
|
||||
':status': '200',
|
||||
'user-agent': 'my-user-agent',
|
||||
'cookie': 'first; second; third; third; fourth',
|
||||
'multiple': ['first', 'second', 'third', 'third; fourth'],
|
||||
'verylong': (new Buffer(9000)).toString('hex')
|
||||
}
|
||||
buffer: util.concat(test_headers.slice(14, 19).map(function(test) { return test.buffer; }))
|
||||
}];
|
||||
|
||||
describe('compressor.js', function() {
|
||||
|
80
testing/xpcshell/node-http2/node_modules/http2-protocol/test/framer.js
generated
vendored
80
testing/xpcshell/node-http2/node_modules/http2-protocol/test/framer.js
generated
vendored
@ -21,30 +21,30 @@ var frame_types = {
|
||||
var test_frames = [{
|
||||
frame: {
|
||||
type: 'DATA',
|
||||
flags: { END_STREAM: false, END_SEGMENT: false, RESERVED4: false,
|
||||
flags: { END_STREAM: false, RESERVED2: false, RESERVED4: false,
|
||||
PADDED: false },
|
||||
stream: 10,
|
||||
|
||||
data: new Buffer('12345678', 'hex')
|
||||
},
|
||||
// length + type + flags + stream + content
|
||||
buffer: new Buffer('0004' + '00' + '00' + '0000000A' + '12345678', 'hex')
|
||||
buffer: new Buffer('000004' + '00' + '00' + '0000000A' + '12345678', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
type: 'HEADERS',
|
||||
flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
|
||||
flags: { END_STREAM: false, RESERVED2: false, END_HEADERS: false,
|
||||
PADDED: false, RESERVED5: false, PRIORITY: false },
|
||||
stream: 15,
|
||||
|
||||
data: new Buffer('12345678', 'hex')
|
||||
},
|
||||
buffer: new Buffer('0004' + '01' + '00' + '0000000F' + '12345678', 'hex')
|
||||
buffer: new Buffer('000004' + '01' + '00' + '0000000F' + '12345678', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
type: 'HEADERS',
|
||||
flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
|
||||
flags: { END_STREAM: false, RESERVED2: false, END_HEADERS: false,
|
||||
PADDED: false, RESERVED5: false, PRIORITY: true },
|
||||
stream: 15,
|
||||
priorityDependency: 10,
|
||||
@ -53,13 +53,13 @@ var test_frames = [{
|
||||
|
||||
data: new Buffer('12345678', 'hex')
|
||||
},
|
||||
buffer: new Buffer('0009' + '01' + '20' + '0000000F' + '0000000A' + '05' + '12345678', 'hex')
|
||||
buffer: new Buffer('000009' + '01' + '20' + '0000000F' + '0000000A' + '05' + '12345678', 'hex')
|
||||
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
type: 'HEADERS',
|
||||
flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
|
||||
flags: { END_STREAM: false, RESERVED2: false, END_HEADERS: false,
|
||||
PADDED: false, RESERVED5: false, PRIORITY: true },
|
||||
stream: 15,
|
||||
priorityDependency: 10,
|
||||
@ -68,7 +68,7 @@ var test_frames = [{
|
||||
|
||||
data: new Buffer('12345678', 'hex')
|
||||
},
|
||||
buffer: new Buffer('0009' + '01' + '20' + '0000000F' + '8000000A' + '05' + '12345678', 'hex')
|
||||
buffer: new Buffer('000009' + '01' + '20' + '0000000F' + '8000000A' + '05' + '12345678', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
@ -80,7 +80,7 @@ var test_frames = [{
|
||||
priorityWeight: 5,
|
||||
exclusiveDependency: false
|
||||
},
|
||||
buffer: new Buffer('0005' + '02' + '00' + '0000000A' + '00000009' + '05', 'hex')
|
||||
buffer: new Buffer('000005' + '02' + '00' + '0000000A' + '00000009' + '05', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
@ -92,7 +92,7 @@ var test_frames = [{
|
||||
priorityWeight: 5,
|
||||
exclusiveDependency: true
|
||||
},
|
||||
buffer: new Buffer('0005' + '02' + '00' + '0000000A' + '80000009' + '05', 'hex')
|
||||
buffer: new Buffer('000005' + '02' + '00' + '0000000A' + '80000009' + '05', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
@ -102,7 +102,7 @@ var test_frames = [{
|
||||
|
||||
error: 'INTERNAL_ERROR'
|
||||
},
|
||||
buffer: new Buffer('0004' + '03' + '00' + '0000000A' + '00000002', 'hex')
|
||||
buffer: new Buffer('000004' + '03' + '00' + '0000000A' + '00000002', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
@ -114,13 +114,15 @@ var test_frames = [{
|
||||
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_MAX_FRAME_SIZE: 0x00010000
|
||||
}
|
||||
},
|
||||
buffer: new Buffer('0018' + '04' + '00' + '0000000A' + '0001' + '12345678' +
|
||||
'0002' + '00000001' +
|
||||
'0003' + '01234567' +
|
||||
'0004' + '89ABCDEF', 'hex')
|
||||
buffer: new Buffer('00001E' + '04' + '00' + '0000000A' + '0001' + '12345678' +
|
||||
'0002' + '00000001' +
|
||||
'0003' + '01234567' +
|
||||
'0004' + '89ABCDEF' +
|
||||
'0005' + '00010000', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
@ -132,7 +134,7 @@ var test_frames = [{
|
||||
promised_stream: 3,
|
||||
data: new Buffer('12345678', 'hex')
|
||||
},
|
||||
buffer: new Buffer('0008' + '05' + '00' + '0000000F' + '00000003' + '12345678', 'hex')
|
||||
buffer: new Buffer('000008' + '05' + '00' + '0000000F' + '00000003' + '12345678', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
@ -142,7 +144,7 @@ var test_frames = [{
|
||||
|
||||
data: new Buffer('1234567887654321', 'hex')
|
||||
},
|
||||
buffer: new Buffer('0008' + '06' + '00' + '0000000F' + '1234567887654321', 'hex')
|
||||
buffer: new Buffer('000008' + '06' + '00' + '0000000F' + '1234567887654321', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
@ -153,7 +155,7 @@ var test_frames = [{
|
||||
last_stream: 0x12345678,
|
||||
error: 'PROTOCOL_ERROR'
|
||||
},
|
||||
buffer: new Buffer('0008' + '07' + '00' + '0000000A' + '12345678' + '00000001', 'hex')
|
||||
buffer: new Buffer('000008' + '07' + '00' + '0000000A' + '12345678' + '00000001', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
@ -163,7 +165,7 @@ var test_frames = [{
|
||||
|
||||
window_size: 0x12345678
|
||||
},
|
||||
buffer: new Buffer('0004' + '08' + '00' + '0000000A' + '12345678', 'hex')
|
||||
buffer: new Buffer('000004' + '08' + '00' + '0000000A' + '12345678', 'hex')
|
||||
}, {
|
||||
frame: {
|
||||
type: 'CONTINUATION',
|
||||
@ -173,7 +175,7 @@ var test_frames = [{
|
||||
data: new Buffer('12345678', 'hex')
|
||||
},
|
||||
// length + type + flags + stream + content
|
||||
buffer: new Buffer('0004' + '09' + '04' + '0000000A' + '12345678', 'hex')
|
||||
buffer: new Buffer('000004' + '09' + '04' + '0000000A' + '12345678', 'hex')
|
||||
}, {
|
||||
frame: {
|
||||
type: 'ALTSVC',
|
||||
@ -186,7 +188,7 @@ var test_frames = [{
|
||||
host: "altsvc.example.com",
|
||||
origin: ""
|
||||
},
|
||||
buffer: new Buffer('001D' + '0A' + '00' + '00000000' + '01E13380' + '115B' + '00' + '02' + '6832' + '12' + '616C747376632E6578616D706C652E636F6D', 'hex')
|
||||
buffer: new Buffer('00001D' + '0A' + '00' + '00000000' + '01E13380' + '115B' + '00' + '02' + '6832' + '12' + '616C747376632E6578616D706C652E636F6D', 'hex')
|
||||
}, {
|
||||
frame: {
|
||||
type: 'ALTSVC',
|
||||
@ -199,7 +201,7 @@ var test_frames = [{
|
||||
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')
|
||||
buffer: new Buffer('000037' + '0A' + '00' + '00000000' + '01E13380' + '115B' + '00' + '02' + '6832' + '12' + '616C747376632E6578616D706C652E636F6D' + '68747470733A2F2F6F6E6C796D652E6578616D706C652E636F6D', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
@ -207,37 +209,37 @@ var test_frames = [{
|
||||
flags: { },
|
||||
stream: 10
|
||||
},
|
||||
buffer: new Buffer('0000' + '0B' + '00' + '0000000A', 'hex')
|
||||
buffer: new Buffer('000000' + '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,
|
||||
flags: { END_STREAM: false, RESERVED2: false, RESERVED4: false,
|
||||
PADDED: true },
|
||||
stream: 10,
|
||||
data: new Buffer('12345678', 'hex')
|
||||
},
|
||||
// length + type + flags + stream + pad length + content + padding
|
||||
buffer: new Buffer('000B' + '00' + '08' + '0000000A' + '06' + '12345678' + '000000000000', 'hex')
|
||||
buffer: new Buffer('00000B' + '00' + '08' + '0000000A' + '06' + '12345678' + '000000000000', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
type: 'HEADERS',
|
||||
flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
|
||||
flags: { END_STREAM: false, RESERVED2: false, END_HEADERS: false,
|
||||
PADDED: true, RESERVED5: false, PRIORITY: false },
|
||||
stream: 15,
|
||||
|
||||
data: new Buffer('12345678', 'hex')
|
||||
},
|
||||
// length + type + flags + stream + pad length + data + padding
|
||||
buffer: new Buffer('000B' + '01' + '08' + '0000000F' + '06' + '12345678' + '000000000000', 'hex')
|
||||
buffer: new Buffer('00000B' + '01' + '08' + '0000000F' + '06' + '12345678' + '000000000000', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
type: 'HEADERS',
|
||||
flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
|
||||
flags: { END_STREAM: false, RESERVED2: false, END_HEADERS: false,
|
||||
PADDED: true, RESERVED5: false, PRIORITY: true },
|
||||
stream: 15,
|
||||
priorityDependency: 10,
|
||||
@ -247,12 +249,12 @@ var padded_test_frames = [{
|
||||
data: new Buffer('12345678', 'hex')
|
||||
},
|
||||
// length + type + flags + stream + pad length + priority dependency + priority weight + data + padding
|
||||
buffer: new Buffer('0010' + '01' + '28' + '0000000F' + '06' + '0000000A' + '05' + '12345678' + '000000000000', 'hex')
|
||||
buffer: new Buffer('000010' + '01' + '28' + '0000000F' + '06' + '0000000A' + '05' + '12345678' + '000000000000', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
type: 'HEADERS',
|
||||
flags: { END_STREAM: false, END_SEGMENT: false, END_HEADERS: false,
|
||||
flags: { END_STREAM: false, RESERVED2: false, END_HEADERS: false,
|
||||
PADDED: true, RESERVED5: false, PRIORITY: true },
|
||||
stream: 15,
|
||||
priorityDependency: 10,
|
||||
@ -262,7 +264,7 @@ var padded_test_frames = [{
|
||||
data: new Buffer('12345678', 'hex')
|
||||
},
|
||||
// length + type + flags + stream + pad length + priority dependency + priority weight + data + padding
|
||||
buffer: new Buffer('0010' + '01' + '28' + '0000000F' + '06' + '8000000A' + '05' + '12345678' + '000000000000', 'hex')
|
||||
buffer: new Buffer('000010' + '01' + '28' + '0000000F' + '06' + '8000000A' + '05' + '12345678' + '000000000000', 'hex')
|
||||
|
||||
}, {
|
||||
frame: {
|
||||
@ -275,7 +277,7 @@ var padded_test_frames = [{
|
||||
data: new Buffer('12345678', 'hex')
|
||||
},
|
||||
// length + type + flags + stream + pad length + promised stream + data + padding
|
||||
buffer: new Buffer('000F' + '05' + '08' + '0000000F' + '06' + '00000003' + '12345678' + '000000000000', 'hex')
|
||||
buffer: new Buffer('00000F' + '05' + '08' + '0000000F' + '06' + '00000003' + '12345678' + '000000000000', 'hex')
|
||||
|
||||
}];
|
||||
for (var idx = 0; idx < padded_test_frames.length; idx++) {
|
||||
@ -286,11 +288,11 @@ for (var idx = 0; idx < padded_test_frames.length; idx++) {
|
||||
describe('framer.js', function() {
|
||||
describe('Serializer', function() {
|
||||
describe('static method .commonHeader({ type, flags, stream }, buffer_array)', function() {
|
||||
it('should add the appropriate 8 byte header buffer in front of the others', function() {
|
||||
it('should add the appropriate 9 byte header buffer in front of the others', function() {
|
||||
for (var i = 0; i < test_frames.length; i++) {
|
||||
var test = test_frames[i];
|
||||
var buffers = [test.buffer.slice(8)];
|
||||
var header_buffer = test.buffer.slice(0,8);
|
||||
var buffers = [test.buffer.slice(9)];
|
||||
var header_buffer = test.buffer.slice(0,9);
|
||||
Serializer.commonHeader(test.frame, buffers);
|
||||
expect(buffers[0]).to.deep.equal(header_buffer);
|
||||
}
|
||||
@ -306,7 +308,7 @@ describe('framer.js', function() {
|
||||
var test = tests[i];
|
||||
var buffers = [];
|
||||
Serializer[type](test.frame, buffers);
|
||||
expect(util.concat(buffers)).to.deep.equal(test.buffer.slice(8));
|
||||
expect(util.concat(buffers)).to.deep.equal(test.buffer.slice(9));
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -334,7 +336,7 @@ describe('framer.js', function() {
|
||||
it('should augment the frame object with these properties: { type, flags, stream })', function() {
|
||||
for (var i = 0; i < deserializer_test_frames.length; i++) {
|
||||
var test = deserializer_test_frames[i], frame = {};
|
||||
Deserializer.commonHeader(test.buffer.slice(0,8), frame);
|
||||
Deserializer.commonHeader(test.buffer.slice(0,9), frame);
|
||||
expect(frame).to.deep.equal({
|
||||
type: test.frame.type,
|
||||
flags: test.frame.flags,
|
||||
@ -356,7 +358,7 @@ describe('framer.js', function() {
|
||||
flags: test.frame.flags,
|
||||
stream: test.frame.stream
|
||||
};
|
||||
Deserializer[type](test.buffer.slice(8), frame);
|
||||
Deserializer[type](test.buffer.slice(9), frame);
|
||||
expect(frame).to.deep.equal(test.frame);
|
||||
}
|
||||
});
|
||||
|
@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "http2",
|
||||
"version": "2.6.0",
|
||||
"version": "2.7.1",
|
||||
"description": "An HTTP/2 client and server implementation",
|
||||
"main": "lib/index.js",
|
||||
"engines" : {
|
||||
"node" : ">=0.10.19"
|
||||
},
|
||||
"dependencies": {
|
||||
"http2-protocol": ">=0.13.0"
|
||||
"http2-protocol": ">=0.14.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"istanbul": "*",
|
||||
|
@ -85,7 +85,7 @@ describe('http.js', function() {
|
||||
request[name].apply(request, originalArguments);
|
||||
var mockFallbackRequest = { on: util.noop };
|
||||
mockFallbackRequest[name] = function() {
|
||||
expect(arguments).to.deep.equal(originalArguments);
|
||||
expect(Array.prototype.slice.call(arguments)).to.deep.equal(originalArguments);
|
||||
done();
|
||||
};
|
||||
request._fallback(mockFallbackRequest);
|
||||
@ -111,6 +111,22 @@ describe('http.js', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('OutgoingResponse', function() {
|
||||
it('should throw error when writeHead is called multiple times on it', function() {
|
||||
var called = false;
|
||||
var stream = { _log: util.log, headers: function () {
|
||||
if (called) {
|
||||
throw new Error('Should not send headers twice');
|
||||
} else {
|
||||
called = true;
|
||||
}
|
||||
}, once: util.noop };
|
||||
var response = new http2.OutgoingResponse(stream);
|
||||
|
||||
response.writeHead(200);
|
||||
response.writeHead(404)
|
||||
});
|
||||
});
|
||||
describe('test scenario', function() {
|
||||
describe('simple request', function() {
|
||||
it('should work as expected', function(done) {
|
||||
|
Loading…
Reference in New Issue
Block a user