diff --git a/libs/substitute.js b/libs/substitute.js new file mode 100644 index 0000000000000000000000000000000000000000..ab04aeec1e4f2ff6a1bb9912b044435cb9583dd2 --- /dev/null +++ b/libs/substitute.js @@ -0,0 +1,71 @@ +// return a function that is substitution middleware, capable +// of being installed to perform textual replacement on +// all server output +exports.substitute = function(subs) { + // given a buffer, find and replace all subs + function subHostNames(data) { + for (var i in subs) { + data = data.toString().replace(new RegExp(i, 'g'), subs[i]); + } + + return data; + } + + return function(req, resp, next) { + // cache the *real* functions + var realWrite = resp.write; + var realEnd = resp.end; + var realWriteHead = resp.writeHead; + var realSend = resp.send; + + var buf = undefined; + var enc = undefined; + var contentType = undefined; + + resp.writeHead = function (sc, reason, hdrs) { + var h = undefined; + if (typeof hdrs === 'object') h = hdrs; + else if (typeof reason === 'object') h = reason; + for (var k in h) { + if (k.toLowerCase() === 'content-type') { + contentType = h[k]; + break; + } + } + if (!contentType) contentType = resp.getHeader('content-type'); + if (!contentType) contentType = "application/unknown"; + realWriteHead.call(resp, sc, reason, hdrs); + }; + + resp.write = function (chunk, encoding) { + if (buf) buf += chunk; + else buf = chunk; + enc = encoding; + }; + + resp.send = function(stuff) { + buf = stuff; + realSend.call(resp,stuff); + }; + + resp.end = function() { + if (!contentType) contentType = resp.getHeader('content-type'); + if (contentType && (contentType === "application/javascript" || + contentType.substr(0,4) === 'text')) + { + if (buf) { + if (Buffer.isBuffer(buf)) buf = buf.toString('utf8'); + var l = Buffer.byteLength(buf); + buf = subHostNames(buf); + if (l != Buffer.byteLength(buf)) resp.setHeader('Content-Length', Buffer.byteLength(buf)); + } + } + if (buf && buf.length) { + realWrite.call(resp, buf, enc); + } + realEnd.call(resp); + } + + next(); + }; +}; diff --git a/run.js b/run.js index 5b5d870a7dee93a5c59862b2f81fa080b028a0f7..7f76544512b29d045dbf6f5e3b1ea42af2d37d06 100755 --- a/run.js +++ b/run.js @@ -2,12 +2,13 @@ // a little node webserver designed to run the unit tests herein -var sys = require("sys"), - http = require("http"), - url = require("url"), - path = require("path"), - fs = require("fs"), - express = require("express"); +var sys = require("sys"), + http = require("http"), + url = require("url"), + path = require("path"), + fs = require("fs"), + express = require("express"), +substitution = require('./libs/substitute.js'); var PRIMARY_HOST = "127.0.0.1"; @@ -18,103 +19,45 @@ var boundServers = [ ]; // var nodemailer = require('nodemailer'); nodemailer.EmailMessage.prototype.send = function(callback) { - this.prepareVariables(); - var headers = this.generateHeaders(), - body = this.generateBody(); - console.log(headers); - console.log(body); + this.prepareVariables(); + var headers = this.generateHeaders(), + body = this.generateBody(); + console.log(headers); + console.log(body); }; -// given a buffer, find and replace all production hostnames -// with development URLs -function subHostNames(data) { - for (var i = 0; i < boundServers.length; i++) { - var o = boundServers[i] - var a = o.server.address(); - var from = o.name; - var to = "http://" + a.address + ":" + a.port; - data = data.toString().replace(new RegExp(from, 'g'), to); - - // now do another replacement to catch bare hostnames sans http(s) - // and explicit cases where port is appended - var fromWithPort; - if (from.substr(0,5) === 'https') { +var subs = undefined; +function substitutionMiddleware(req, resp, next) { + if (!subs) { + subs = { }; + for (var i = 0; i < boundServers.length; i++) { + var o = boundServers[i] + var a = o.server.address(); + var from = o.name; + var to = "http://" + a.address + ":" + a.port; + subs[from] = to; + + // now do another replacement to catch bare hostnames sans http(s) + // and explicit cases where port is appended + var fromWithPort; + if (from.substr(0,5) === 'https') { from = from.substr(8); fromWithPort = from + ":443"; - } else { + } else { from = from.substr(7); fromWithPort = from + ":80"; + } + to = to.substr(7); + + if (o.subPath) to += o.subPath; + + subs[fromWithPort] = to; + subs[from] = to; } - to = to.substr(7); - - if (o.subPath) to += o.subPath; - - data = data.replace(new RegExp(fromWithPort, 'g'), to); - data = data.replace(new RegExp(from, 'g'), to); } - - return data; + (substitution.substitute(subs))(req, resp, next); } -// Middleware that intercepts outbound textual responses and substitutes -// in development hostnames -function substitutionMiddleware(req, resp, next) { - // cache the *real* functions - var realWrite = resp.write; - var realEnd = resp.end; - var realWriteHead = resp.writeHead; - var realSend = resp.send; - - var buf = undefined; - var enc = undefined; - var contentType = undefined; - - resp.writeHead = function (sc, reason, hdrs) { - var h = undefined; - if (typeof hdrs === 'object') h = hdrs; - else if (typeof reason === 'object') h = reason; - for (var k in h) { - if (k.toLowerCase() === 'content-type') { - contentType = h[k]; - break; - } - } - if (!contentType) contentType = resp.getHeader('content-type'); - if (!contentType) contentType = "application/unknown"; - realWriteHead.call(resp, sc, reason, hdrs); - }; - - resp.write = function (chunk, encoding) { - if (buf) buf += chunk; - else buf = chunk; - enc = encoding; - }; - - resp.send = function(stuff) { - buf = stuff; - realSend.call(resp,stuff); - }; - - resp.end = function() { - if (!contentType) contentType = resp.getHeader('content-type'); - if (contentType && (contentType === "application/javascript" || - contentType.substr(0,4) === 'text')) - { - if (buf) { - if (Buffer.isBuffer(buf)) buf = buf.toString('utf8'); - var l = Buffer.byteLength(buf); - buf = subHostNames(buf); - if (l != Buffer.byteLength(buf)) resp.setHeader('Content-Length', Buffer.byteLength(buf)); - } - } - if (buf && buf.length) { - realWrite.call(resp, buf, enc); - } - realEnd.call(resp); - } - - next(); -}; function createServer(obj) { var app = express.createServer();