Last active
August 29, 2015 13:56
-
-
Save mdobson/9239634 to your computer and use it in GitHub Desktop.
Tunneling HTTP over WebSockets
This file contains hidden or 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 http = require('http'); | |
var WebSocketServer = require('ws').Server; | |
var webSocket = null; | |
var server = http.createServer(function(req, res) { | |
var requestLine = [req.method.toUpperCase(), req.url, 'HTTP/' + req.httpVersion + '\r\n'].join(' '); | |
Object.keys(req.headers).forEach(function(header) { | |
requestLine += header + ': ' + req.headers[header] + '\r\n'; | |
}); | |
var buf = ''; | |
if(webSocket) { | |
req.on('data', function(data) { | |
buf += data.toString(); | |
}); | |
req.on('end', function() { | |
if(buf.length) { | |
requestLine += '\r\n'; | |
requestLine += buf; | |
requestLine += '\r\n\r\n'; | |
} else { | |
requestLine += '\r\n\r\n'; | |
} | |
webSocket.send(requestLine); | |
}); | |
webSocket.once('message', function(data) { | |
var response = data.split('\r\n\r\n'); | |
var headersNShit = response.shift().split('\r\n'); | |
var body = response.join(); | |
var statusLine = headersNShit.shift(); | |
headersNShit.forEach(function(header) { | |
var headerPair = header.split(':'); | |
res.setHeader(headerPair[0], headerPair[1].trim()); | |
}); | |
statusLine = statusLine.split(' '); | |
res.statusCode = statusLine[1]; | |
res.end(body); | |
//req.socket.write(data); | |
}); | |
} | |
}); | |
var wss = new WebSocketServer({ server: server }); | |
wss.on('connection', function(ws) { | |
webSocket = ws; | |
}); | |
server.listen(3000); |
This file contains hidden or 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 WebSocket = require('ws'); | |
var FakeSocket = require('./fake_socket'); | |
var http = require('http'); | |
var argo = require('argo'); | |
var resource = require('argo-resource'); | |
var Hello = require('./hello_resource'); | |
var ws = new WebSocket('ws://localhost:3000'); | |
var app = argo() | |
.use(function(handle) { | |
handle('request', function(env, next) { | |
env.response.on('finish', function() { | |
ws.send(env.request.socket.data.toString()); | |
}); | |
//env.response.setHeader('Content-Length', env.request.url.length); | |
//env.response.body = env.request.url; | |
next(env); | |
}); | |
}) | |
.use(resource(Hello)) | |
.build(); | |
var server = http.createServer(app.run); | |
/* | |
var server = http.createServer(function(req, res) { | |
res.on('finish', function() { | |
ws.send(req.socket.data.toString()); | |
}); | |
res.setHeader('Content-Length', req.url.length); | |
res.end(req.url); | |
}); | |
*/ | |
ws.on('open', function() { | |
}); | |
ws.on('message', function(data) { | |
var fake = new FakeSocket(); | |
fake.write(data); | |
fake.on('readable', function() { | |
var data; | |
while (data = fake.read()) { | |
this.ondata(data, 0, data.length); | |
} | |
}); | |
server.emit('connection', fake); | |
}); |
This file contains hidden or 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 stream = require('stream'); | |
var util = require('util'); | |
var FakeSocket = module.exports = function() { | |
this.data = []; | |
stream.Duplex.call(this); | |
}; | |
util.inherits(FakeSocket, stream.Duplex); | |
FakeSocket.prototype.setTimeout = function() { }; | |
FakeSocket.prototype.destroy = function() { }; | |
FakeSocket.prototype._read = function(n) { | |
if (!this.data.length) { | |
return null; | |
} | |
var bytes = this.data.shift(); | |
return this.unshift(bytes); | |
}; | |
FakeSocket.prototype._write = function(chunk, encoding, cb) { | |
if (!chunk || chunk == 0) { | |
return cb(); | |
} | |
this.data.push(chunk); | |
cb(); | |
}; |
This file contains hidden or 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 Hello = module.exports = function() {}; | |
Hello.prototype.init = function(config) { | |
config | |
.path('/test') | |
.consumes('application/json') | |
.get('/', this.hello) | |
.post('/', this.greet); | |
}; | |
Hello.prototype.hello = function(env, next) { | |
env.response.statusCode = 200; | |
env.response.body = 'Hello world!'; | |
next(env); | |
}; | |
Hello.prototype.greet = function(env, next) { | |
env.request.getBody(function(err, body) { | |
if(err) { | |
console.log(err); | |
} else { | |
var b = JSON.parse(body.toString()); | |
env.response.statusCode = 200; | |
env.response.body = 'Hello, ' + b.name + '!'; | |
next(env); | |
} | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment