http2-protocol
Advanced tools
Comparing version 0.13.0 to 0.14.0
Version history | ||
=============== | ||
### 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) ### | ||
@@ -5,0 +11,0 @@ |
@@ -52,33 +52,4 @@ // The implementation of the [HTTP/2 Header Compression][http2-compression] spec is separated from | ||
// 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); | ||
@@ -112,18 +83,16 @@ return entry; | ||
// <---------- 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); | ||
} | ||
@@ -138,3 +107,3 @@ return droppedEntries; | ||
if (this._size <= limit) { | ||
this.unshift(entry); | ||
this.splice(this._staticLength, 0, entry); | ||
this._size += entry._size; | ||
@@ -268,3 +237,2 @@ } | ||
// { name: 2 , value: 2 , index: false } | ||
// { name: -1 , value: -1 , index: false } // reference set emptying | ||
// Literal: | ||
@@ -281,24 +249,7 @@ // { name: 2 , value: 'X', index: false } // without indexing | ||
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') { | ||
@@ -308,18 +259,4 @@ var index = rep.value; | ||
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); | ||
} | ||
@@ -333,3 +270,3 @@ | ||
// * The header is added to the header table. | ||
// * The new entry is added to the reference set. | ||
// * The header is emitted. | ||
else { | ||
@@ -344,4 +281,2 @@ if (typeof rep.name === 'number') { | ||
entry = entryFromPair(pair); | ||
entry.reference = true; | ||
entry.emitted = true; | ||
this._table.add(entry); | ||
@@ -367,11 +302,2 @@ } | ||
// * [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(); | ||
@@ -433,58 +359,8 @@ }; | ||
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 }); | ||
} | ||
@@ -495,3 +371,2 @@ | ||
entry = entryFromPair(pair); | ||
entry.emitted = true; | ||
@@ -501,13 +376,3 @@ 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); | ||
} | ||
@@ -525,13 +390,2 @@ | ||
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(); | ||
@@ -1151,8 +1005,3 @@ }; | ||
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)); | ||
} | ||
@@ -1198,3 +1047,2 @@ | ||
header.contextUpdate = false; | ||
header.clearReferenceSet = false; | ||
header.newMaxSize = 0; | ||
@@ -1205,8 +1053,3 @@ header.mustNeverIndex = false; | ||
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); | ||
} | ||
@@ -1253,3 +1096,3 @@ | ||
var MAX_HTTP_PAYLOAD_SIZE = 16383; | ||
var MAX_HTTP_PAYLOAD_SIZE = 16384; | ||
@@ -1295,12 +1138,2 @@ // The Compressor class | ||
// * 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) { | ||
@@ -1405,16 +1238,11 @@ for (var i = 0; i < value.length; i++) { | ||
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]; | ||
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; | ||
} | ||
@@ -1421,0 +1249,0 @@ } |
@@ -395,2 +395,3 @@ var assert = require('assert'); | ||
this.on('SETTINGS', this._receiveSettings); | ||
this.on('RECEIVING_SETTINGS_MAX_FRAME_SIZE', this._sanityCheckMaxFrameSize); | ||
}; | ||
@@ -434,2 +435,9 @@ | ||
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 | ||
@@ -436,0 +444,0 @@ Connection.prototype.set = function set(settings, callback) { |
@@ -170,4 +170,2 @@ var assert = require('assert'); | ||
var MAX_HTTP_PAYLOAD_SIZE = 16383; | ||
Endpoint.prototype._initializeDataFlow = function _initializeDataFlow(role, settings, filters) { | ||
@@ -185,4 +183,4 @@ var firstStreamId, compressorRole, decompressorRole; | ||
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); | ||
@@ -198,5 +196,5 @@ this._decompressor = new Decompressor(this._log, decompressorRole); | ||
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)); | ||
}; | ||
@@ -203,0 +201,0 @@ |
@@ -22,3 +22,3 @@ var assert = require('assert'); | ||
// | ||
// [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 | ||
@@ -25,0 +25,0 @@ // API for child classes |
@@ -14,3 +14,3 @@ // The framer consists of two [Transform Stream][1] subclasses that operate in [object mode][2]: | ||
var MAX_PAYLOAD_SIZE = 16383; | ||
var MAX_PAYLOAD_SIZE = 16384; | ||
var WINDOW_UPDATE_PAYLOAD_SIZE = 4; | ||
@@ -29,5 +29,4 @@ | ||
function Serializer(log, sizeLimit) { | ||
function Serializer(log) { | ||
this._log = log.child({ component: 'serializer' }); | ||
this._sizeLimit = sizeLimit || MAX_PAYLOAD_SIZE; | ||
Transform.call(this, { objectMode: true }); | ||
@@ -47,5 +46,5 @@ } | ||
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!'); | ||
@@ -73,6 +72,5 @@ for (var i = 0; i < buffers.length; i++) { | ||
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 }); | ||
@@ -121,3 +119,3 @@ this._next(COMMON_HEADER_SIZE); | ||
var payloadSize = Deserializer.commonHeader(this._buffer, this._frame); | ||
if (payloadSize <= this._sizeLimit) { | ||
if (payloadSize <= MAX_PAYLOAD_SIZE) { | ||
this._next(payloadSize); | ||
@@ -156,10 +154,10 @@ } else { | ||
// [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. | ||
// | ||
@@ -169,4 +167,6 @@ // 0 1 2 3 | ||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
// | R | Length (14) | Type (8) | Flags (8) | | ||
// +-+-+---------------------------+---------------+---------------+ | ||
// | Length (24) | | ||
// +---------------+---------------+---------------+ | ||
// | Type (8) | Flags (8) | | ||
// +-+-----------------------------+---------------+---------------+ | ||
// |R| Stream Identifier (31) | | ||
@@ -179,8 +179,4 @@ // +-+-------------------------------------------------------------+ | ||
// | ||
// * 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. | ||
@@ -208,3 +204,3 @@ // | ||
var COMMON_HEADER_SIZE = 8; | ||
var COMMON_HEADER_SIZE = 9; | ||
@@ -226,6 +222,7 @@ var frameTypes = []; | ||
} | ||
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); | ||
@@ -240,14 +237,20 @@ var flagByte = 0; | ||
} | ||
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) { | ||
@@ -259,3 +262,3 @@ // We are required to ignore unknown frame types | ||
frame.flags = {}; | ||
var flagByte = buffer.readUInt8(3); | ||
var flagByte = buffer.readUInt8(4); | ||
var definedFlags = frameFlags[frame.type]; | ||
@@ -266,3 +269,3 @@ for (var i = 0; i < definedFlags.length; i++) { | ||
frame.stream = buffer.readUInt32BE(4) & 0x7fffffff; | ||
frame.stream = buffer.readUInt32BE(5) & 0x7fffffff; | ||
@@ -282,3 +285,3 @@ return length; | ||
// [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) | ||
// ------------------------------------------------------------ | ||
@@ -294,6 +297,2 @@ // | ||
// 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): | ||
@@ -304,3 +303,3 @@ // Bit 4 being set indicates that the Pad Length field is present. | ||
frameFlags.DATA = ['END_STREAM', 'END_SEGMENT', 'RESERVED4', 'PADDED']; | ||
frameFlags.DATA = ['END_STREAM', 'RESERVED2', 'RESERVED4', 'PADDED']; | ||
@@ -328,3 +327,3 @@ typeSpecificAttributes.DATA = ['data']; | ||
// [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) | ||
// -------------------------------------------------------------- | ||
@@ -339,6 +338,2 @@ // | ||
// 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): | ||
@@ -355,3 +350,3 @@ // The END_HEADERS bit indicates that this frame contains the entire payload necessary to provide | ||
frameFlags.HEADERS = ['END_STREAM', 'END_SEGMENT', 'END_HEADERS', 'PADDED', 'RESERVED5', 'PRIORITY']; | ||
frameFlags.HEADERS = ['END_STREAM', 'RESERVED2', 'END_HEADERS', 'PADDED', 'RESERVED5', 'PRIORITY']; | ||
@@ -417,3 +412,3 @@ typeSpecificAttributes.HEADERS = ['priorityDependency', 'priorityWeight', 'exclusiveDependency', 'headers', 'data']; | ||
// [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) | ||
// ------------------------------------------------------- | ||
@@ -463,3 +458,3 @@ // | ||
// [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) | ||
// ----------------------------------------------------------- | ||
@@ -502,3 +497,3 @@ // | ||
// [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) | ||
// ------------------------------------------------------- | ||
@@ -606,3 +601,7 @@ // | ||
// [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) | ||
// --------------------------------------------------------------- | ||
@@ -668,3 +667,3 @@ // | ||
// [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) | ||
// ----------------------------------------------- | ||
@@ -699,3 +698,3 @@ // | ||
// [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) | ||
// --------------------------------------------------- | ||
@@ -751,3 +750,3 @@ // | ||
// [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) | ||
// ----------------------------------------------------------------- | ||
@@ -774,3 +773,3 @@ // | ||
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); | ||
@@ -786,5 +785,8 @@ | ||
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) | ||
// ------------------------------------------------------------ | ||
@@ -814,3 +816,3 @@ // | ||
// [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) | ||
// ------------------------------------------------------------ | ||
@@ -904,3 +906,3 @@ // | ||
// [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) | ||
// ------------------------------------------------------------ | ||
@@ -925,3 +927,3 @@ // | ||
// [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) | ||
// ------------------------------------------------------------ | ||
@@ -928,0 +930,0 @@ |
@@ -1,2 +0,2 @@ | ||
// [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]. | ||
@@ -31,6 +31,6 @@ // | ||
// [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/ | ||
@@ -41,3 +41,3 @@ // [node-stream]: http://nodejs.org/api/stream.html | ||
exports.ImplementedVersion = 'h2-13'; | ||
exports.ImplementedVersion = 'h2-14'; | ||
@@ -44,0 +44,0 @@ exports.Endpoint = require('./endpoint').Endpoint; |
@@ -243,2 +243,6 @@ var assert = require('assert'); | ||
if (frame.type === 'HEADERS') { | ||
if (this._processedHeaders && !frame.flags['END_STREAM']) { | ||
this.emit('error', 'PROTOCOL_ERROR'); | ||
} | ||
this._processedHeaders = true; | ||
this._onHeaders(frame); | ||
@@ -350,3 +354,3 @@ } else if (frame.type === 'PUSH_PROMISE') { | ||
// [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) | ||
// ---------------- | ||
@@ -386,2 +390,3 @@ // | ||
this._closedWithRst = undefined; | ||
this._processedHeaders = false; | ||
}; | ||
@@ -388,0 +393,0 @@ |
{ | ||
"name": "http2-protocol", | ||
"version": "0.13.0", | ||
"version": "0.14.0", | ||
"description": "A JavaScript implementation of the HTTP/2 framing layer", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
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 | ||
@@ -8,0 +10,0 @@ ------------ |
@@ -79,41 +79,38 @@ var expect = require('chai').expect; | ||
var test_headers = [{ | ||
// literal w/index, name index | ||
// index | ||
header: { | ||
name: 1, | ||
value: 'GET', | ||
index: true, | ||
value: 1, | ||
index: false, | ||
mustNeverIndex: false, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
}, | ||
buffer: new Buffer('42' + '03474554', 'hex') | ||
buffer: new Buffer('82', 'hex') | ||
}, { | ||
// literal w/index, name index | ||
// index | ||
header: { | ||
name: 6, | ||
value: 'http', | ||
index: true, | ||
name: 5, | ||
value: 5, | ||
index: false, | ||
mustNeverIndex: false, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
}, | ||
buffer: new Buffer('47' + '839d29af', 'hex') | ||
buffer: new Buffer('86', 'hex') | ||
}, { | ||
// literal w/index, name index | ||
// index | ||
header: { | ||
name: 5, | ||
value: '/', | ||
index: true, | ||
name: 3, | ||
value: 3, | ||
index: false, | ||
mustNeverIndex: false, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
}, | ||
buffer: new Buffer('46' + '012F', 'hex') | ||
buffer: new Buffer('84', 'hex') | ||
}, { | ||
// literal w/index, name index | ||
header: { | ||
name: 3, | ||
name: 0, | ||
value: 'www.foo.com', | ||
@@ -123,22 +120,42 @@ index: true, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
}, | ||
buffer: new Buffer('44' + '89f1e3c2f29ceb90f4ff', 'hex') | ||
buffer: new Buffer('41' + '89f1e3c2f29ceb90f4ff', 'hex') | ||
}, { | ||
// literal w/index, name index | ||
// indexed | ||
header: { | ||
name: 2, | ||
value: 'https', | ||
index: true, | ||
name: 1, | ||
value: 1, | ||
index: false, | ||
mustNeverIndex: false, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
}, | ||
buffer: new Buffer('43' + '849d29ad1f', 'hex') | ||
buffer: new Buffer('82', 'hex') | ||
}, { | ||
// indexed | ||
header: { | ||
name: 6, | ||
value: 6, | ||
index: false, | ||
mustNeverIndex: false, | ||
contextUpdate: 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: 1, | ||
name: 0, | ||
value: 'www.bar.com', | ||
@@ -148,10 +165,9 @@ index: true, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
}, | ||
buffer: new Buffer('42' + '89f1e3c2f18ec5c87a7f', 'hex') | ||
buffer: new Buffer('41' + '89f1e3c2f18ec5c87a7f', 'hex') | ||
}, { | ||
// literal w/index, name index | ||
header: { | ||
name: 29, | ||
name: 23, | ||
value: 'no-cache', | ||
@@ -161,34 +177,31 @@ index: true, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
}, | ||
buffer: new Buffer('5e' + '86a8eb10649cbf', 'hex') | ||
buffer: new Buffer('58' + '86a8eb10649cbf', 'hex') | ||
}, { | ||
// indexed | ||
// index | ||
header: { | ||
name: 3, | ||
value: 3, | ||
name: 1, | ||
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, | ||
name: 6, | ||
value: 6, | ||
index: false, | ||
mustNeverIndex: false, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
}, | ||
buffer: new Buffer('86', 'hex') | ||
buffer: new Buffer('87', 'hex') | ||
}, { | ||
// literal w/index, name index | ||
header: { | ||
name: 4, | ||
name: 3, | ||
value: '/custom-path.css', | ||
@@ -198,7 +211,17 @@ index: true, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
}, | ||
buffer: new Buffer('45' + '8b6096a127a56ac699d72211', 'hex') | ||
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 | ||
@@ -211,3 +234,2 @@ header: { | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
@@ -217,15 +239,14 @@ }, | ||
}, { | ||
// indexed | ||
// index | ||
header: { | ||
name: 2, | ||
value: 2, | ||
name: 1, | ||
value: 1, | ||
index: false, | ||
mustNeverIndex: false, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
}, | ||
buffer: new Buffer('83', 'hex') | ||
buffer: new Buffer('82', 'hex') | ||
}, { | ||
// indexed | ||
// index | ||
header: { | ||
@@ -237,3 +258,2 @@ name: 6, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
@@ -243,2 +263,46 @@ }, | ||
}, { | ||
// 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 | ||
@@ -251,3 +315,2 @@ header: { | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
@@ -264,3 +327,2 @@ }, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
@@ -277,3 +339,2 @@ }, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
@@ -290,3 +351,2 @@ }, | ||
contextUpdate: false, | ||
clearReferenceSet: false, | ||
newMaxSize: 0 | ||
@@ -302,17 +362,5 @@ }, | ||
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') | ||
}]; | ||
@@ -345,3 +393,3 @@ | ||
}, | ||
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; })) | ||
}, { | ||
@@ -355,11 +403,3 @@ headers: { | ||
}, | ||
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; })) | ||
}]; | ||
@@ -366,0 +406,0 @@ |
@@ -24,3 +24,3 @@ var expect = require('chai').expect; | ||
type: 'DATA', | ||
flags: { END_STREAM: false, END_SEGMENT: false, RESERVED4: false, | ||
flags: { END_STREAM: false, RESERVED2: false, RESERVED4: false, | ||
PADDED: false }, | ||
@@ -32,3 +32,3 @@ stream: 10, | ||
// length + type + flags + stream + content | ||
buffer: new Buffer('0004' + '00' + '00' + '0000000A' + '12345678', 'hex') | ||
buffer: new Buffer('000004' + '00' + '00' + '0000000A' + '12345678', 'hex') | ||
@@ -38,3 +38,3 @@ }, { | ||
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 }, | ||
@@ -45,3 +45,3 @@ stream: 15, | ||
}, | ||
buffer: new Buffer('0004' + '01' + '00' + '0000000F' + '12345678', 'hex') | ||
buffer: new Buffer('000004' + '01' + '00' + '0000000F' + '12345678', 'hex') | ||
@@ -51,3 +51,3 @@ }, { | ||
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 }, | ||
@@ -61,3 +61,3 @@ stream: 15, | ||
}, | ||
buffer: new Buffer('0009' + '01' + '20' + '0000000F' + '0000000A' + '05' + '12345678', 'hex') | ||
buffer: new Buffer('000009' + '01' + '20' + '0000000F' + '0000000A' + '05' + '12345678', 'hex') | ||
@@ -68,3 +68,3 @@ | ||
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 }, | ||
@@ -78,3 +78,3 @@ stream: 15, | ||
}, | ||
buffer: new Buffer('0009' + '01' + '20' + '0000000F' + '8000000A' + '05' + '12345678', 'hex') | ||
buffer: new Buffer('000009' + '01' + '20' + '0000000F' + '8000000A' + '05' + '12345678', 'hex') | ||
@@ -91,3 +91,3 @@ }, { | ||
}, | ||
buffer: new Buffer('0005' + '02' + '00' + '0000000A' + '00000009' + '05', 'hex') | ||
buffer: new Buffer('000005' + '02' + '00' + '0000000A' + '00000009' + '05', 'hex') | ||
@@ -104,3 +104,3 @@ }, { | ||
}, | ||
buffer: new Buffer('0005' + '02' + '00' + '0000000A' + '80000009' + '05', 'hex') | ||
buffer: new Buffer('000005' + '02' + '00' + '0000000A' + '80000009' + '05', 'hex') | ||
@@ -115,3 +115,3 @@ }, { | ||
}, | ||
buffer: new Buffer('0004' + '03' + '00' + '0000000A' + '00000002', 'hex') | ||
buffer: new Buffer('000004' + '03' + '00' + '0000000A' + '00000002', 'hex') | ||
@@ -128,9 +128,11 @@ }, { | ||
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') | ||
@@ -147,3 +149,3 @@ }, { | ||
}, | ||
buffer: new Buffer('0008' + '05' + '00' + '0000000F' + '00000003' + '12345678', 'hex') | ||
buffer: new Buffer('000008' + '05' + '00' + '0000000F' + '00000003' + '12345678', 'hex') | ||
@@ -158,3 +160,3 @@ }, { | ||
}, | ||
buffer: new Buffer('0008' + '06' + '00' + '0000000F' + '1234567887654321', 'hex') | ||
buffer: new Buffer('000008' + '06' + '00' + '0000000F' + '1234567887654321', 'hex') | ||
@@ -170,3 +172,3 @@ }, { | ||
}, | ||
buffer: new Buffer('0008' + '07' + '00' + '0000000A' + '12345678' + '00000001', 'hex') | ||
buffer: new Buffer('000008' + '07' + '00' + '0000000A' + '12345678' + '00000001', 'hex') | ||
@@ -181,3 +183,3 @@ }, { | ||
}, | ||
buffer: new Buffer('0004' + '08' + '00' + '0000000A' + '12345678', 'hex') | ||
buffer: new Buffer('000004' + '08' + '00' + '0000000A' + '12345678', 'hex') | ||
}, { | ||
@@ -192,3 +194,3 @@ frame: { | ||
// length + type + flags + stream + content | ||
buffer: new Buffer('0004' + '09' + '04' + '0000000A' + '12345678', 'hex') | ||
buffer: new Buffer('000004' + '09' + '04' + '0000000A' + '12345678', 'hex') | ||
}, { | ||
@@ -206,3 +208,3 @@ frame: { | ||
}, | ||
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') | ||
}, { | ||
@@ -220,3 +222,3 @@ frame: { | ||
}, | ||
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') | ||
@@ -229,3 +231,3 @@ }, { | ||
}, | ||
buffer: new Buffer('0000' + '0B' + '00' + '0000000A', 'hex') | ||
buffer: new Buffer('000000' + '0B' + '00' + '0000000A', 'hex') | ||
}]; | ||
@@ -237,3 +239,3 @@ | ||
type: 'DATA', | ||
flags: { END_STREAM: false, END_SEGMENT: false, RESERVED4: false, | ||
flags: { END_STREAM: false, RESERVED2: false, RESERVED4: false, | ||
PADDED: true }, | ||
@@ -244,3 +246,3 @@ stream: 10, | ||
// 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') | ||
@@ -250,3 +252,3 @@ }, { | ||
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 }, | ||
@@ -258,3 +260,3 @@ stream: 15, | ||
// 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') | ||
@@ -264,3 +266,3 @@ }, { | ||
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 }, | ||
@@ -275,3 +277,3 @@ stream: 15, | ||
// 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') | ||
@@ -281,3 +283,3 @@ }, { | ||
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 }, | ||
@@ -292,3 +294,3 @@ stream: 15, | ||
// 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') | ||
@@ -306,3 +308,3 @@ }, { | ||
// 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') | ||
@@ -318,7 +320,7 @@ }]; | ||
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); | ||
@@ -339,3 +341,3 @@ expect(buffers[0]).to.deep.equal(header_buffer); | ||
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)); | ||
} | ||
@@ -368,3 +370,3 @@ }); | ||
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({ | ||
@@ -391,3 +393,3 @@ type: test.frame.type, | ||
}; | ||
Deserializer[type](test.buffer.slice(8), frame); | ||
Deserializer[type](test.buffer.slice(9), frame); | ||
expect(frame).to.deep.equal(test.frame); | ||
@@ -394,0 +396,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
24
88
238964
5620
4