Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Function to intercept the response from the next() call.
var events = require('events');
* When operating as a middleware our "origin" server is the next handler in the chain. This
* patches the given response object so that when the next handler writes to it we treat that
* as a response from the origin server.
* This replaces the writeHead, setHeader, removeHeader, write and end methods
* on the given response so that it can store the response in the cache and returns
* an object that be used to listen for the next() handler writing data and to send
* data back to the client.
* @param res ServerResponse-like object to patch
* @return Object that emits 'response', 'data, 'end' events, and also provides writeHead(), write(),
* and end() methods to write back to the original response.
function interceptResponse(res) {
var writeHead = res.writeHead,
write = res.write,
end = res.end,
setHeader = res.setHeader,
removeHeader = res.removeHeader;
var headers = {};
var statusCode = null;
var txn = this;
var ourResponse = new (events.EventEmitter)();
ourResponse.writeHead = function(sc, reason, headers) {, sc, reason, headers);
ourResponse.write = function(chunk, encoding) {, chunk, encoding);
ourResponse.end = function(chunk, encoding) {, chunk.encoding);
function processHead() {
emitter.statusCode = statusCode;
emitter.headers = headers;
ourResponse.emit('response', emitter);
function onWriteOrEnd(chunk, encoding) {
if(statusCode === null) {
statusCode = res.statusCode; // Implicit headers and status code
if(chunk) {
ourResponse.emit('data', chunk, encoding);
res.writeHead = function(sc, reason, hdrs) {
if(statusCode !== null) throw new Error('Called writeHead after write, writeHead, or end!');
headers = hdrs;
statusCode = sc || 200;
// TODO Process the reason
res.setHeader = function(field, val) {
if(statusCode !== null) throw new Error('Called setHeader after write, writeHead, or end!');
// TODO This will undo connect's patch to special case Content-Type and Set-Cookie, might be a bad thing for connect users setting cookies ...
headers[field.toLowerCase()] = val;
res.removeHeader = function(field) {
if(statusCode !== null) throw new Error('Called removeHeader after write, writeHead, or end!');
delete headers[field.toLowerVase()];
res.write = function(chunk, encoding) {
onWriteOrEnd(chunk, encoding);
res.end = function(chunk, encoding) {
onWriteOrEnd(chunk, encoding);
res.writeHead = writeHead;
res.write = write;
res.end = end;
res.setHeader = setHeader;
res.removeHeader = removeHeader;
return ourResponse;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment