spdy-transport
Advanced tools
Comparing version 1.0.0-rc8 to 1.0.0-rc9
@@ -386,2 +386,8 @@ 'use strict'; | ||
// Someone is using our ids! | ||
if ((frame.id + state.stream.nextId) % 2 === 0) { | ||
state.framer.rstFrame({ id: frame.id, code: 'PROTOCOL_ERROR' }); | ||
return; | ||
} | ||
var stream = this._createStream({ | ||
@@ -733,3 +739,3 @@ id: frame.id, | ||
stream._sendPush(uri.status, function(err) { | ||
stream._sendPush(uri.status, uri.response, function(err) { | ||
if (!callback) { | ||
@@ -736,0 +742,0 @@ if (err) |
@@ -201,3 +201,3 @@ 'use strict'; | ||
} else if (kind === 'response') { | ||
pairs.push({ name: ':status', value: frame.status + '' }); | ||
pairs.push({ name: ':status', value: (frame.status || 200) + '' }); | ||
} | ||
@@ -263,19 +263,24 @@ | ||
var pairs = []; | ||
var pairs = { | ||
promise: [], | ||
response: [] | ||
}; | ||
pairs.push({ name: ':status', value: frame.status + '' }); | ||
this._defaultHeaders(frame, pairs); | ||
this._defaultHeaders(frame, pairs.promise); | ||
pairs.response.push({ name: ':status', value: (frame.status || 200) + '' }); | ||
this._compressHeaders(frame.headers, pairs, function(err, chunks) { | ||
if (err) { | ||
if (callback) | ||
return callback(err); | ||
else | ||
return self.emit('error', err); | ||
} | ||
function compress(headers, pairs, callback) { | ||
self._compressHeaders(headers, pairs, function(err, chunks) { | ||
if (err) { | ||
if (callback) | ||
return callback(err); | ||
else | ||
return self.emit('error', err); | ||
} | ||
// Send separate PRIORITY frame if needed | ||
var priority = frame.priority; | ||
var isDefaultPriority = self._isDefaultPriority(priority); | ||
callback(chunks); | ||
}); | ||
} | ||
function sendPromise(chunks) { | ||
self._continuationFrame({ | ||
@@ -288,13 +293,35 @@ id: frame.id, | ||
buf.writeUInt32BE(frame.promisedId); | ||
}, isDefaultPriority ? callback : null); | ||
}); | ||
} | ||
if (isDefaultPriority) | ||
return; | ||
function sendResponse(chunks, callback) { | ||
var priority = frame.priority; | ||
var isDefaultPriority = self._isDefaultPriority(priority); | ||
var flags = isDefaultPriority ? 0 : constants.flags.PRIORITY; | ||
// NOTE: these frames are written synchronously, so callback order is | ||
// correct | ||
self.priorityFrame({ | ||
// Mostly for testing | ||
if (frame.fin) | ||
flags |= constants.flags.END_STREAM; | ||
self._continuationFrame({ | ||
id: frame.promisedId, | ||
priority: priority | ||
type: 'HEADERS', | ||
flags: flags, | ||
reserve: isDefaultPriority ? 0 : 5, | ||
chunks: chunks | ||
}, function(buf) { | ||
if (isDefaultPriority) | ||
return; | ||
buf.writeUInt32BE((priority.exclusive ? 0x80000000 : 0) | | ||
priority.parent); | ||
buf.writeUInt8((priority.weight | 0) - 1); | ||
}, callback); | ||
} | ||
compress(frame.headers, pairs.promise, function(promiseChunks) { | ||
compress(frame.response, pairs.response, function(responseChunks) { | ||
sendPromise(promiseChunks); | ||
sendResponse(responseChunks, callback); | ||
}); | ||
}); | ||
@@ -301,0 +328,0 @@ }; |
@@ -288,3 +288,3 @@ 'use strict'; | ||
method: frame.method, | ||
status: frame.status, | ||
status: frame.status || 200, | ||
version: frame.version, | ||
@@ -295,3 +295,5 @@ scheme: frame.scheme, | ||
priority: frame.priority, | ||
headers: frame.headers | ||
// Merge everything together, there is no difference in SPDY protocol | ||
headers: util._extend(util._extend({}, frame.headers), frame.response) | ||
}, callback); | ||
@@ -298,0 +300,0 @@ }; |
@@ -146,2 +146,15 @@ 'use strict'; | ||
Parser.prototype._filterHeader = function _filterHeader(headers, name) { | ||
var res = {}; | ||
var keys = Object.keys(headers); | ||
for (var i = 0; i < keys.length; i++) { | ||
var key = keys[i]; | ||
if (key !== name) | ||
res[key] = headers[key]; | ||
} | ||
return res; | ||
}; | ||
Parser.prototype.onSynHeadFrame = function onSynHeadFrame(type, | ||
@@ -202,16 +215,28 @@ flags, | ||
}); | ||
} else { | ||
callback(null, [ { | ||
type: 'PUSH_PROMISE', | ||
id: associated, | ||
promisedId: id, | ||
fin: fin, | ||
headers: headers, | ||
path: path | ||
}, { | ||
type: 'PRIORITY', | ||
id: id, | ||
priority: priorityInfo | ||
}]); | ||
return; | ||
} | ||
if (stream && !headers[':status']) | ||
return callback(new Error('Missing `:status` header')); | ||
var filteredHeaders = self._filterHeader(headers, ':status'); | ||
callback(null, [ { | ||
type: 'PUSH_PROMISE', | ||
id: associated, | ||
fin: false, | ||
promisedId: id, | ||
headers: filteredHeaders, | ||
path: path | ||
}, { | ||
type: 'HEADERS', | ||
id: id, | ||
fin: fin, | ||
priority: priorityInfo, | ||
writable: true, | ||
path: undefined, | ||
headers: { | ||
':status': headers[':status'] | ||
} | ||
}]); | ||
}); | ||
@@ -218,0 +243,0 @@ }; |
@@ -26,3 +26,3 @@ 'use strict'; | ||
this.host = options.host; | ||
this.headers = options.headers; | ||
this.headers = options.headers || {}; | ||
this.connection = connection; | ||
@@ -38,3 +38,3 @@ this.parent = options.parent || null; | ||
state.version = this.connection.version; | ||
state.version = this.connection.getVersion(); | ||
state.isServer = this.connection.isServer(); | ||
@@ -386,3 +386,3 @@ state.debug = state.isServer ? debug.server : debug.client; | ||
push: true, | ||
request: false, | ||
request: true, | ||
method: frame.headers[':method'], | ||
@@ -426,3 +426,3 @@ path: frame.headers[':path'], | ||
Stream.prototype._sendPush = function _sendPush(status, callback) { | ||
Stream.prototype._sendPush = function _sendPush(status, response, callback) { | ||
var self = this; | ||
@@ -440,3 +440,4 @@ var state = this._spdyState; | ||
status: status, | ||
headers: this.headers | ||
headers: this.headers, | ||
response: response | ||
}, function(err) { | ||
@@ -443,0 +444,0 @@ self._hardUncork(); |
{ | ||
"name": "spdy-transport", | ||
"version": "1.0.0-rc8", | ||
"version": "1.0.0-rc9", | ||
"description": "SPDY v2, v3, v3.1 and HTTP2 transport", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -429,3 +429,3 @@ var assert = require('assert'); | ||
expect({ | ||
expect([ { | ||
type: 'PUSH_PROMISE', | ||
@@ -441,7 +441,20 @@ id: 4, | ||
':method': 'GET', | ||
':status': '200', | ||
a: 'b' | ||
} | ||
}, done); | ||
}, { | ||
type: 'HEADERS', | ||
id: 41, | ||
priority: { | ||
exclusive: false, | ||
parent: 0, | ||
weight: 16 | ||
}, | ||
writable: true, | ||
path: undefined, | ||
fin: false, | ||
headers: { | ||
':status': '200' | ||
} | ||
} ], done); | ||
}); | ||
@@ -480,3 +493,2 @@ }); | ||
':method': 'GET', | ||
':status': '200', | ||
@@ -486,3 +498,3 @@ a: 'b' | ||
}, { | ||
type: 'PRIORITY', | ||
type: 'HEADERS', | ||
id: 41, | ||
@@ -493,2 +505,8 @@ priority: { | ||
weight: 1 | ||
}, | ||
writable: true, | ||
path: undefined, | ||
fin: false, | ||
headers: { | ||
':status': '200' | ||
} | ||
@@ -495,0 +513,0 @@ } ], done); |
@@ -308,3 +308,14 @@ var assert = require('assert'); | ||
}); | ||
it('should kill stream on wrong id', function(done) { | ||
client._spdyState.stream.nextId = 2; | ||
var stream = client.request({ | ||
path: '/hello' | ||
}); | ||
stream.once('error', function(err) { | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -30,3 +30,6 @@ var assert = require('assert'); | ||
assert.equal(push.path, '/push'); | ||
done(); | ||
push.on('response', function(status, headers) { | ||
assert.equal(status, 201); | ||
done(); | ||
}); | ||
}); | ||
@@ -41,2 +44,3 @@ }); | ||
path: '/push', | ||
status: 201, | ||
priority: { | ||
@@ -53,2 +57,35 @@ parent: 0, | ||
it('should send HEADERS on PUSH_PROMISE', function(done) { | ||
client.request({ | ||
path: '/parent' | ||
}, function(err, stream) { | ||
assert(!err); | ||
stream.on('pushPromise', function(push) { | ||
push.on('headers', function(headers) { | ||
assert.deepEqual(headers, { a: 'b' }); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
server.on('stream', function(stream) { | ||
assert.equal(stream.path, '/parent'); | ||
stream.respond(200, {}); | ||
stream.pushPromise({ | ||
path: '/push', | ||
priority: { | ||
parent: 0, | ||
exclusive: false, | ||
weight: 42 | ||
} | ||
}, function(err, stream) { | ||
assert(!err); | ||
stream.sendHeaders({ a: 'b' }); | ||
}); | ||
}); | ||
}); | ||
it('should create PUSH_PROMISE and end parent req', function(done) { | ||
@@ -261,6 +298,8 @@ client.request({ | ||
stream.on('pushPromise', function(push) { | ||
// .abort() does this only on next tick | ||
push.emit('close'); | ||
push.on('response', function() { | ||
// .abort() does this only on next tick | ||
push.emit('close'); | ||
stream.end('ok'); | ||
stream.end('ok'); | ||
}); | ||
}); | ||
@@ -267,0 +306,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
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
222695
6869