Skip to content

Instantly share code, notes, and snippets.

@kilianc
Last active October 3, 2015 07:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kilianc/2417848 to your computer and use it in GitHub Desktop.
Save kilianc/2417848 to your computer and use it in GitHub Desktop.
Make you request object able to buffer flying packet after pause() call
require('http').IncomingMessage.prototype.makeBuffered = function () {
var self = this
var unluckyChunks = []
var isPaused = false
var isEnded = false
var originalResume = self.resume
var originalPause = self.pause
var originalEmit = self.emit
var currentEmit = originalEmit
function patchedEmit(eventName, chunk) {
if (eventName === 'data') {
unluckyChunks.push(chunk)
} else if (eventName === 'end') {
isEnded = true
} else {
originalEmit.apply(self, arguments)
}
}
self.resume = function () {
if (!isPaused) return
isPaused = false
currentEmit = originalEmit
if (unluckyChunks.length) {
unluckyChunks.forEach(function (chunk) {
request.emit('data', chunk)
})
}
if (isEnded) {
request.emit('end')
}
originalResume.apply(this, arguments)
}
self.pause = function () {
if (isPaused) return
isPaused = true
unluckyChunks = []
currentEmit = patchedEmit
originalPause.apply(this, arguments)
}
self.emit = function () {
currentEmit.apply(this, arguments)
}
}
var fs = require('fs'),
http = require('http'),
httpreq = require('request'),
crypto = require('crypto')
var shasum1 = crypto.createHash('sha1')
var shasum2 = crypto.createHash('sha1')
var shasum3 = crypto.createHash('sha1')
var zipfile = fs.createWriteStream('node.zip')
http.createServer(function (request, response) {
patchRequest(request)
request.pipe(zipfile)
request.pause()
process.nextTick(function () {
request.on('data', function (chunk) {
shasum3.update(chunk)
})
})
request.on('data', function (chunk) {
shasum2.update(chunk)
console.log('.')
})
request.on('end', function () {
console.log('LOCAL END')
clearInterval(pauseInt)
clearInterval(resumeInt)
response.writeHead(200)
response.end(';')
console.log(shasum1.digest('hex'))
console.log(shasum2.digest('hex'))
console.log(shasum3.digest('hex'))
process.exit()
})
var pauseInt = setInterval(function () { request.pause() }, 5000 * Math.random() + 3000);
var resumeInt = setInterval(function () { request.resume() }, 1000 * Math.random() + 200);
}).listen(8080);
setTimeout(function () {
httpreq.get('https://nodeload.github.com/joyent/node/zipball/master').on('data', function (chunk) {
shasum1.update(chunk)
}).on('end', function (chunk) {
console.log('END FROM REMOTE')
}).pipe(
http.request({ host: 'localhost', port: '8080', method: 'POST' })
)
}, 500)
// patch
function patchRequest (request) {
var unluckyChunks = []
var isPaused = false
var isEnded = false
var originalResume = request.resume
var originalPause = request.pause
var originalEmit = request.emit
var currentEmit = originalEmit
function patchedEmit(eventName, chunk) {
if (eventName === 'data') {
unluckyChunks.push(chunk)
} else if (eventName === 'end') {
isEnded = true
} else {
originalEmit.apply(request, arguments)
}
}
request.resume = function () {
if (!isPaused) return
isPaused = false
currentEmit = originalEmit
if (unluckyChunks.length) {
unluckyChunks.forEach(function (chunk) {
request.emit('data', chunk)
})
}
if (isEnded) {
request.emit('end')
}
originalResume.apply(this, arguments)
}
request.pause = function () {
if (isPaused) return
isPaused = true
unluckyChunks = []
currentEmit = patchedEmit
originalPause.apply(this, arguments)
}
request.emit = function () {
currentEmit.apply(this, arguments)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment