Created
March 23, 2014 17:37
-
-
Save miensol/9726643 to your computer and use it in GitHub Desktop.
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
var net = require('net'), | |
http = require('http'), | |
Writable = require('stream').Writable, | |
parsers = http.parsers, | |
HTTPParser = process.binding('http_parser').HTTPParser, | |
util = require('util'), | |
EventEmitter = require('events').EventEmitter; | |
function freeParser(parser, req) { | |
if (parser) { | |
parser._headers = []; | |
parser.onIncoming = null; | |
if (parser.socket) { | |
parser.socket.onend = null; | |
parser.socket.ondata = null; | |
parser.socket.parser = null; | |
} | |
parser.socket = null; | |
parser.incoming = null; | |
parsers.free(parser); | |
parser = null; | |
} | |
if (req) { | |
req.parser = null; | |
} | |
} | |
var HttpParsingStream = function (options) { | |
Writable.call(this, {}); | |
var socket = options.socket; | |
var parser = parsers.alloc(); | |
var streamChunks = []; | |
var that = this; | |
parser.reinitialize(options.parserMode); | |
parser.socket = socket; | |
socket.parser = parser; | |
parser.onIncoming = function (request) { | |
that.emit('headers', request); | |
request.on('data', function () { | |
//we either have to call resume or attach on data handler to get end event... | |
// console.log(options.name + '.data', arguments); | |
}); | |
request.on('end', function () { | |
that.emit('end'); | |
freeParser(parser, request); | |
}); | |
}; | |
socket.on('close', function () { | |
that.emit('socket.close'); | |
}); | |
this._write = function (chunk, encoding, callback) { | |
streamChunks.push({ | |
chunk: chunk, | |
encoding: encoding | |
}); | |
parser.execute(chunk, 0, chunk.length); | |
callback && callback(); | |
}; | |
this.writeCurrentChunks = function (writableStream) { | |
streamChunks.forEach(function (chunkObj) { | |
console.log(chunkObj.chunk.toString('ascii')); | |
writableStream.write(chunkObj.chunk, chunkObj.encoding); | |
}); | |
}; | |
}; | |
HttpParsingStream.createForRequest = function (socket) { | |
return new HttpParsingStream({ | |
socket: socket, | |
parserMode: HTTPParser.REQUEST, | |
name: 'request' | |
}); | |
}; | |
HttpParsingStream.createForResponse = function (socket) { | |
return new HttpParsingStream({ | |
socket: socket, | |
parserMode: HTTPParser.RESPONSE, | |
name: 'response' | |
}); | |
}; | |
util.inherits(HttpParsingStream, Writable); | |
net.createServer(function (socketRequest) { | |
var requestParser = HttpParsingStream.createForRequest(socketRequest); | |
requestParser.on('headers', function (req) { | |
console.log('request.headers'); | |
//pause the request until we setup necessary plumbing | |
req.pause(); | |
var hostNameHeader = req.headers.host, | |
hostAndPort = hostNameHeader.split(':'), | |
host = hostAndPort[0], | |
port = parseInt(hostAndPort[1]) || 80; | |
var srvSocket = net.connect(port, host, function () { | |
var responseParser = HttpParsingStream.createForResponse(srvSocket); | |
responseParser.on('headers', function () { | |
console.log('response.headers'); | |
}); | |
responseParser.on('end', function () { | |
console.log('response.end'); | |
}); | |
srvSocket.pipe(responseParser); | |
srvSocket.pipe(socketRequest); | |
requestParser.writeCurrentChunks(srvSocket); | |
socketRequest.pipe(srvSocket); | |
req.resume(); | |
}); | |
}); | |
requestParser.on('end', function () { | |
console.log('request.end'); | |
}); | |
socketRequest.pipe(requestParser); | |
}).listen(9000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I've tested your code but it shows error below on line 31
TypeError: Cannot read property 'alloc' of undefined
Would you please let me know how to fix it?