ソースを参照

Remove psuedo-UTF8 encoding.

It's less efficient on average that base64 (150% vs 133%). It's
non-standard (0 shifted to 256 before encoding). And I rarely use it.
Joel Martin 15 年 前
コミット
55dee43279
10 ファイル変更20 行追加175 行削除
  1. 1 2
      docs/TODO
  2. 0 14
      docs/proxy_description.txt
  3. 0 7
      include/default_controls.js
  4. 4 31
      include/rfb.js
  5. 1 4
      tests/ws.html
  6. 0 4
      tests/wsencoding.html
  7. 11 81
      utils/websocket.c
  8. 0 4
      utils/websocket.h
  9. 3 27
      utils/websocket.py
  10. 0 1
      vnc_auto.html

+ 1 - 2
docs/TODO

@@ -1,7 +1,6 @@
 Short Term:
 
-- Timing delta between frames in proxy record log, for playback
-  support (for demo and test).
+- Add realtime playback of recordings.
 
 - Playback/demo on website.
 

+ 0 - 14
docs/proxy_description.txt

@@ -32,20 +32,6 @@ the proxy to add sequence numbers to every WebSockets frame so that
 the browser can reorder them.
 
 
-UTF-8 encoding:
-
-In addition to the base64 encoding of the data, the proxy also
-supports UTF-8 encoding of the data (the native WebSockets encoding).
-However, in order to not burden the browser too much, the encoding
-doesn't use the full UTF-8 value space, but only uses the first 256
-values. This actually makes UTF-8 encoding slightly less space
-efficient than base64. Also, flash cannot handle byte arrays with 0's
-in them properly, so the values are actually 1-256 (rather than 0-255)
-and the browser does modulus 256 on the data. For these two reasons,
-base64 is the default and is indicated in the GET string by
-"base64=1".
-
-
 Flash security policy:
 
 The proxy detects flash security policy requests (again by sniffing

+ 0 - 7
include/default_controls.js

@@ -45,8 +45,6 @@ load: function(target) {
     html += '          <ul>';
     html += '            <li><input id="VNC_encrypt"';
     html += '                type="checkbox"> Encrypt</li>';
-    html += '            <li><input id="VNC_base64"';
-    html += '                type="checkbox" checked> Base64 Encode</li>';
     html += '            <li><input id="VNC_true_color"';
     html += '                type="checkbox" checked> True Color</li>';
     html += '            <li><input id="VNC_cursor"';
@@ -113,7 +111,6 @@ load: function(target) {
     DC.initSetting('port', '');
     DC.initSetting('password', '');
     DC.initSetting('encrypt', false);
-    DC.initSetting('base64', true);
     DC.initSetting('true_color', true);
     DC.initSetting('cursor', true);
 
@@ -212,7 +209,6 @@ clickSettingsMenu: function() {
         DC.closeSettingsMenu();
     } else {
         DC.updateSetting('encrypt');
-        DC.updateSetting('base64');
         DC.updateSetting('true_color');
         if (DC.rfb.get_canvas().get_cursor_uri()) {
             DC.updateSetting('cursor');
@@ -243,7 +239,6 @@ closeSettingsMenu: function() {
 settingsDisabled: function(disabled) {
     var DC = DefaultControls;
     $('VNC_encrypt').disabled = disabled;
-    $('VNC_base64').disabled = disabled;
     $('VNC_true_color').disabled = disabled;
     if (DC.rfb && DC.rfb.get_canvas().get_cursor_uri()) {
         $('VNC_cursor').disabled = disabled;
@@ -258,7 +253,6 @@ settingsApply: function() {
     //Util.Debug(">> settingsApply");
     var DC = DefaultControls;
     DC.saveSetting('encrypt');
-    DC.saveSetting('base64');
     DC.saveSetting('true_color');
     if (DC.rfb.get_canvas().get_cursor_uri()) {
         DC.saveSetting('cursor');
@@ -361,7 +355,6 @@ connect: function() {
     }
 
     DC.rfb.set_encrypt(DC.getSetting('encrypt'));
-    DC.rfb.set_b64encode(DC.getSetting('base64'));
     DC.rfb.set_true_color(DC.getSetting('true_color'));
     DC.rfb.set_local_cursor(DC.getSetting('cursor'));
 

+ 4 - 31
include/rfb.js

@@ -141,8 +141,6 @@ Util.conf_default(conf, that, 'focusContainer', document);
 
 Util.conf_default(conf, that, 'encrypt',        false, true);
 Util.conf_default(conf, that, 'true_color',     true, true);
-// false means UTF-8 on the wire
-Util.conf_default(conf, that, 'b64encode',      true, true);
 Util.conf_default(conf, that, 'local_cursor',   true, true);
 
 // time to wait for connection
@@ -250,12 +248,6 @@ function init_ws() {
         uri = "ws://";
     }
     uri += rfb_host + ":" + rfb_port + "/";
-    if (conf.b64encode) {
-        vars.push("b64encode");
-    }
-    if (vars.length > 0) {
-        uri += "?" + vars.join("&");
-    }
     Util.Info("connecting to " + uri);
     ws = new WebSocket(uri);
 
@@ -447,34 +439,15 @@ updateState = function(state, statusMsg) {
 };
 
 function encode_message(arr) {
-    if (conf.b64encode) {
-        /* base64 encode */
-        SQ = SQ + Base64.encode(arr);
-    } else {
-        /* UTF-8 encode. 0 -> 256 to avoid WebSockets framing */
-        SQ = SQ + arr.map(function (num) {
-                if (num === 0) {
-                    return String.fromCharCode(256);
-                } else {
-                    return String.fromCharCode(num);
-                }
-            } ).join('');
-    }
+    /* base64 encode */
+    SQ = SQ + Base64.encode(arr);
 }
 
 function decode_message(data) {
     var i, length;
     //Util.Debug(">> decode_message: " + data);
-    if (conf.b64encode) {
-        /* base64 decode */
-        RQ = RQ.concat(Base64.decode(data, 0));
-    } else {
-        /* UTF-8 decode. 256 -> 0 to WebSockets framing */
-        length = data.length;
-        for (i=0; i < length; i += 1) {
-            RQ.push(data.charCodeAt(i) % 256);
-        }
-    }
+    /* base64 decode */
+    RQ = RQ.concat(Base64.decode(data, 0));
     //Util.Debug(">> decode_message, RQ: " + RQ);
 }
 

+ 1 - 4
tests/ws.html

@@ -157,10 +157,7 @@
             if ($('encrypt').checked) {
                 scheme = "wss://";
             }
-            var uri = scheme + host + ":" + port + "/?b64encode";
-            //if (RFB.use_seq) {
-            //    uri += "&seq_num";
-            //}
+            var uri = scheme + host + ":" + port;
             console.log("connecting to " + uri);
             ws = new WebSocket(uri);
 

+ 0 - 4
tests/wsencoding.html

@@ -68,10 +68,6 @@
                 scheme = "wss://";
             }
             var uri = scheme + host + ":" + port;
-            //var uri = scheme + host + ":" + port + "/?b64encode";
-            //if (RFB.use_seq) {
-            //    uri += "&seq_num";
-            //}
             console.log("connecting to " + uri);
             ws = new WebSocket(uri);
 

+ 11 - 81
utils/websocket.c

@@ -42,7 +42,6 @@ int ssl_initialized = 0;
 char *tbuf, *cbuf, *tbuf_tmp, *cbuf_tmp;
 unsigned int bufsize, dbufsize;
 settings_t settings;
-client_settings_t client_settings;
 
 void traffic(char * token) {
     fprintf(stdout, "%s", token);
@@ -189,33 +188,11 @@ int encode(u_char const *src, size_t srclength, char *target, size_t targsize) {
     int i, sz = 0, len = 0;
     unsigned char chr;
     target[sz++] = '\x00';
-    if (client_settings.do_b64encode) {
-        len = __b64_ntop(src, srclength, target+sz, targsize-sz);
-        if (len < 0) {
-            return len;
-        }
-        sz += len;
-    } else {
-        for (i=0; i < srclength; i++) {
-            chr = src[i];
-            if (chr < 128) {
-                if (chr == 0x00) {
-                    target[sz++] = '\xc4';
-                    target[sz++] = '\x80';
-                } else {
-                    target[sz++] = chr;
-                }
-            } else {
-                if (chr < 192) {
-                    target[sz++] = '\xc2';
-                    target[sz++] = chr;
-                } else {
-                    target[sz++] = '\xc3';
-                    target[sz++] = chr - 64;
-                }
-            }
-        }
+    len = __b64_ntop(src, srclength, target+sz, targsize-sz);
+    if (len < 0) {
+        return len;
     }
+    sz += len;
     target[sz++] = '\xff';
     return sz;
 }
@@ -233,33 +210,11 @@ int decode(char *src, size_t srclength, u_char *target, size_t targsize) {
         /* We may have more than one frame */
         end = memchr(start, '\xff', srclength);
         *end = '\x00';
-        if (client_settings.do_b64encode) {
-            len = __b64_pton(start, target+retlen, targsize-retlen);
-            if (len < 0) {
-                return len;
-            }
-            retlen += len;
-        } else {
-            for (i=0; i < end-start; i++) {
-                chr = start[i];
-                if (chr < 128) {
-                    target[retlen++] = chr;
-                } else {
-                    i++;
-                    switch (chr) {
-                    case (unsigned char) '\xc2':
-                        target[retlen++] = start[i];
-                        break;
-                    case (unsigned char) '\xc3':
-                        target[retlen++] = start[i] + 64;
-                        break;
-                    case (unsigned char) '\xc4':
-                        target[retlen++] = 0;
-                        break;
-                    }
-                }
-            }
+        len = __b64_pton(start, target+retlen, targsize-retlen);
+        if (len < 0) {
+            return len;
         }
+        retlen += len;
         start = end + 2; // Skip '\xff' end and '\x00' start 
         framecount++;
     } while (end < (src+srclength-1));
@@ -375,13 +330,9 @@ ws_ctx_t *do_handshake(int sock) {
     char handshake[4096], response[4096], trailer[17];
     char *scheme, *pre;
     headers_t headers;
-    char *args_start, *args_end, *arg_idx;
     int len, ret;
     ws_ctx_t * ws_ctx;
 
-    // Reset settings
-    client_settings.do_b64encode = 0;
-
     // Peek, but don't read the data
     len = recv(sock, handshake, 1024, MSG_PEEK);
     handshake[len] = 0;
@@ -432,21 +383,6 @@ ws_ctx_t *do_handshake(int sock) {
         printf("  using protocol version 75\n");
     }
     
-    // Parse client settings from the GET path
-    args_start = strstr(headers.path, "?");
-    if (args_start) {
-        if (strstr(args_start, "#")) {
-            args_end = strstr(args_start, "#");
-        } else {
-            args_end = args_start + strlen(args_start);
-        }
-        arg_idx = strstr(args_start, "b64encode");
-        if (arg_idx && arg_idx < args_end) {
-            printf("  b64encode=1\n");
-            client_settings.do_b64encode = 1;
-        }
-    }
-
     sprintf(response, server_handshake, pre, headers.origin, pre, scheme,
             headers.host, headers.path, pre, trailer);
     //printf("response: %s\n", response);
@@ -561,15 +497,9 @@ void start_server() {
             continue;
         }
 
-        /* Calculate dbufsize based on client_settings */
-        if (client_settings.do_b64encode) {
-            /* base64 is 4 bytes for every 3
-             *    20 for WS '\x00' / '\xff' and good measure  */
-            dbufsize = (bufsize * 3)/4 - 20;
-        } else {
-            /* UTF-8 encoding is up to 2X larger */
-            dbufsize = (bufsize/2) - 20;
-        }
+        /* base64 is 4 bytes for every 3
+         *    20 for WS '\x00' / '\xff' and good measure  */
+        dbufsize = (bufsize * 3)/4 - 20;
 
         settings.handler(ws_ctx);
         close(csock);

+ 0 - 4
utils/websocket.h

@@ -16,10 +16,6 @@ typedef struct {
     char *cert;
 } settings_t;
 
-typedef struct {
-    int do_b64encode;
-} client_settings_t;
-
 typedef struct {
     char path[1024+1];
     char host[1024+1];

+ 3 - 27
utils/websocket.py

@@ -29,8 +29,6 @@ settings = {
     'ssl_only'    : False,
     'daemon'      : True,
     'record'      : None, }
-client_settings = {
-    'b64encode'   : False, }
 
 server_handshake = """HTTP/1.1 101 Web Socket Protocol Handshake\r
 Upgrade: WebSocket\r
@@ -48,27 +46,16 @@ def traffic(token="."):
     sys.stdout.flush()
 
 def encode(buf):
-    if client_settings['b64encode']:
-        buf = b64encode(buf)
-    else:
-        # Modified UTF-8 encode
-        buf = buf.decode('latin-1').encode('utf-8').replace("\x00", "\xc4\x80")
+    buf = b64encode(buf)
 
     return "\x00%s\xff" % buf
 
 def decode(buf):
     """ Parse out WebSocket packets. """
     if buf.count('\xff') > 1:
-        if client_settings['b64encode']:
-            return [b64decode(d[1:]) for d in buf.split('\xff')]
-        else:
-            # Modified UTF-8 decode
-            return [d[1:].replace("\xc4\x80", "\x00").decode('utf-8').encode('latin-1') for d in buf.split('\xff')]
+        return [b64decode(d[1:]) for d in buf.split('\xff')]
     else:
-        if client_settings['b64encode']:
-            return [b64decode(buf[1:-1])]
-        else:
-            return [buf[1:-1].replace("\xc4\x80", "\x00").decode('utf-8').encode('latin-1')]
+        return [b64decode(buf[1:-1])]
 
 def parse_handshake(handshake):
     ret = {}
@@ -99,9 +86,6 @@ def gen_md5(keys):
 
 
 def do_handshake(sock):
-    global client_settings
-
-    client_settings['b64encode'] = False
 
     # Peek, but don't read the data
     handshake = sock.recv(1024, socket.MSG_PEEK)
@@ -136,14 +120,6 @@ def do_handshake(sock):
     #print "handshake: " + repr(handshake)
     h = parse_handshake(handshake)
 
-    # Parse client settings from the GET path
-    cvars = parse_qsl(urlsplit(h['path'])[3], True)
-    for name, val in cvars:
-        if name not in ['b64encode']: continue
-        value = val and val or True
-        client_settings[name] = value
-        print "  %s=%s" % (name, value)
-
     if h.get('key3'):
         trailer = gen_md5(h)
         pre = "Sec-"

+ 0 - 1
vnc_auto.html

@@ -99,7 +99,6 @@ Connect parameters are provided in query string:
             }
 
             rfb = new RFB({'encrypt':      Util.getQueryVar('encrypt', true),
-                       'b64encode':    Util.getQueryVar('base64', true),
                        'true_color':   Util.getQueryVar('true_color', true),
                        'local_cursor': Util.getQueryVar('cursor', true),
                        'updateState':  updateState});