node.jsでのバイナリの扱い(合法テザリングへの道のり）

すいません、以下のコードだとテザリングとしてはうまくうごきません。
http://kjunichi.cocolog-nifty.com/misc/2012/03/wifiipadiphone3.html
にソース貼り付けておきました。

タイトルのバイナリの扱いのポイントは
絶対にbinaryを指定をしない
これに尽きます。

``` エンコード.js
webBrowser.on('data', function(data) {
 // WebSocketにBASE64エンコードして送信
 myWsClient.emit('httptows' ,data.toString('base64'));
```

``` デコード.js
myWsClient.on('wstohttp', function(data) {
 // 受信した文字列をBASE64でコードしてWebブラウザに送信
 var a = new Buffer(data.toString(), 'base64');
 webBrowser.write(a);
```

``` index.html
<script src="/socket.io/socket.io.js"></script>
<script>
	// フロント側のHttpProxyサーバから
  	var socket = io.connect('http://localhost');
  	
  	// WS->HttpProxyサーバ
  	var proxy = io.connect('http://localhost:8123');
  	
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });
  
  socket.on('httptows', function (data) {
    console.log("to proxy : " +data);
    proxy.emit('wstohttp', data);
  });
  
  // WS->HttpProxyサーバからの応答
  proxy.on('httptows', function (data) {
  	console.log("from proxy : " + data);
  	socket.emit('wstohttp', data );
  });
  
  // WS->HttpProxyサーバからの応答(切断)
  proxy.on('httpend', function (data) {
  	console.log("from proxy end ");
  	socket.emit('httpend', data );
  });
  
  console.log("test!");
</script>
```


``` http2ws.js
// 例外が発生してもサービスを停止しないようにする
process.on('uncaughtException', function(err){ console.log(err.stack); });

var app = require('http').createServer(handler)
  , io = require('socket.io').listen(app)
  , fs = require('fs')

app.listen(80);

function handler (req, res) {
  fs.readFile(__dirname + '/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

var myWsClient = {};

io.sockets.on('connection', function (wsclient) {
	myWsClient = wsclient;
	console.log("HTTP Proxy start");
	var server = doProxy();
	wsclient.on('end',function() {
		console.log("HTTP Proxy end");
		server.close();
	});
});

function doProxy() {
	// HttpProxyを開始する。
	var port = 8081;
	var sys = require('util');
	var net = require('net');

	var server = net.createServer(function(webBrowser) {
		console.log('web client connected');
		
		// クライアントからデータを受けた場合
		webBrowser.on('data', function(data) {
			var parseheader = data.toString().split(/\n/);
			if(parseheader[0].match(/^GET/) ||
		 		parseheader[0].match(/^CONNECT/) ||
		 		parseheader[0].match(/^POST/)) {
		 		console.log("client send : " + parseheader[0].toString());
			} else {
				console.log("client send ");
			}
				
			// Base64化してWS->HttpProxyへ送る
			console.log("to ws : " + data.toString('base64'));
			myWsClient.emit('httptows' ,data.toString('base64'));
		});

		webBrowser.on('end', function() {
			console.log('client disconnected');
	  	});

	  	myWsClient.on('wstohttp', function(data) {
	  		// WebSocket経由で結果受取、Base64デコードしてブラウザに返す。
			console.log('server send data :' + data);
			var a = new Buffer(data.toString(), 'base64');
			
			webBrowser.write(a);
			dumpResponse(a);
		});
		
		myWsClient.on('httpend', function(data) {
			// HttpProxy先でコネクションが切れたら、こちらもクライアントを切断
			webBrowser.end();
		});
		myWsClient.on('end', function() {
			console.log('server disconnected');
			webBrowser.end();
		});
	}); // server

	server.listen(port, function() { //'listening' listener
		console.log('server bound');
	});

	sys.puts('Server listening on port ' + port);
}

function dumpResponse(buf) {
	var tmp = "";
	// 表示できる文字は表示する
	for (var i = 0; i < buf.length ; i++) {
		var c = buf.readUInt8(i);
		if( (c > 31 && c < 127) || c==13 || c==10) {
			tmp = tmp + String.fromCharCode(c);
		} else {
			tmp = tmp + c + ":";
		}
	}
	console.log(tmp);
}
```

``` ws2http.js
// 例外が発生してもサービスを停止しないようにする
process.on('uncaughtException', function(err){ console.log(err.stack); });

var app = require('http').createServer(handler)
  , io = require('socket.io').listen(app)
  , fs = require('fs');

var net = require('net');

app.listen(8123);

function handler (req, res) {
  fs.readFile(__dirname + '/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

io.sockets.on('connection', function (socket) 
	{
		var isProxyClose = true;
	    // HTTP Proxyサーバへ接続する。
   		var proxy = doProxyProc(socket, isProxyClose);

		
    }
);

function doProxyProc(socket,isProxyClose) {
	var proxy = "";
	console.log('server connected');
	socket.on('wstohttp', function(data) {
		// WebSocketでデータを受けたらHttpProxyに接続する
		proxy = net.createConnection(8080,'127.0.0.1',function() {
	  		console.log("from client : " + data);

			// base64デコードしてproxyサーバに送る
			var a = new Buffer(data.toString(), 'base64');
			proxy.write(a);
			dumpResponse(a);
			
			proxy.on('close',function(){
				console.log('server close!');
				isProxyClose = true;
				socket.emit('httpend', 'end');
			});
			
			proxy.on('data',function(data) {
			  	// WebSocketでHttpProxyからの応答をBase64エンコードして返す。
			  	
  				socket.emit('httptows', data.toString('base64'));
  				//console.log('server send data : ' + data.toString('base64'));
  				dumpString(data.toString('base64'));
			});
		
			proxy.on('end', function() {
  				console.log('server disconnected');
  				socket.emit('httpend', 'end');
  				//socket.end();
			});
		});
		socket.on('end', function() {
			console.log('client disconnected');
			proxy.end();
		});
	});
	return proxy;
}

function dumpString(str) {
	var tmp = "";
	// 表示できる文字は表示する
	for (var i = 0; i < str.length ; i++) {
		var c = str.charAt(i);
		if( (c > 31 && c < 127) || c==13 || c==10) {
			tmp = tmp + String.fromCharCode(c);
		} else {
			tmp = tmp + c + ":";
		}
	}
	console.log(tmp);
}

function dumpResponse(buf) {
	var tmp = "";
	// 表示できる文字は表示する
	for (var i = 0; i < buf.length ; i++) {
		var c = buf.readUInt8(i);
		if( (c > 31 && c < 127) || c==13 || c==10) {
			tmp = tmp + String.fromCharCode(c);
		} else {
			tmp = tmp + c + ":";
		}
	}
	console.log(tmp);
}