Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix tests on latest Node.js #5

Merged
merged 9 commits into from
Aug 31, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .jshintignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
node_modules/
node_modules/
2 changes: 1 addition & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ coverage
.vscode/.browse*
npm-debug.log
typings
builds
builds
7 changes: 2 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
language: node_js
node_js:
- "4"
# - "6"
# - "7"
script: mocha
env:
- COMMAND=test
- "6"
- "8"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Original Source and Fork intent

This NodeJS `http2.js` module version is a fork of `node-http2` hosted on Github originally made by Gábor Molnár and available here: https://github.com/molnarg/node-http2

This fork of `node-http2` module named `http2.js` starts at version `4.0.0` in case previous the repository decides to pick up work again on version `3.x.x`.
This fork of `node-http2` module named `http2.js` starts at version `4.0.0` in case previous the repository decides to pick up work again on version `3.x.x`.

We are aware that node 8.4.0 now has experimental `http2` support via `--expose-http2`, and we will continue to support the full JavaScript implementation of `http2.js` at our discretion until HTTP/2 is more fully supported in a broad range of client platforms.

Expand Down
44 changes: 21 additions & 23 deletions lib/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,8 @@ IncomingMessage.prototype._validateHeaders = function _validateHeaders(headers)
for (var i = 0; i < deprecatedHeaders.length; i++) {
var key = deprecatedHeaders[i];
if (key in headers || (key === 'te' && headers[key] !== 'trailers')) {
this._log.error({ key: key, value: headers[key] }, 'Deprecated header found');
this.stream.reset('PROTOCOL_ERROR');
this._log.error({ key: key, value: headers[key] }, 'Deprecated header found');
this.stream.reset('PROTOCOL_ERROR');
return;
}
}
Expand All @@ -367,7 +367,7 @@ IncomingMessage.prototype._validateHeaders = function _validateHeaders(headers)
if(headerNamePattern.test(headerName)) {
this.stream.reset('PROTOCOL_ERROR');
return;
}
}
}
}
};
Expand Down Expand Up @@ -411,13 +411,14 @@ OutgoingMessage.prototype._finish = function _finish() {
this.once('socket', this._finish.bind(this));
}
};

