From 4f7500025676ea75090aadef0eeb19947e7d5208 Mon Sep 17 00:00:00 2001 From: Iwasaki Yudai Date: Wed, 2 Sep 2015 20:16:35 -0700 Subject: [PATCH] Send data in base64 format Raw data sometimes include invalid UTF-8 bytes and that brings errors to WebSocket clients. To avoid the errors, encode data into base64 before sending it. --- app/client_context.go | 8 ++++---- app/resource.go | 4 ++-- resources/gotty.js | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/client_context.go b/app/client_context.go index 5696edf3..63ad67e8 100644 --- a/app/client_context.go +++ b/app/client_context.go @@ -1,6 +1,7 @@ package app import ( + "encoding/base64" "encoding/json" "log" "net/http" @@ -11,7 +12,6 @@ import ( "unsafe" "github.com/gorilla/websocket" - "github.com/yudai/utf8reader" ) type clientContext struct { @@ -93,16 +93,16 @@ func (context *clientContext) processSend() { } buf := make([]byte, 1024) - utf8f := utf8reader.New(context.pty) for { - size, err := utf8f.Read(buf) + size, err := context.pty.Read(buf) + safeMessage := base64.StdEncoding.EncodeToString([]byte(buf[:size])) if err != nil { log.Printf("Command exited for: %s", context.request.RemoteAddr) return } - err = context.connection.WriteMessage(websocket.TextMessage, append([]byte{Output}, buf[:size]...)) + err = context.connection.WriteMessage(websocket.TextMessage, append([]byte{Output}, []byte(safeMessage)...)) if err != nil { return } diff --git a/app/resource.go b/app/resource.go index d4b568ec..7312c29d 100644 --- a/app/resource.go +++ b/app/resource.go @@ -111,7 +111,7 @@ func staticIndexHtml() (*asset, error) { return a, nil } -var _staticJsGottyJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x56\x5f\x8f\xe2\x36\x10\x7f\xdf\x4f\x61\xf9\x05\xa7\xe5\xb2\x70\x57\xf5\x01\xb4\xad\xd4\xd3\x56\xba\xb6\xea\x9e\x0e\xda\x7d\x58\xad\x4e\x26\x19\x20\x5d\x63\x47\xb6\xb3\x11\xad\xf8\xee\x9d\x49\x42\x08\xc1\x39\xee\xfc\x00\x8e\xe7\xdf\x6f\x66\x3c\x33\x16\xeb\x42\x27\x3e\x33\x5a\x44\xec\xbf\x1b\x86\xeb\x55\x5a\xb6\xf5\x3e\x77\xf7\x5a\xae\x14\xa4\xec\x8e\x95\x99\x4e\x4d\x19\x2b\x93\x48\x62\x8d\x73\x6b\xbc\x49\x8c\x62\x77\x77\x8c\x57\xbc\x33\x3e\x6f\x85\x0b\x8b\x04\x26\xce\x74\xfc\xcc\x46\xa5\x73\xb3\xdb\xdb\x11\x9b\xd1\x96\x76\x11\xfb\xfe\x42\xf3\xd6\x38\x1f\x38\xce\xa5\xdf\x6a\xb9\x03\x24\xa1\xf0\xe8\x64\xeb\x88\xc4\xa1\xc5\x27\xbe\x31\xde\xef\xf9\xf3\x89\x2c\x0b\x6f\x3e\x41\x62\xb4\x86\xc4\x23\xcb\x9b\xe9\xfc\xa6\x25\x9a\x1c\xf4\x23\x09\x5e\x84\xe0\xc8\x51\x12\x55\x43\xc9\x1e\x61\xb5\x30\xc9\x0b\x78\x81\xce\x8d\x4f\x56\xa3\x46\xdd\x51\xc0\x83\xdd\xf5\x8e\xf2\x4c\x6f\x96\xd9\x0e\x6c\xe7\xbc\x74\xb1\xd1\x64\xbe\x6b\x1c\x5e\x41\xfb\x2e\x82\x86\xd3\x81\x4e\x45\xe5\xd9\x67\x74\x67\xfb\xd9\x9b\x17\xd0\x5d\xc3\xb4\x5a\x2b\xa8\xd1\x81\xff\xa0\x11\xc9\xab\x54\x82\x84\x3f\x22\x6d\xcc\xde\x4d\xd8\x77\x6c\x3a\x99\x4c\xc6\xa8\xb4\x2f\xbe\x25\xe0\x71\x0a\x6b\x59\x28\xbf\xf0\xc6\xca\x0d\x34\xae\xab\x6c\x15\x37\x27\xf1\x1f\x98\x0f\x25\xa2\xf9\x55\xd9\x38\x51\x20\xad\xe8\x9b\x21\xce\x46\x6d\x2d\xb5\xc4\x9f\x4c\xd7\x3a\x2f\x38\xe3\x0d\xf8\x8f\x16\xd6\x4e\x44\x18\x04\x2f\x38\x39\xf3\x06\x74\x62\x52\xf4\x88\x8f\x19\xb7\xb2\xe4\x41\x49\xa3\x8f\x9a\x3f\x81\x4c\xf7\x43\x39\xee\xe6\x29\x33\xc8\x55\x09\x67\x26\xce\x0b\xb7\xbd\xc0\x44\x0b\x69\x46\xff\xbd\xfc\x1d\xf6\xce\x5b\x4c\x44\x57\x33\x9e\x84\x94\x77\xd3\xc8\x27\x1c\xaf\x30\x31\xce\x2f\xf8\x0e\x61\x73\x24\xb7\xf0\x16\x3d\x46\x5b\x7d\xf3\x43\x08\x4f\xde\xbb\xec\xdf\x33\x90\x78\x6b\x8b\x9d\x76\x63\x66\x0d\x5e\x83\x2b\x70\x83\x44\x5a\xfc\x2d\xf9\xf1\xdb\xe2\xe1\xcf\xd8\x55\xd8\xb2\xf5\x7e\x98\x9b\x56\xd8\x50\x77\x35\xc8\x66\xc7\xcd\xf8\xaa\x04\xb9\x30\xab\x7e\xbf\xcc\x7b\x18\xa4\x46\x41\xca\xe5\x69\x28\x37\xf5\x5d\xd1\xce\x4b\xa5\x30\x21\x2b\x23\x6d\xda\xaf\x8d\xbe\x5c\x53\x2a\x09\x16\x89\x07\x91\x9a\xa4\xd8\x61\xd1\xd3\x45\xbf\x57\x40\xdb\x5f\xf6\x1f\xf0\x96\xf8\x26\x7d\x3c\xea\xe8\x3b\xf4\x1b\xc8\x0e\x9c\xab\xeb\xf4\xcb\x3d\x24\x95\x5e\x22\x53\x45\x8b\xe9\x23\x76\x2a\x4b\x40\x4c\x7b\x60\x5d\x99\xf9\x64\x2b\x4e\x7c\x4f\x93\xe7\xbe\xae\x44\x3a\x60\xa3\xc9\x68\x36\x10\x0e\x13\x97\x36\xf3\xf0\xd7\xf2\xd7\xe9\x8f\x82\x74\x04\x2e\xfa\xca\x82\x7c\x99\x07\xd4\x4e\x03\x6a\x6f\x6f\x59\x6e\xf4\x26\xc0\xfd\x76\x08\x04\xf6\x8a\xc7\x6a\x7e\x2c\x33\xaf\xe0\x9b\x51\xbc\x0b\xe8\xcd\xb1\x0d\x81\xc5\xd6\x03\x34\x11\xaa\x7b\x9f\x4b\xeb\x06\x95\x3f\xac\xfe\xc1\x81\x13\xbf\x60\x9d\x8a\x8e\x6c\x14\xaf\x8d\xbd\x97\x18\xe4\x36\x63\xc8\x32\x54\x85\x38\xb6\x9c\x51\x80\x53\x70\x23\xf8\x02\xbc\xa7\x1e\x40\x75\x87\x32\xf8\xcb\x67\xd5\x47\x17\xdb\x13\x52\x9e\x03\x70\xda\xd0\xf4\x3a\x2a\xb2\x8f\xbf\x46\xfe\xf0\x2d\xf1\xfb\x21\x10\xbf\xfe\x1c\xbe\x1e\xc1\x33\xe7\xab\x57\x04\x79\x6f\x8f\x3a\x6a\xdf\xcf\xd5\x62\x48\x70\xf6\xe1\x57\xea\xf8\x65\x09\x07\xf0\x1e\x86\x6b\x2b\x51\xc6\x5d\xaf\xac\x6c\xcd\x04\xc5\x35\x94\xc1\x2a\xde\x85\xbe\xd2\x20\x5a\x4e\xea\xf4\x5b\x53\x3e\xbc\x82\x55\x72\x2f\xf8\xfb\xda\x29\x34\xcd\xde\x13\x96\x14\xe7\x9d\x2e\x94\xea\x37\x98\xf3\x04\xd0\xd4\x6d\x67\x7f\xfb\x26\xe8\xc9\x10\xea\xf3\xc8\xfd\xc4\x26\x21\x17\xf0\x8a\x90\xbc\x29\xbc\xa8\xdf\x4a\xe3\x5e\xc4\xeb\x07\xc5\x20\xa4\x43\x4d\x38\xdc\x9c\xde\x5c\xc7\xf7\x48\x37\xb4\xe7\x73\xa8\x1d\x95\x53\x1e\xb5\xf2\xf4\x57\x43\xa0\x00\x1e\x22\x11\xdd\xfc\x1f\x00\x00\xff\xff\x75\x62\xa1\xec\xb9\x0a\x00\x00") +var _staticJsGottyJs = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x56\x5f\x8f\xe2\x36\x10\x7f\xdf\x4f\x61\xf9\x05\xa7\xe5\xb2\x70\xd7\x87\x0a\xb4\xad\xd4\xd3\x56\xba\xb6\xea\x9e\x0e\xda\x7d\x58\xad\x4e\x26\x19\x20\x5d\x63\x47\xb6\xb3\x11\xad\xf8\xee\x9d\x49\x42\x08\xc1\x39\xee\xfc\x00\x8e\xe7\xdf\x6f\x66\x3c\x33\x16\xeb\x42\x27\x3e\x33\x5a\x44\xec\xbf\x1b\x86\xeb\x55\x5a\xb6\xf5\x3e\x77\xf7\x5a\xae\x14\xa4\xec\x8e\x95\x99\x4e\x4d\x19\x2b\x93\x48\x62\x8d\x73\x6b\xbc\x49\x8c\x62\x77\x77\x8c\x57\xbc\x33\x3e\x6f\x85\x0b\x8b\x04\x26\xce\x74\xfc\xcc\x46\xa5\x73\xb3\xdb\xdb\x11\x9b\xd1\x96\x76\x11\xfb\xfe\x42\xf3\xd6\x38\x1f\x38\xce\xa5\xdf\x6a\xb9\x03\x24\xa1\xf0\xe8\x64\xeb\x88\xc4\xa1\xc5\x27\xbe\x31\xde\xef\xf9\xf3\x89\x2c\x0b\x6f\x3e\x41\x62\xb4\x86\xc4\x23\xcb\x9b\xe9\xfc\xa6\x25\x9a\x1c\xf4\x23\x09\x5e\x84\xe0\xc8\x51\x12\x55\x43\xc9\x1e\x61\xb5\x30\xc9\x0b\x78\x81\xce\x8d\x4f\x56\xa3\x46\xdd\x51\xc0\x83\xdd\xf5\x8e\xf2\x4c\x6f\x96\xd9\x0e\x6c\xe7\xbc\x74\xb1\xd1\x64\xbe\x6b\x1c\x5e\x41\xfb\x2e\x82\x86\xd3\x81\x4e\x45\xe5\xd9\x67\x74\x67\xfb\xd9\x9b\x17\xd0\x5d\xc3\xb4\x5a\x2b\xa8\xd1\x81\xff\xa0\x11\xc9\xab\x54\x82\x84\x3f\x22\x6d\xcc\xde\x4d\xd8\x77\x6c\x3a\x99\x4c\xc6\xa8\xb4\x2f\xbe\x25\xe0\x71\x0a\x6b\x59\x28\xbf\xf0\xc6\xca\x0d\x34\xae\xab\x6c\x15\x37\x27\xf1\x1f\x98\x0f\x25\xa2\xf9\x55\xd9\x38\x51\x20\xad\xe8\x9b\x21\xce\x46\x6d\x2d\xb5\xc4\x9f\x4c\xd7\x3a\x2f\x38\xe3\x0d\xf8\x8f\x16\xd6\x4e\x44\x18\x04\x2f\x38\x39\xf3\x06\x74\x62\x52\xf4\x88\x8f\x19\xb7\xb2\xe4\x41\x49\xa3\x8f\x9a\x3f\x81\x4c\xf7\x43\x39\xee\xe6\x29\x33\xc8\x55\x09\x67\x26\xce\x0b\xb7\xbd\xc0\x44\x0b\x69\x46\xff\xbd\xfc\x1d\xf6\xce\x5b\x4c\x44\x57\x33\x9e\x84\x94\x77\xd3\xc8\x27\x1c\xaf\x30\x31\xce\x2f\xf8\x0e\x61\x73\x24\xb7\xf0\x16\x3d\x46\x5b\x7d\xf3\x43\x08\x4f\xde\xbb\xec\xdf\x33\x90\x78\x6b\x8b\x9d\x76\x63\x66\x0d\x5e\x83\x2b\x70\x83\x44\x5a\xfc\x2d\xf9\xf1\xdb\xe2\xe1\xcf\xd8\x55\xd8\xb2\xf5\x7e\x98\x9b\x56\xd8\x50\x77\x35\xc8\x66\xc7\xcd\xf8\xaa\x04\xb9\x30\xab\x7e\xbf\xcc\x7b\x18\xa4\x46\x41\xca\xe5\x69\x28\x37\xf5\x5d\xd1\xce\x4b\xa5\x30\x21\x2b\x23\x6d\xda\xaf\x8d\xbe\x5c\x53\x2a\x09\x16\x89\x07\x91\x9a\xa4\xd8\x61\xd1\xd3\x45\xbf\x57\x40\xdb\x5f\xf6\x1f\xf0\x96\xf8\x26\x7d\x3c\xea\xe8\x3b\xf4\x1b\xc8\x0e\x9c\xab\xeb\xf4\xcb\x3d\x24\x95\x5e\x22\x53\x45\x8b\xe9\x23\x76\x2a\x4b\x40\x4c\x7b\x60\x5d\x99\xf9\x64\x2b\x4e\x7c\x4f\x93\xe7\xbe\xae\x44\x3a\x60\xa3\xc9\x68\x36\x10\x0e\x13\x97\x36\xf3\xf0\xd7\xf2\xd7\x1f\x45\xd3\xc4\xa5\x37\x2b\x41\xea\xa2\xc0\xa5\x5f\x59\x90\x2f\xf3\x80\x89\x69\xc0\xc4\xed\x2d\xcb\x8d\xde\x04\xb8\xdf\x0e\x01\xc2\xbe\xf1\x58\xc1\x58\x66\x5e\x41\x0d\xe3\x1b\x50\xbc\x0b\xe8\xcd\xb1\x25\x81\xc5\x36\x04\x34\x1d\xaa\x1a\xc8\xa5\x75\x83\xca\x1f\x56\xff\xe0\xf0\x89\x5f\xb0\x66\x45\x47\x36\x8a\xd7\xc6\xde\x4b\x0c\x78\x9b\x3d\x64\x19\xaa\x48\x1c\x61\xce\x28\xc0\x89\xb8\x11\x7c\x01\xde\x53\x3f\xa0\x1a\x44\x19\xfc\xe5\xb3\xea\xa3\x8b\xed\x09\x29\xcf\x01\x38\x6d\x68\x7a\xdd\x15\xd9\xc7\x5f\x23\x7f\xf8\x96\xf8\xfd\x10\x88\x5f\x7f\x26\x5f\x8f\xe0\x99\xf3\xd5\x8b\x82\xbc\xb7\x47\x1d\xb5\xef\xe7\x6a\x31\x24\x38\x07\xf1\x2b\x75\xfc\xb2\x9c\x03\x78\x0f\xc3\x75\x96\x28\xe3\xae\x57\x59\xb6\x66\x82\xe2\x1a\xca\x60\x15\xef\x42\x5f\x69\x16\x2d\x27\x75\xfd\xad\x29\x1f\x5e\xc1\x2a\xb9\x17\xfc\x7d\xed\x14\x9a\x66\xef\x09\x4b\x8a\xb3\x4f\x17\x4a\xf5\x9b\xcd\x79\x02\x68\x02\xb7\xef\x80\xf6\x7d\xd0\x93\x21\xd4\xe7\x91\xfb\x89\x4d\x42\x2e\xe0\x15\x21\x79\x53\x78\x51\xbf\x9b\xc6\xbd\x88\xd7\x8f\x8b\x41\x48\x87\x9a\x70\xb8\x39\xbd\xbf\x8e\x6f\x93\x6e\x68\xcf\x67\x52\x3b\x36\xa7\x3c\x6a\xe5\xe9\xaf\x86\x40\x01\x3c\x44\x22\xba\xf9\x3f\x00\x00\xff\xff\xb4\x83\x76\xe8\xc5\x0a\x00\x00") func staticJsGottyJsBytes() ([]byte, error) { return bindataRead( @@ -126,7 +126,7 @@ func staticJsGottyJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static/js/gotty.js", size: 2745, mode: os.FileMode(436), modTime: time.Unix(1441082090, 0)} + info := bindataFileInfo{name: "static/js/gotty.js", size: 2757, mode: os.FileMode(436), modTime: time.Unix(1441231392, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/resources/gotty.js b/resources/gotty.js index da2bcdfa..1decd5df 100644 --- a/resources/gotty.js +++ b/resources/gotty.js @@ -53,7 +53,7 @@ data = event.data.slice(1); switch(event.data[0]) { case '0': - term.io.writeUTF16(data); + term.io.writeUTF8(window.atob(data)); break; case '1': // pong