LoginSignup
9
9

More than 5 years have passed since last update.

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

Last updated at Posted at 2012-04-16

すいません、以下のコードだとテザリングとしてはうまくうごきません。
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);
}
9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9