OutgoingMessage.prototype.setHeader = function setHeader(name, value) {
if (this.headersSent) {
return this.emit('error', new Error('Can\'t set headers after they are sent.'));
} else {
name = name.toLowerCase();
if (deprecatedHeaders.indexOf(name) !== -1) {
return this.emit('error', new Error('Cannot set deprecated header: ' + name));
return this.emit('error', new Error('Cannot set deprecated header: ' + name));
}
this._headers[name] = value;
}
Expand Down Expand Up @@ -1016,25 +1017,25 @@ Agent.prototype.request = function request(options, callback) {
endpoint.socket = options.transport;

endpoint.socket.on('error', function (error) {
self._log.error('Socket error: ' + error.toString());
request.emit('error', error);
self._log.error('Socket error: ' + error.toString());
request.emit('error', error);
});

endpoint.on('error', function(error){
self._log.error('Connection error: ' + error.toString());
request.emit('error', error);
self._log.error('Connection error: ' + error.toString());
request.emit('error', error);
});

endpoint.socket.on('close', function (error) {
// DPW This is sort of a hack to protect against
// the reuse of a endpoint that has the underlying
// connection closed. It would probably be better
// to implement this near lin 933 (if (key in this.endpoints))
// by checking the endpoint state (requires new API to expose)

// Alternatively, this could be a bug with my WS connection
// not emitting an error when it is unexpectedly closed ??
delete self.endpoints[key];
// DPW This is sort of a hack to protect against
// the reuse of a endpoint that has the underlying
// connection closed. It would probably be better
// to implement this near lin 933 (if (key in this.endpoints))
// by checking the endpoint state (requires new API to expose)

// Alternatively, this could be a bug with my WS connection
// not emitting an error when it is unexpectedly closed ??
delete self.endpoints[key];
});

this.endpoints[key] = endpoint;
Expand Down Expand Up @@ -1167,7 +1168,7 @@ function unbundleSocket(socket) {
}

function hasValue(obj) {
return obj === null && obj === undefined;
return obj != null;
}


Expand Down Expand Up @@ -1225,12 +1226,9 @@ OutgoingRequest.prototype._start = function _start(stream, options) {

headers[':scheme'] = options.protocol.slice(0, -1);
headers[':method'] = options.method;
if(options.port)
{
if (options.port) {
headers[':authority'] = options.host + ':' + options.port;
}
else
{
} else {
headers[':authority'] = options.host;
}
headers[':path'] = options.path;
Expand Down
34 changes: 25 additions & 9 deletions lib/protocol/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,26 @@ Connection.prototype.createStream = function createStream() {
var stream = new Stream(this._log, this);
this._allocatePriority(stream);

stream.on('end', this._removeStream.bind(this, stream));
stream.on('state', this._streamStateChange.bind(this, stream));

return stream;
};

Connection.prototype._streamStateChange = function _removeStream(stream, state) {
if (state === 'CLOSED') {
if (!stream._closedByUs) {
this._removeStream(stream)
} else {
// An endpoint MUST ignore frames that it receives on closed streams after
// it has sent a RST_STREAM frame. An endpoint MAY choose to limit the
// period over which it ignores frames and treat frames that arrive after
// this time as being in error.
setTimeout(this._removeStream.bind(self, stream), 30000) // TODO: make timeout configurable
}
}
};


Connection.prototype._removeStream = function _removeStream(stream) {
this._log.trace('Removing outbound stream.');

Expand Down Expand Up @@ -285,7 +300,7 @@ Connection.prototype._send = function _send(immediate) {
} else {
if (!this._sendScheduled) {
this._sendScheduled = true;
timers.setImmediate(this._send.bind(this, true));
timers.setImmediate(this._send.bind(this, true));
}
return;
}
Expand All @@ -303,7 +318,7 @@ priority_loop:
// 2. if there's no frame, skip this stream
// 3. if forwarding this frame would make `streamCount` greater than `streamLimit`, skip
// this stream
// 4. adding stream to the bucket of the next round unless it has ended
// 4. adding stream to the bucket of the next round
// 5. assigning an ID to the frame (allocating an ID to the stream if there isn't already)
// 6. if forwarding a PUSH_PROMISE, allocate ID to the promised stream
// 7. forwarding the frame, changing `streamCount` as appropriate
Expand All @@ -312,7 +327,6 @@ priority_loop:
while (bucket.length > 0) {
for (var index = 0; index < bucket.length; index++) {
var stream = bucket[index];
if(!stream || !stream.upstream) continue;
var frame = stream.upstream.read((this._window > 0) ? this._window : -1);

if (!frame) {
Expand All @@ -322,11 +336,7 @@ priority_loop:
continue;
}

if (!stream._ended) {
nextBucket.push(stream);
} else {
delete this._streamIds[stream.id];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose _removeStream() delete the item in _streamIds

}
nextBucket.push(stream);

if (frame.stream === undefined) {
frame.stream = stream.id || this._allocateId(stream);
Expand Down Expand Up @@ -396,6 +406,12 @@ Connection.prototype._receive = function _receive(frame, done) {

// * or creates one if it's not in `this.streams`
if (!stream) {
if (frame.type === 'PRIORITY') {
// Priority frames can be sent on closed streams that have already been
// removed, or idle streams. Because priority dependencies are missing in
// this implementation anyway, these frames can simply be ignored.
return;
}
stream = this._createIncomingStream(frame.stream);
}

Expand Down
18 changes: 14 additions & 4 deletions lib/protocol/flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,10 @@ Flow.prototype.read = function read(limit) {
}

// * Looking at the first frame in the queue without pulling it out if possible.
var frame = this._readableState.buffer[0];
var frame = bufferHead(this._readableState.buffer);
if (!frame && !this._readableState.ended) {
this._read();
frame = this._readableState.buffer[0];
frame = bufferHead(this._readableState.buffer);
}

if (frame && (frame.type === 'DATA')) {
Expand Down Expand Up @@ -297,8 +297,7 @@ Flow.prototype.push = function push(frame) {
// `getLastQueuedFrame` returns the last frame in output buffers. This is primarily used by the
// [Stream](stream.html) class to mark the last frame with END_STREAM flag.
Flow.prototype.getLastQueuedFrame = function getLastQueuedFrame() {
var readableQueue = this._readableState.buffer;
return this._queue[this._queue.length - 1] || readableQueue[readableQueue.length - 1];
return this._queue[this._queue.length - 1] || bufferTail(this._readableState.buffer);
};

// Outgoing frames - managing the window size
Expand Down Expand Up @@ -352,3 +351,14 @@ Flow.prototype.setInitialWindow = function setInitialWindow(initialWindow) {
this._increaseWindow(initialWindow - this._initialWindow);
this._initialWindow = initialWindow;
};

// The node stream internal buffer was changed from an Array to a linked list in node v6.3.0
function bufferHead (buffer) {
if ('head' in buffer) return buffer.head && buffer.head.data
return buffer[0]
}

function bufferTail (buffer) {
if ('tail' in buffer) return buffer.tail && buffer.tail.data
return buffer[buffer.length - 1]
}
12 changes: 6 additions & 6 deletions lib/protocol/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ exports.Endpoint = require('./endpoint').Endpoint;
exports.serializers = {};
var modules = ['./framer', './compressor', './flow', './connection', './stream', './endpoint'];
try {
modules.map(require).forEach(function (module) {
for (var name in module.serializers) {
exports.serializers[name] = module.serializers[name];
}
});
modules.map(require).forEach(function (module) {
for (var name in module.serializers) {
exports.serializers[name] = module.serializers[name];
}
});
} catch (e) {
// NOOP, probably in browser
// NOOP, probably in browser
}


Expand Down
22 changes: 6 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,19 @@
"engines": {
"node": ">=0.12.0"
},
"dependencies": {
"assert": "1.4.1",
"events": "1.1.1",
"https-browserify": "0.0.1",
"setimmediate": "^1.0.5",
"stream-browserify": "2.0.1",
"timers-browserify": "2.0.2",
"url": "^0.11.0",
"websocket-stream": "^5.0.1"
},
"devDependencies": {
"jshint": "*",
"istanbul": "*",
"bunyan": "^2.0.2",
"chai": "*",
"mocha": "*",
"docco": "*",
"browserify": "14.0.0 ",
"bunyan": "*"
"istanbul": "*",
"jshint": "*",
"mocha": "*",
"websocket-stream": "^5.0.1"
},
"scripts": {
"lint": "jshint",
"pretest": "npm run lint",
"test": "istanbul test _mocha -- --reporter spec --slow 500 --timeout 15000",
"test": "istanbul test node_modules/mocha/bin/_mocha -- --reporter spec --slow 500 --timeout 15000",
"doc": "docco lib/* --output doc --layout parallel --template root.jst --css doc/docco.css && docco lib/protocol/* --output doc/protocol --layout parallel --template protocol.jst --css doc/docco.css"
},
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion test/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ describe('connection.js', function() {
do {
newPriority = randomPriority();
} while(newPriority === oldPriority);

stream = { _priority: oldPriority };
connection._insert(stream, oldPriority);
connection._reprioritize(stream, newPriority);
Expand Down
4 changes: 2 additions & 2 deletions test/flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ describe('flow.js', function() {
flow._increaseWindow(Infinity);
var increase = util.random(1,100);

expect(flow._increaseWindow.bind(flow, increase)).to.throw('Uncaught, unspecified "error" event.');
expect(flow._increaseWindow.bind(flow, increase)).to.throw(util.uncaughtErrorEventMessage);
});
it('should emit error when `_window` grows over the window limit', function() {
var WINDOW_SIZE_LIMIT = Math.pow(2, 31) - 1;
flow._send = util.noop;
flow._window = 0;

flow._increaseWindow(WINDOW_SIZE_LIMIT);
expect(flow._increaseWindow.bind(flow, 1)).to.throw('Uncaught, unspecified "error" event.');
expect(flow._increaseWindow.bind(flow, 1)).to.throw(util.uncaughtErrorEventMessage);

});
});
Expand Down
Loading