Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
N
noVNC
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
rasky
noVNC
Commits
fc003a13
Commit
fc003a13
authored
Aug 15, 2012
by
Joel Martin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Pull in latest websockify."
This reverts commit
4dd1bb1e
.
parent
ca6b3f4c
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
127 additions
and
301 deletions
+127
-301
websock.js
include/websock.js
+20
-83
websocket.py
utils/websocket.py
+89
-105
websockify
utils/websockify
+18
-113
No files found.
include/websock.js
View file @
fc003a13
...
...
@@ -61,8 +61,6 @@ function Websock() {
var
api
=
{},
// Public API
websocket
=
null
,
// WebSocket object
protocols
,
// Protocols to request in priority order
mode
=
'base64'
,
rQ
=
[],
// Receive queue
rQi
=
0
,
// Receive queue index
rQmax
=
10000
,
// Max receive queue size before compacting
...
...
@@ -125,46 +123,26 @@ function rQshift32() {
(
rQ
[
rQi
++
]
<<
8
)
+
(
rQ
[
rQi
++
]
);
}
function
rQslice
(
start
,
end
)
{
if
(
mode
===
'binary'
)
{
if
(
end
)
{
return
rQ
.
subarray
(
rQi
+
start
,
rQi
+
end
);
}
else
{
return
rQ
.
subarray
(
rQi
+
start
);
}
}
else
{
if
(
end
)
{
return
rQ
.
slice
(
rQi
+
start
,
rQi
+
end
);
}
else
{
return
rQ
.
slice
(
rQi
+
start
);
}
}
}
function
rQshiftStr
(
len
)
{
if
(
typeof
(
len
)
===
'undefined'
)
{
len
=
rQlen
();
}
var
arr
=
rQ
slice
(
0
,
len
);
var
arr
=
rQ
.
slice
(
rQi
,
rQi
+
len
);
rQi
+=
len
;
return
String
.
fromCharCode
.
apply
(
null
,
arr
);
return
arr
.
map
(
function
(
num
)
{
return
String
.
fromCharCode
(
num
);
}
).
join
(
''
);
}
function
rQshiftBytes
(
len
)
{
if
(
typeof
(
len
)
===
'undefined'
)
{
len
=
rQlen
();
}
var
a
=
rQslice
(
0
,
len
),
b
=
[];
if
(
mode
===
'binary'
)
{
// Convert to plain array
b
.
push
.
apply
(
b
,
a
);
}
else
{
// Already plain array, just return the original
b
=
a
}
rQi
+=
len
;
return
b
;
return
rQ
.
slice
(
rQi
-
len
,
rQi
)
;
}
function
rQshiftArray
(
len
)
{
if
(
typeof
(
len
)
===
'undefined'
)
{
len
=
rQlen
();
}
var
a
=
rQslice
(
0
,
len
);
rQi
+=
len
;
return
a
;
function
rQslice
(
start
,
end
)
{
if
(
end
)
{
return
rQ
.
slice
(
rQi
+
start
,
rQi
+
end
);
}
else
{
return
rQ
.
slice
(
rQi
+
start
);
}
}
// Check to see if we must wait for 'num' bytes (default to FBU.bytes)
...
...
@@ -192,26 +170,13 @@ function rQwait(msg, num, goback) {
function
encode_message
()
{
/* base64 encode */
if
(
mode
===
'binary'
)
{
return
(
new
Uint8Array
(
sQ
)).
buffer
;
}
else
{
return
Base64
.
encode
(
sQ
);
}
return
Base64
.
encode
(
sQ
);
}
function
decode_message
(
data
)
{
//Util.Debug(">> decode_message: " + data);
if
(
mode
===
'binary'
)
{
// Create new arraybuffer and dump old and new data into it
// TODO: this could be far more efficient and re-use the array
var
new_rQ
=
new
Uint8Array
(
rQ
.
length
+
data
.
byteLength
);
new_rQ
.
set
(
rQ
);
new_rQ
.
set
(
new
Uint8Array
(
data
),
rQ
.
length
);
rQ
=
new_rQ
;
}
else
{
/* base64 decode and concat to the end */
rQ
=
rQ
.
concat
(
Base64
.
decode
(
data
,
0
));
}
/* base64 decode */
rQ
=
rQ
.
concat
(
Base64
.
decode
(
data
,
0
));
//Util.Debug(">> decode_message, rQ: " + rQ);
}
...
...
@@ -265,7 +230,7 @@ function recv_message(e) {
// Compact the receive queue
if
(
rQ
.
length
>
rQmax
)
{
//Util.Debug("Compacting receive queue");
rQ
=
rQslice
(
rQi
);
rQ
=
rQ
.
slice
(
rQi
);
rQi
=
0
;
}
}
else
{
...
...
@@ -298,32 +263,7 @@ function init() {
rQ
=
[];
rQi
=
0
;
sQ
=
[];
websocket
=
null
,
protocols
=
"base64"
;
var
bt
=
false
,
wsbt
=
false
;
if
((
'Uint8Array'
in
window
)
&&
(
'set'
in
Uint8Array
.
prototype
))
{
bt
=
true
;
}
// TODO: this sucks, the property should exist on the prototype
// but it does not.
try
{
if
(
bt
&&
(
'binaryType'
in
(
new
WebSocket
(
"ws://localhost:17523"
))))
{
wsbt
=
true
;
}
}
catch
(
exc
)
{
// Just ignore failed test localhost connections
}
if
(
bt
&&
wsbt
)
{
Util
.
Info
(
"Detected binaryType support in WebSockets"
);
protocols
=
[
'binary'
,
'base64'
];
}
else
{
Util
.
Info
(
"No binaryType support in WebSockets, using base64 encoding"
);
protocols
=
'base64'
;
}
websocket
=
null
;
}
function
open
(
uri
)
{
...
...
@@ -332,22 +272,19 @@ function open(uri) {
if
(
test_mode
)
{
websocket
=
{};
}
else
{
websocket
=
new
WebSocket
(
uri
,
protocols
);
websocket
=
new
WebSocket
(
uri
,
'base64'
);
// TODO: future native binary support
//websocket = new WebSocket(uri, ['binary', 'base64']);
}
websocket
.
onmessage
=
recv_message
;
websocket
.
onopen
=
function
()
{
Util
.
Debug
(
">> WebSock.onopen"
);
if
(
websocket
.
protocol
)
{
mode
=
websocket
.
protocol
;
Util
.
Info
(
"Server chose sub-protocol: "
+
websocket
.
protocol
);
}
else
{
mode
=
'base64'
;
Util
.
Error
(
"Server select no sub-protocol!: "
+
websocket
.
protocol
);
}
if
(
mode
===
'binary'
)
{
websocket
.
binaryType
=
'arraybuffer'
;
}
eventHandlers
.
open
();
Util
.
Debug
(
"<< WebSock.onopen"
);
};
...
...
utils/websocket.py
View file @
fc003a13
This diff is collapsed.
Click to expand it.
utils/websockify
View file @
fc003a13
...
...
@@ -13,11 +13,9 @@ as taken from http://docs.python.org/dev/library/ssl.html#certificates
import
socket
,
optparse
,
time
,
os
,
sys
,
subprocess
from
select
import
select
import
websocket
try
:
from
urllib.parse
import
parse_qs
,
urlparse
except
:
from
urlparse
import
parse_qs
,
urlparse
from
websocket
import
WebSocketServer
class
WebSocketProxy
(
websocket
.
WebSocketServer
):
class
WebSocketProxy
(
WebSocketServer
):
"""
Proxy traffic to and from a WebSockets client to a normal TCP
socket server target. All traffic to/from the client is base64
...
...
@@ -45,9 +43,6 @@ Traffic Legend:
self
.
target_port
=
kwargs
.
pop
(
'target_port'
)
self
.
wrap_cmd
=
kwargs
.
pop
(
'wrap_cmd'
)
self
.
wrap_mode
=
kwargs
.
pop
(
'wrap_mode'
)
self
.
unix_target
=
kwargs
.
pop
(
'unix_target'
)
self
.
ssl_target
=
kwargs
.
pop
(
'ssl_target'
)
self
.
target_cfg
=
kwargs
.
pop
(
'target_cfg'
)
# Last 3 timestamps command was run
self
.
wrap_times
=
[
0
,
0
,
0
]
...
...
@@ -63,7 +58,6 @@ Traffic Legend:
if
not
self
.
rebinder
:
raise
Exception
(
"rebind.so not found, perhaps you need to run make"
)
self
.
rebinder
=
os
.
path
.
abspath
(
self
.
rebinder
)
self
.
target_host
=
"127.0.0.1"
# Loopback
# Find a free high port
...
...
@@ -77,10 +71,7 @@ Traffic Legend:
"REBIND_OLD_PORT"
:
str
(
kwargs
[
'listen_port'
]),
"REBIND_NEW_PORT"
:
str
(
self
.
target_port
)})
if
self
.
target_cfg
:
self
.
target_cfg
=
os
.
path
.
abspath
(
self
.
target_cfg
)
websocket
.
WebSocketServer
.
__init__
(
self
,
*
args
,
**
kwargs
)
WebSocketServer
.
__init__
(
self
,
*
args
,
**
kwargs
)
def
run_wrap_cmd
(
self
):
print
(
"Starting '
%
s'"
%
" "
.
join
(
self
.
wrap_cmd
))
...
...
@@ -97,26 +88,14 @@ Traffic Legend:
# Need to call wrapped command after daemonization so we can
# know when the wrapped command exits
if
self
.
wrap_cmd
:
dst_string
=
"'
%
s' (port
%
s)"
%
(
" "
.
join
(
self
.
wrap_cmd
),
self
.
target_port
)
elif
self
.
unix_target
:
dst_string
=
self
.
unix_target
else
:
dst_string
=
"
%
s:
%
s"
%
(
self
.
target_host
,
self
.
target_port
)
if
self
.
target_cfg
:
msg
=
" - proxying from
%
s:
%
s to targets in
%
s"
%
(
self
.
listen_host
,
self
.
listen_port
,
self
.
target_cfg
)
else
:
msg
=
" - proxying from
%
s:
%
s to
%
s"
%
(
self
.
listen_host
,
self
.
listen_port
,
dst_string
)
if
self
.
ssl_target
:
msg
+=
" (using SSL)"
print
(
msg
+
"
\n
"
)
if
self
.
wrap_cmd
:
print
(
" - proxying from
%
s:
%
s to '
%
s' (port
%
s)
\n
"
%
(
self
.
listen_host
,
self
.
listen_port
,
" "
.
join
(
self
.
wrap_cmd
),
self
.
target_port
))
self
.
run_wrap_cmd
()
else
:
print
(
" - proxying from
%
s:
%
s to
%
s:
%
s
\n
"
%
(
self
.
listen_host
,
self
.
listen_port
,
self
.
target_host
,
self
.
target_port
))
def
poll
(
self
):
# If we are wrapping a command, check it's status
...
...
@@ -158,26 +137,12 @@ Traffic Legend:
"""
Called after a new WebSocket connection has been established.
"""
# Checks if we receive a token, and look
# for a valid target for it then
if
self
.
target_cfg
:
(
self
.
target_host
,
self
.
target_port
)
=
self
.
get_target
(
self
.
target_cfg
,
self
.
path
)
# Connect to the target
if
self
.
wrap_cmd
:
msg
=
"connecting to command:
%
s"
%
(
" "
.
join
(
self
.
wrap_cmd
),
self
.
target_port
)
elif
self
.
unix_target
:
msg
=
"connecting to unix socket:
%
s"
%
self
.
unix_target
else
:
msg
=
"connecting to:
%
s:
%
s"
%
(
self
.
target_host
,
self
.
target_port
)
if
self
.
ssl_target
:
msg
+=
" (using SSL)"
self
.
msg
(
msg
)
self
.
msg
(
"connecting to:
%
s:
%
s"
%
(
self
.
target_host
,
self
.
target_port
))
tsock
=
self
.
socket
(
self
.
target_host
,
self
.
target_port
,
connect
=
True
,
use_ssl
=
self
.
ssl_target
,
unix_socket
=
self
.
unix_target
)
connect
=
True
)
if
self
.
verbose
and
not
self
.
daemon
:
print
(
self
.
traffic_legend
)
...
...
@@ -189,49 +154,10 @@ Traffic Legend:
if
tsock
:
tsock
.
shutdown
(
socket
.
SHUT_RDWR
)
tsock
.
close
()
self
.
vmsg
(
"
%
s:
%
s:
Closed target
"
%
(
self
.
vmsg
(
"
%
s:
%
s:
Target closed
"
%
(
self
.
target_host
,
self
.
target_port
))
raise
def
get_target
(
self
,
target_cfg
,
path
):
"""
Parses the path, extracts a token, and looks for a valid
target for that token in the configuration file(s). Sets
target_host and target_port if successful
"""
# The files in targets contain the lines
# in the form of token: host:port
# Extract the token parameter from url
args
=
parse_qs
(
urlparse
(
path
)[
4
])
# 4 is the query from url
if
not
len
(
args
[
'token'
]):
raise
self
.
EClose
(
"Token not present"
)
token
=
args
[
'token'
][
0
]
.
rstrip
(
'
\n
'
)
# target_cfg can be a single config file or directory of
# config files
if
os
.
path
.
isdir
(
target_cfg
):
cfg_files
=
[
os
.
path
.
join
(
target_cfg
,
f
)
for
f
in
os
.
listdir
(
target_cfg
)]
else
:
cfg_files
=
[
target_cfg
]
targets
=
{}
for
f
in
cfg_files
:
for
line
in
[
l
.
strip
()
for
l
in
file
(
f
)
.
readlines
()]:
if
line
and
not
line
.
startswith
(
'#'
):
ttoken
,
target
=
line
.
split
(
': '
)
targets
[
ttoken
]
=
target
.
strip
()
self
.
vmsg
(
"Target config:
%
s"
%
repr
(
targets
))
if
targets
.
has_key
(
token
):
return
targets
[
token
]
.
split
(
':'
)
else
:
raise
self
.
EClose
(
"Token '
%
s' not found"
%
token
)
def
do_proxy
(
self
,
target
):
"""
Proxy client WebSocket to normal target socket.
...
...
@@ -265,8 +191,6 @@ Traffic Legend:
# Receive target data, encode it and queue for client
buf
=
target
.
recv
(
self
.
buffer_size
)
if
len
(
buf
)
==
0
:
self
.
vmsg
(
"
%
s:
%
s: Target closed connection"
%
(
self
.
target_host
,
self
.
target_port
))
raise
self
.
CClose
(
1000
,
"Target closed"
)
cqueue
.
append
(
buf
)
...
...
@@ -287,13 +211,11 @@ Traffic Legend:
if
closed
:
# TODO: What about blocking on client socket?
self
.
vmsg
(
"
%
s:
%
s: Client closed connection"
%
(
self
.
target_host
,
self
.
target_port
))
raise
self
.
CClose
(
closed
[
'code'
],
closed
[
'reason'
])
def
websockify_init
():
usage
=
"
\n
%
prog [options]"
usage
+=
" [source_addr:]source_port
[target_addr:target_port]
"
usage
+=
" [source_addr:]source_port
target_addr:target_port
"
usage
+=
"
\n
%
prog [options]"
usage
+=
" [source_addr:]source_port -- WRAP_COMMAND_LINE"
parser
=
optparse
.
OptionParser
(
usage
=
usage
)
...
...
@@ -313,29 +235,17 @@ def websockify_init():
parser
.
add_option
(
"--key"
,
default
=
None
,
help
=
"SSL key file (if separate from cert)"
)
parser
.
add_option
(
"--ssl-only"
,
action
=
"store_true"
,
help
=
"disallow non-encrypted client connections"
)
parser
.
add_option
(
"--ssl-target"
,
action
=
"store_true"
,
help
=
"connect to SSL target as SSL client"
)
parser
.
add_option
(
"--unix-target"
,
help
=
"connect to unix socket target"
,
metavar
=
"FILE"
)
help
=
"disallow non-encrypted connections"
)
parser
.
add_option
(
"--web"
,
default
=
None
,
metavar
=
"DIR"
,
help
=
"run webserver on same port. Serve files from DIR."
)
parser
.
add_option
(
"--wrap-mode"
,
default
=
"exit"
,
metavar
=
"MODE"
,
choices
=
[
"exit"
,
"ignore"
,
"respawn"
],
help
=
"action to take when the wrapped program exits "
"or daemonizes: exit (default), ignore, respawn"
)
parser
.
add_option
(
"--prefer-ipv6"
,
"-6"
,
action
=
"store_true"
,
dest
=
"source_is_ipv6"
,
help
=
"prefer IPv6 when resolving source_addr"
)
parser
.
add_option
(
"--target-config"
,
metavar
=
"FILE"
,
dest
=
"target_cfg"
,
help
=
"Configuration file containing valid targets "
"in the form 'token: host:port' or, alternatively, a "
"directory containing configuration files of this form"
)
(
opts
,
args
)
=
parser
.
parse_args
()
# Sanity checks
if
len
(
args
)
<
2
and
not
opts
.
target_cfg
:
if
len
(
args
)
<
2
:
parser
.
error
(
"Too few arguments"
)
if
sys
.
argv
.
count
(
'--'
):
opts
.
wrap_cmd
=
args
[
1
:]
...
...
@@ -344,29 +254,24 @@ def websockify_init():
if
len
(
args
)
>
2
:
parser
.
error
(
"Too many arguments"
)
if
not
websocket
.
ssl
and
opts
.
ssl_target
:
parser
.
error
(
"SSL target requested and Python SSL module not loaded."
);
if
opts
.
ssl_only
and
not
os
.
path
.
exists
(
opts
.
cert
):
parser
.
error
(
"SSL only and
%
s not found"
%
opts
.
cert
)
# Parse host:port and convert ports to numbers
if
args
[
0
]
.
count
(
':'
)
>
0
:
opts
.
listen_host
,
opts
.
listen_port
=
args
[
0
]
.
rsplit
(
':'
,
1
)
opts
.
listen_host
=
opts
.
listen_host
.
strip
(
'[]'
)
else
:
opts
.
listen_host
,
opts
.
listen_port
=
''
,
args
[
0
]
try
:
opts
.
listen_port
=
int
(
opts
.
listen_port
)
except
:
parser
.
error
(
"Error parsing listen port"
)
if
opts
.
wrap_cmd
or
opts
.
unix_target
or
opts
.
target_cfg
:
if
opts
.
wrap_cmd
:
opts
.
target_host
=
None
opts
.
target_port
=
None
else
:
if
args
[
1
]
.
count
(
':'
)
>
0
:
opts
.
target_host
,
opts
.
target_port
=
args
[
1
]
.
rsplit
(
':'
,
1
)
opts
.
target_host
=
opts
.
target_host
.
strip
(
'[]'
)
else
:
parser
.
error
(
"Error parsing target"
)
try
:
opts
.
target_port
=
int
(
opts
.
target_port
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment