/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // This module is the stateful server side of test_http2.js and is meant // to have node be restarted in between each invocation var http2 = require('../node-http2'); var fs = require('fs'); var url = require('url'); var crypto = require('crypto'); // Hook into the decompression code to log the decompressed name-value pairs var http2_compression = require('../node-http2/lib/protocol/compressor'); var HeaderSetDecompressor = http2_compression.HeaderSetDecompressor; var originalRead = HeaderSetDecompressor.prototype.read; var lastDecompressor; var decompressedPairs; HeaderSetDecompressor.prototype.read = function() { if (this != lastDecompressor) { lastDecompressor = this; decompressedPairs = []; } var pair = originalRead.apply(this, arguments); if (pair) { decompressedPairs.push(pair); } return pair; } var http2_connection = require('../node-http2/lib/protocol/connection'); var Connection = http2_connection.Connection; var originalClose = Connection.prototype.close; Connection.prototype.close = function (error, lastId) { if (lastId !== undefined) { this._lastIncomingStream = lastId; } originalClose.apply(this, arguments); } function getHttpContent(path) { var content = '' + '' + 'HOORAY!' + 'You Win! (by requesting' + path + ')' + ''; return content; } function generateContent(size) { var content = ''; for (var i = 0; i < size; i++) { content += '0'; } return content; } /* This takes care of responding to the multiplexed request for us */ var m = { mp1res: null, mp2res: null, buf: null, mp1start: 0, mp2start: 0, checkReady: function() { if (this.mp1res != null && this.mp2res != null) { this.buf = generateContent(30*1024); this.mp1start = 0; this.mp2start = 0; this.send(this.mp1res, 0); setTimeout(this.send.bind(this, this.mp2res, 0), 5); } }, send: function(res, start) { var end = Math.min(start + 1024, this.buf.length); var content = this.buf.substring(start, end); res.write(content); if (end < this.buf.length) { setTimeout(this.send.bind(this, res, end), 10); } else { res.end(); } } }; var runlater = function() {}; runlater.prototype = { req : null, resp : null, onTimeout : function onTimeout() { this.resp.writeHead(200); this.resp.end("It's all good 750ms."); } }; function executeRunLater(arg) { arg.onTimeout(); } var h11required_conn = null; var h11required_header = "yes"; var didRst = false; var rstConnection = null; function handleRequest(req, res) { var u = url.parse(req.url); var content = getHttpContent(u.pathname); var push, push1, push1a, push2, push3; if (req.httpVersionMajor === 2) { res.setHeader('X-Connection-Http2', 'yes'); res.setHeader('X-Http2-StreamId', '' + req.stream.id); } else { res.setHeader('X-Connection-Http2', 'no'); } if (u.pathname === '/exit') { res.setHeader('Content-Type', 'text/plain'); res.setHeader('Connection', 'close'); res.writeHead(200); res.end('ok'); process.exit(); } if (u.pathname === '/750ms') { var rl = new runlater(); rl.req = req; rl.resp = res; setTimeout(executeRunLater, 750, rl); return; } else if ((u.pathname === '/multiplex1') && (req.httpVersionMajor === 2)) { res.setHeader('Content-Type', 'text/plain'); res.writeHead(200); m.mp1res = res; m.checkReady(); return; } else if ((u.pathname === '/multiplex2') && (req.httpVersionMajor === 2)) { res.setHeader('Content-Type', 'text/plain'); res.writeHead(200); m.mp2res = res; m.checkReady(); return; } else if (u.pathname === "/header") { var val = req.headers["x-test-header"]; if (val) { res.setHeader("X-Received-Test-Header", val); } } else if (u.pathname === "/doubleheader") { res.setHeader('Content-Type', 'text/html'); res.writeHead(200); res.write(content); res.writeHead(200); res.end(); return; } else if (u.pathname === "/cookie_crumbling") { res.setHeader("X-Received-Header-Pairs", JSON.stringify(decompressedPairs)); } else if (u.pathname === "/push") { push = res.push('/push.js'); push.writeHead(200, { 'content-type': 'application/javascript', 'pushed' : 'yes', 'content-length' : 11, 'X-Connection-Http2': 'yes' }); push.end('// comments'); content = '