-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d9daadf
commit f0fe7bf
Showing
4 changed files
with
823 additions
and
649 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,115 +1,121 @@ | ||
var Readable = require('stream').Readable | ||
var Readable = require("stream").Readable; | ||
|
||
module.exports = function hijackResponse (res, cb) { | ||
var writeHead = res.writeHead | ||
var write = res.write | ||
var end = res.end | ||
var originalResponse = res | ||
var hijacking = true | ||
var hijackedResponse = new Readable() | ||
hijackedResponse.__proto__ = originalResponse // eslint-disable-line no-proto | ||
hijackedResponse.emit = hijackedResponse.emit | ||
module.exports = function hijackResponse(res, cb) { | ||
var writeHead = res.writeHead; | ||
var write = res.write; | ||
var end = res.end; | ||
var originalResponse = res; | ||
var hijacking = true; | ||
var hijackedResponse = new Readable(); | ||
hijackedResponse.__proto__ = originalResponse; // eslint-disable-line no-proto | ||
hijackedResponse.emit = hijackedResponse.emit; | ||
|
||
var readableMethods = Object.keys(Readable.prototype) | ||
readableMethods.forEach(function (method) { | ||
hijackedResponse[method] = Readable.prototype[method].bind(hijackedResponse) | ||
}) | ||
var readableMethods = Object.keys(Readable.prototype); | ||
readableMethods.forEach(function(method) { | ||
hijackedResponse[method] = Readable.prototype[method].bind( | ||
hijackedResponse | ||
); | ||
}); | ||
|
||
hijackedResponse._read = function () {} | ||
hijackedResponse._read = function() {}; | ||
|
||
res.write = function (rawChunk, encoding) { | ||
if (!res.headersSent && res.writeHead !== writeHead) res._implicitHeader() | ||
res.write = function(rawChunk, encoding) { | ||
if (!res.headersSent && res.writeHead !== writeHead) res._implicitHeader(); | ||
if (hijacking) { | ||
var chunk = rawChunk | ||
if (rawChunk !== null && !Buffer.isBuffer(chunk) && encoding !== 'buffer') { | ||
var chunk = rawChunk; | ||
if ( | ||
rawChunk !== null && | ||
!Buffer.isBuffer(chunk) && | ||
encoding !== "buffer" | ||
) { | ||
if (!encoding) { | ||
chunk = new Buffer(rawChunk) | ||
chunk = new Buffer(rawChunk); | ||
} else { | ||
chunk = new Buffer(rawChunk, encoding) | ||
chunk = new Buffer(rawChunk, encoding); | ||
} | ||
} | ||
hijackedResponse.push(chunk) | ||
hijackedResponse.push(chunk); | ||
} else { | ||
write.call(originalResponse, rawChunk, encoding) | ||
write.call(originalResponse, rawChunk, encoding); | ||
} | ||
} | ||
}; | ||
|
||
res.end = function (chunk, encoding) { | ||
res.end = function(chunk, encoding) { | ||
if (chunk) { | ||
res.write(chunk, encoding) | ||
res.write(chunk, encoding); | ||
} else if (!res.headersSent && res.writeHead !== writeHead) { | ||
res._implicitHeader() | ||
res._implicitHeader(); | ||
} | ||
if (hijacking) { | ||
hijackedResponse.push(null) | ||
hijackedResponse.push(null); | ||
} else { | ||
end.call(originalResponse) | ||
end.call(originalResponse); | ||
} | ||
} | ||
}; | ||
|
||
var resEmit = res.emit | ||
res.emit = function (eventName) { | ||
if (eventName === 'close') { | ||
hijackedResponse.emit('close') | ||
var resEmit = res.emit; | ||
res.emit = function(eventName) { | ||
if (eventName === "close") { | ||
hijackedResponse.emit("close"); | ||
} | ||
|
||
return resEmit.apply(this, arguments) | ||
} | ||
return resEmit.apply(this, arguments); | ||
}; | ||
|
||
hijackedResponse.destroyHijacked = function () { | ||
res.write = res.end = function () {} | ||
hijackedResponse._readableState.buffer = [] | ||
return resEmit.call(res, 'close') | ||
} | ||
hijackedResponse.destroyHijacked = function() { | ||
res.write = res.end = function() {}; | ||
hijackedResponse._readableState.buffer = []; | ||
return resEmit.call(res, "close"); | ||
}; | ||
|
||
hijackedResponse.write = function (chunk, encoding) { | ||
write.call(originalResponse, chunk, encoding) | ||
} | ||
hijackedResponse.write = function(chunk, encoding) { | ||
write.call(originalResponse, chunk, encoding); | ||
}; | ||
|
||
hijackedResponse.end = function (chunk, encoding) { | ||
hijackedResponse.end = function(chunk, encoding) { | ||
if (chunk) { | ||
write.call(originalResponse, chunk, encoding) | ||
write.call(originalResponse, chunk, encoding); | ||
} | ||
if (hijacking) { | ||
end.call(originalResponse) | ||
end.call(originalResponse); | ||
} else { | ||
// If unhijacked, delay end-event so pipes don't close too early giving | ||
// you a chance to have error handlers work. | ||
setImmediate(function () { | ||
end.call(originalResponse) | ||
}) | ||
setImmediate(function() { | ||
end.call(originalResponse); | ||
}); | ||
} | ||
} | ||
}; | ||
|
||
hijackedResponse.__defineGetter__('statusCode', function () { | ||
return originalResponse.statusCode | ||
}) | ||
hijackedResponse.__defineGetter__("statusCode", function() { | ||
return originalResponse.statusCode; | ||
}); | ||
|
||
hijackedResponse.__defineSetter__('statusCode', function (statusCode) { | ||
originalResponse.statusCode = statusCode | ||
}) | ||
hijackedResponse.__defineSetter__("statusCode", function(statusCode) { | ||
originalResponse.statusCode = statusCode; | ||
}); | ||
|
||
res.writeHead = function (statusCode, statusMessage, headers) { | ||
if (typeof headers === 'undefined' && typeof statusMessage === 'object') { | ||
headers = statusMessage | ||
statusMessage = undefined | ||
res.writeHead = function(statusCode, statusMessage, headers) { | ||
if (typeof headers === "undefined" && typeof statusMessage === "object") { | ||
headers = statusMessage; | ||
statusMessage = undefined; | ||
} | ||
if (statusCode) { | ||
res.statusCode = statusCode | ||
res.statusCode = statusCode; | ||
} | ||
if (headers) { | ||
for (var headerName in headers) { | ||
res.setHeader(headerName, headers[headerName]) | ||
res.setHeader(headerName, headers[headerName]); | ||
} | ||
} | ||
res.writeHead = writeHead | ||
cb(null, hijackedResponse) | ||
} | ||
res.writeHead = writeHead; | ||
cb(null, hijackedResponse); | ||
}; | ||
|
||
hijackedResponse.unhijack = function () { | ||
hijacking = false | ||
res.write = write | ||
res.end = end | ||
return originalResponse | ||
} | ||
} | ||
hijackedResponse.unhijack = function() { | ||
hijacking = false; | ||
res.write = write; | ||
res.end = end; | ||
return originalResponse; | ||
}; | ||
}; |
Oops, something went wrong.