diff --git a/lib/spdy-transport/connection.js b/lib/spdy-transport/connection.js index e3f7db7..7873904 100644 --- a/lib/spdy-transport/connection.js +++ b/lib/spdy-transport/connection.js @@ -240,7 +240,10 @@ Connection.prototype._onVersion = function _onVersion (version) { }) // Update session window - if (state.version >= 3.1 || (state.isServer && state.autoSpdy31)) { this._onSessionWindowDrain() } + if (state.version >= 3.1 || + (state.isServer && state.autoSpdy31 && state.version >= 3.1)) { + this._onSessionWindowDrain() + } this.emit('version', version) } @@ -469,7 +472,8 @@ Connection.prototype._handleHeaders = function _handleHeaders (frame) { Connection.prototype._onSessionWindowDrain = function _onSessionWindowDrain () { var state = this._spdyState - if (state.version < 3.1 && !(state.isServer && state.autoSpdy31)) { + if (state.version < 3.1 && + !(state.isServer && state.autoSpdy31 && state.version >= 3.1)) { return } diff --git a/lib/spdy-transport/protocol/spdy/zlib-pool.js b/lib/spdy-transport/protocol/spdy/zlib-pool.js index 53c210a..5ac376c 100644 --- a/lib/spdy-transport/protocol/spdy/zlib-pool.js +++ b/lib/spdy-transport/protocol/spdy/zlib-pool.js @@ -24,7 +24,8 @@ function createDeflate (version, compression) { function createInflate (version) { var inflate = zlib.createInflate({ dictionary: transport.protocol.spdy.dictionary[version], - flush: zlib.Z_SYNC_FLUSH + flush: zlib.Z_SYNC_FLUSH, + windowBits: 15 }) // For node.js v0.8 diff --git a/lib/spdy-transport/stream.js b/lib/spdy-transport/stream.js index f22ea5e..4397b85 100644 --- a/lib/spdy-transport/stream.js +++ b/lib/spdy-transport/stream.js @@ -25,6 +25,8 @@ function Stream (connection, options) { this.path = options.path this.host = options.host this.headers = options.headers || {} + this.headersSent = false + this.trailers = null this.connection = connection this.parent = options.parent || null @@ -354,13 +356,20 @@ Stream.prototype._onFinish = function _onFinish () { }) return } - - state.framer.dataFrame({ - id: this.id, - priority: state.priority.getPriority(), - fin: true, - data: new Buffer(0) - }) + if (this.trailers) { + state.framer.headersFrame({ + id: this.id, + headers: this.trailers, + fin: true + }) + } else { + state.framer.dataFrame({ + id: this.id, + priority: state.priority.getPriority(), + fin: true, + data: Buffer.alloc(0) + }) + } } this._maybeClose() @@ -510,6 +519,8 @@ Stream.prototype.send = function send (callback) { this._writableState.finished = true } + this.headersSent = true + // TODO(indunty): ideally it should just take a stream object as an input var self = this this._hardCork() @@ -546,6 +557,9 @@ Stream.prototype.respond = function respond (status, headers, callback) { status: status, headers: headers } + + this.headersSent = true + this._hardCork() state.framer.responseFrame(frame, function (err) { self._hardUncork() @@ -597,14 +611,19 @@ Stream.prototype.sendHeaders = function sendHeaders (headers, callback) { return } - this._hardCork() - state.framer.headersFrame({ - id: this.id, - headers: headers - }, function (err) { - self._hardUncork() - if (callback) { callback(err) } - }) + if (state.protocol.name !== 'h2' || this.headersSent === false) { + this.headersSent = true + this._hardCork() + state.framer.headersFrame({ + id: this.id, + headers: headers + }, function (err) { + self._hardUncork() + if (callback) { callback(err) } + }) + } else { + this.trailers = headers + } } Stream.prototype.destroy = function destroy () { diff --git a/test/both/transport/stream-test.js b/test/both/transport/stream-test.js index 7b608fd..456dfa3 100644 --- a/test/both/transport/stream-test.js +++ b/test/both/transport/stream-test.js @@ -122,7 +122,6 @@ describe('Transport/Stream', function () { stream.sendHeaders({ a: 'b' }) stream.end() }) - server.on('stream', function (stream) { var gotHeaders = false stream.on('headers', function (headers) { @@ -350,6 +349,7 @@ describe('Transport/Stream', function () { }) it('should emit trailing headers', function (done) { + var dataReceived = false client.request({ method: 'POST', path: '/hello-split' @@ -364,11 +364,25 @@ describe('Transport/Stream', function () { }) }) + if (name === 'h2') { + server.on('frame', function (frame) { + if (frame.type === 'HEADERS' && dataReceived) { + assert.ok(frame.fin) + } + }) + } + server.on('stream', function (stream) { stream.respond(200, {}) stream.resume() + stream.on('data', function (data) { + dataReceived = true + }) stream.on('headers', function (headers) { + if (name === 'h2') { + assert.ok(dataReceived) + } assert.equal(headers.trailer, 'yes') done() })