Browse Source

Web Socket to TCP socket proxy and HTML interface.

- wsproxy.py: creates a web sockets to TCP socket proxy.
- interact.html: prints received Web Sockets data and has text box to
  send strings.
Joel Martin 15 years ago
parent
commit
3292c4a995
2 changed files with 173 additions and 0 deletions
  1. 82 0
      interact.html
  2. 91 0
      wsproxy.py

+ 82 - 0
interact.html

@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>Web Sockets echo test</title>
+    <meta charset="UTF-8">
+    <script src="mootools.js"></script>
+    <script src="mootools-more.js"></script>
+    <script>
+
+        var cnt = 0;
+        var s = null; var timer = null;
+
+        function debug(str) {
+            cell = $('debug');
+            cell.innerHTML += str + "<br/>";
+        }
+
+        function send_data() {
+            var entry = $('entry');
+            debug(">> send: " + entry.value);
+            s.send(entry.value + "\n");
+            entry.value = "";  // Clear it
+            return true;
+        }
+
+        window.onload = function() {
+            debug(">> window.onload");
+            var uri = new URI(window.location);
+            var host = uri.getData("host");
+            var port = uri.getData("port");
+            if ((!host) || (!port)) {
+                debug("must set host and port");
+                return;
+            }
+            var location = "ws://" + host + ":" + port
+            debug("connecting to " + location);
+            s = new WebSocket(location);
+            s.onmessage = function(e) {
+                debug(">> onmessage");
+                var out = $("out");
+                out.innerHTML = out.innerHTML + e.data;
+            };
+            s.onopen = function(e) {
+                debug(">> onopen");
+            };
+            s.onclose = function(e) {
+                debug(">> onclose");
+                if (timer) {
+                    timer = $clear(timer);
+                }
+                debug("<< onclose");
+            }
+            debug("<< window.onload");
+        };
+
+
+    </script>
+  </head>
+    <body>
+        <h1>Web Sockets Interactive</h1>
+
+        <fieldset>
+        <h3>Server output:</h3>
+        <pre>
+            <div id="out"></div>
+        </pre>
+        </fieldset>
+
+        <p>Enter something in the entry below to send to the server.</p>
+
+        <fieldset>
+            <p>Enter: <input id="entry" onkeypress="{if (event.keyCode==13) send_data()}" size="42"></p>
+            <!-- <p>Enter: <input id="entry" onchange="send_data()" onkeypress="{if (event.keyCode==13) send_data()}" size="42"></p> -->
+        </fieldset>
+        
+        <br><br>
+        Debug:
+        <div id="debug" style="width:600px;height:300px"></div>
+    </body>
+
+
+

+ 91 - 0
wsproxy.py

@@ -0,0 +1,91 @@
+#!/usr/bin/python
+
+import sys, os, socket, time
+from select import select
+
+server_handshake = """HTTP/1.1 101 Web Socket Protocol Handshake\r
+Upgrade: WebSocket\r
+Connection: Upgrade\r
+WebSocket-Origin: %s\r
+WebSocket-Location: ws://%s%s\r
+WebSocket-Protocol: sample\r
+\r
+"""
+
+cqueue = []
+tqueue = []
+
+def start_proxy(listen_port, target_host, target_port):
+    lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    lsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+    lsock.bind(('', listen_port))
+    lsock.listen(100)
+    while True:
+        try:
+            print 'listening on port %s' % listen_port
+            csock, address = lsock.accept()
+            print 'Got client connection'
+            handshake(csock)
+            print "Handshake complete"
+            print "Connecting to: %s:%s" % (target_host, target_port)
+            tsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            tsock.connect((target_host, target_port))
+
+            socks = [csock, tsock]
+
+            while True:
+                ins, outs, excepts = select(socks, socks, socks, 1)
+                if excepts: raise Exception("Socket exception")
+
+                if csock in ins:
+                    buf = csock.recv(1024)
+                    if len(buf) == 0:
+                        csock.close()
+                        tsock.close()
+                        raise Exception("Client closed")
+                    tqueue.append(buf[1:-1])
+                    print "Client recv: %s (%d)" % (buf[1:-1], len(buf))
+
+                if tsock in ins:
+                    buf = tsock.recv(1024)
+                    if len(buf) == 0:
+                        csock.close()
+                        tsock.close()
+                        raise Exception("Target closed")
+                    cqueue.append(buf)
+                    print "Target recv: %s (%d)" % (buf[1:-1], len(buf))
+
+                if cqueue and csock in outs:
+                    while cqueue:
+                        print "Client send: %s" % "\x00" + cqueue[0] + "\xff"
+                        csock.send("\x00" + cqueue.pop(0) + "\xff")
+
+                if tqueue and tsock in outs:
+                    while tqueue:
+                        print "Target send: %s" % tqueue[0]
+                        tsock.send(tqueue.pop(0))
+
+        except Exception, e:
+            csock = tsock = None
+            print "Ignoring exception:", e
+
+def handshake(client):
+    handshake = client.recv(255)
+    req_lines = handshake.split("\r\n")
+    _, path, _ = req_lines[0].split(" ")
+    _, origin = req_lines[4].split(" ")
+    _, host = req_lines[3].split(" ")
+    #print "*** got handshake:\n%s" % handshake
+    print "*** client origin: %s, location: ws://%s%s" % (origin, host, path)
+    client.send(server_handshake % (origin, host, path))
+
+if __name__ == '__main__':
+    try:
+        if len(sys.argv) != 4: raise
+        listen_port = int(sys.argv[1])
+        target_host = sys.argv[2]
+        target_port = int(sys.argv[3])
+    except:
+        print "Usage: <listen_port> <target_host> <target_port>"
+        sys.exit(1)
+    start_proxy(listen_port, target_host, target_port)