Skip to content

Commit

Permalink
Merge pull request #241 from mcmanus/originFrame
Browse files Browse the repository at this point in the history
Support for ORIGIN FRAME
  • Loading branch information
nwgh authored Feb 16, 2018
2 parents 4f174b2 + 9759f5c commit f3189f3
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 31 deletions.
13 changes: 12 additions & 1 deletion lib/protocol/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ Connection.prototype._initializeStreamManagement = function _initializeStreamMan
Connection.prototype._writeControlFrame = function _writeControlFrame(frame) {
if ((frame.type === 'SETTINGS') || (frame.type === 'PING') ||
(frame.type === 'GOAWAY') || (frame.type === 'WINDOW_UPDATE') ||
(frame.type === 'ALTSVC')) {
(frame.type === 'ALTSVC') || (frame.type == 'ORIGIN')) {
this._log.debug({ frame: frame }, 'Receiving connection level frame');
this.emit(frame.type, frame);
} else {
Expand Down Expand Up @@ -557,6 +557,17 @@ Connection.prototype._receivePing = function _receivePing(frame) {
}
};

Connection.prototype.originFrame = function originFrame(originList) {
this._log.debug(originList, 'emitting origin frame');

this.push({
type: 'ORIGIN',
flags: {},
stream: 0,
originList : originList,
});
};

// Terminating the connection
Connection.prototype.close = function close(error) {
if (this._closed) {
Expand Down
10 changes: 1 addition & 9 deletions lib/protocol/flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ function Flow(flowControlId) {
this._queue = [];
this._ended = false;
this._received = 0;
this._blocked = false;
}
Flow.prototype = Object.create(Duplex.prototype, { constructor: { value: Flow } });

Expand Down Expand Up @@ -157,7 +156,6 @@ Flow.prototype._read = function _read() {
// * if there are items in the flow control queue, then let's put them into the output queue (to
// the extent it is possible with respect to the window size and output queue feedback)
else if (this._window > 0) {
this._blocked = false;
this._readableState.sync = true; // to avoid reentrant calls
do {
var moreNeeded = this._push(this._queue[0]);
Expand All @@ -173,14 +171,8 @@ Flow.prototype._read = function _read() {
}

// * otherwise, come back when the flow control window is positive
else if (!this._blocked) {
this._parentPush({
type: 'BLOCKED',
flags: {},
stream: this._flowControlId
});
else {
this.once('window_update', this._read);
this._blocked = true;
}
};

Expand Down
29 changes: 15 additions & 14 deletions lib/protocol/framer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1069,26 +1069,27 @@ Deserializer.ALTSVC = function readAltSvc(buffer, frame) {
}
};

// BLOCKED
// ------------------------------------------------------------
//
// The BLOCKED frame (type=0xB) indicates that the sender is unable to send data
// due to a closed flow control window.
//
// The BLOCKED frame does not define any flags and contains no payload.

frameTypes[0xB] = 'BLOCKED';
// frame 0xB was BLOCKED and some versions of chrome will
// throw PROTOCOL_ERROR upon seeing it with non 0 payload

frameFlags.BLOCKED = [];
frameTypes[0xC] = 'ORIGIN';
frameFlags.ORIGIN = [];
typeSpecificAttributes.ORIGIN = ['originList'];

typeSpecificAttributes.BLOCKED = [];

Serializer.BLOCKED = function writeBlocked(frame, buffers) {
Serializer.ORIGIN = function writeOrigin(frame, buffers) {
for (var i = 0; i < frame.originList.length; i++) {
var buffer = new Buffer(2);
buffer.writeUInt16BE(frame.originList[i].length, 0);
buffers.push(buffer);
buffers.push(new Buffer(frame.originList[i], 'ascii'));
}
};

Deserializer.BLOCKED = function readBlocked(buffer, frame) {
Deserializer.ORIGIN = function readOrigin(buffer, frame) {
// ignored
};


// [Error Codes](https://tools.ietf.org/html/rfc7540#section-7)
// ------------------------------------------------------------

Expand Down
14 changes: 7 additions & 7 deletions lib/protocol/stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ Stream.prototype._writeUpstream = function _writeUpstream(frame) {
this._onPriority(frame);
} else if (frame.type === 'ALTSVC') {
// TODO
} else if (frame.type === 'BLOCKED') {
} else if (frame.type === 'ORIGIN') {
// TODO
}

Expand Down Expand Up @@ -413,7 +413,7 @@ Stream.prototype._transition = function transition(sending, frame) {
var connectionError;
var streamError;

var DATA = false, HEADERS = false, PRIORITY = false, ALTSVC = false, BLOCKED = false;
var DATA = false, HEADERS = false, PRIORITY = false, ALTSVC = false, ORIGIN = false;
var RST_STREAM = false, PUSH_PROMISE = false, WINDOW_UPDATE = false;
switch(frame.type) {
case 'DATA' : DATA = true; break;
Expand All @@ -423,7 +423,7 @@ Stream.prototype._transition = function transition(sending, frame) {
case 'PUSH_PROMISE' : PUSH_PROMISE = true; break;
case 'WINDOW_UPDATE': WINDOW_UPDATE = true; break;
case 'ALTSVC' : ALTSVC = true; break;
case 'BLOCKED' : BLOCKED = true; break;
case 'ORIGIN' : ORIGIN = true; break;
}

var previousState = this.state;
Expand Down Expand Up @@ -483,7 +483,7 @@ Stream.prototype._transition = function transition(sending, frame) {
this._setState('CLOSED');
} else if (receiving && HEADERS) {
this._setState('HALF_CLOSED_LOCAL');
} else if (BLOCKED || PRIORITY) {
} else if (PRIORITY || ORIGIN) {
/* No state change */
} else {
connectionError = 'PROTOCOL_ERROR';
Expand Down Expand Up @@ -518,7 +518,7 @@ Stream.prototype._transition = function transition(sending, frame) {
case 'HALF_CLOSED_LOCAL':
if (RST_STREAM || (receiving && frame.flags.END_STREAM)) {
this._setState('CLOSED');
} else if (BLOCKED || ALTSVC || receiving || PRIORITY || (sending && WINDOW_UPDATE)) {
} else if (ORIGIN || ALTSVC || receiving || PRIORITY || (sending && WINDOW_UPDATE)) {
/* No state change */
} else {
connectionError = 'PROTOCOL_ERROR';
Expand All @@ -538,7 +538,7 @@ Stream.prototype._transition = function transition(sending, frame) {
case 'HALF_CLOSED_REMOTE':
if (RST_STREAM || (sending && frame.flags.END_STREAM)) {
this._setState('CLOSED');
} else if (BLOCKED || ALTSVC || sending || PRIORITY || (receiving && WINDOW_UPDATE)) {
} else if (ORIGIN || ALTSVC || sending || PRIORITY || (receiving && WINDOW_UPDATE)) {
/* No state change */
} else {
connectionError = 'PROTOCOL_ERROR';
Expand Down Expand Up @@ -569,7 +569,7 @@ Stream.prototype._transition = function transition(sending, frame) {
if (PRIORITY || (sending && RST_STREAM) ||
(receiving && WINDOW_UPDATE) ||
(receiving && this._closedByUs &&
(this._closedWithRst || RST_STREAM || ALTSVC))) {
(this._closedWithRst || RST_STREAM || ALTSVC || ORIGIN))) {
/* No state change */
} else {
streamError = 'STREAM_CLOSED';
Expand Down

0 comments on commit f3189f3

Please sign in to comment.