michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: var spdy = require('../node-spdy/lib/spdy.js'); michael@0: var fs = require('fs'); michael@0: var url = require('url'); michael@0: var crypto = require('crypto'); michael@0: michael@0: function getHttpContent(path) { michael@0: var content = '' + michael@0: '' + michael@0: 'HOORAY!' + michael@0: 'You Win! (by requesting' + path + ')' + michael@0: ''; michael@0: return content; michael@0: } michael@0: michael@0: function getHugeContent(size) { michael@0: var content = ''; michael@0: michael@0: for (var i = 0; i < size; i++) { michael@0: content += '0'; michael@0: } michael@0: michael@0: return content; michael@0: } michael@0: michael@0: /* This takes care of responding to the multiplexed request for us */ michael@0: var Multiplex = function() {}; michael@0: michael@0: Multiplex.prototype = { michael@0: mp1res: null, michael@0: mp2res: null, michael@0: buf: null, michael@0: mp1start: 0, michael@0: mp2start: 0, michael@0: michael@0: checkReady: function() { michael@0: if (this.mp1res != null && this.mp2res != null) { michael@0: this.buf = getHugeContent(30*1024); michael@0: this.mp1start = 0; michael@0: this.mp2start = 0; michael@0: this.send(this.mp1res, 0); michael@0: setTimeout(function() { this.send(this.mp2res, 0); }.bind(this), 5); michael@0: } michael@0: }, michael@0: michael@0: send: function(res, start) { michael@0: var end = start + 1024; michael@0: if (end > this.buf.length) michael@0: end = this.buf.length; michael@0: var content = this.buf.substring(start, end); michael@0: if (end < this.buf.length) { michael@0: res.write(content); michael@0: setTimeout(function() { this.send(res, end); }.bind(this), 10); michael@0: } else { michael@0: res.end(content); michael@0: } michael@0: }, michael@0: }; michael@0: michael@0: var m = new Multiplex(); michael@0: michael@0: var post_hash = null; michael@0: function receivePostData(chunk) { michael@0: post_hash.update(chunk.toString()); michael@0: } michael@0: michael@0: function finishPost(res, content) { michael@0: var md5 = post_hash.digest('hex'); michael@0: res.setHeader('X-Calculated-MD5', md5); michael@0: res.writeHead(200); michael@0: res.end(content); michael@0: } michael@0: michael@0: function handleRequest(req, res) { michael@0: var u = url.parse(req.url); michael@0: var content = getHttpContent(u.pathname); michael@0: michael@0: if (req.streamID) { michael@0: res.setHeader('X-Connection-Spdy', 'yes'); michael@0: res.setHeader('X-Spdy-StreamId', '' + req.streamID); michael@0: } else { michael@0: res.setHeader('X-Connection-Spdy', 'no'); michael@0: } michael@0: michael@0: if (u.pathname == '/exit') { michael@0: res.setHeader('Content-Type', 'text/plain'); michael@0: res.writeHead(200); michael@0: res.end('ok'); michael@0: process.exit(); michael@0: } else if (u.pathname == '/multiplex1' && req.streamID) { michael@0: res.setHeader('Content-Type', 'text/plain'); michael@0: res.writeHead(200); michael@0: m.mp1res = res; michael@0: m.checkReady(); michael@0: return; michael@0: } else if (u.pathname == '/multiplex2' && req.streamID) { michael@0: res.setHeader('Content-Type', 'text/plain'); michael@0: res.writeHead(200); michael@0: m.mp2res = res; michael@0: m.checkReady(); michael@0: return; michael@0: } else if (u.pathname == "/header") { michael@0: m = new Multiplex(); michael@0: var val = req.headers["x-test-header"]; michael@0: if (val) { michael@0: res.setHeader("X-Received-Test-Header", val); michael@0: } michael@0: } else if (u.pathname == "/push") { michael@0: res.push('/push.js', michael@0: { 'content-type': 'application/javascript', michael@0: 'pushed' : 'yes', michael@0: 'content-length' : 11, michael@0: 'X-Connection-Spdy': 'yes'}, michael@0: function(err, stream) { michael@0: if (err) return; michael@0: stream.end('// comments'); michael@0: }); michael@0: content = '