Skip to content

Instantly share code, notes, and snippets.

@ShawnHuang
Forked from suxue/WebSocketServer.sh
Created August 16, 2018 01:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ShawnHuang/9f52e1399fd37d31350de946466f22df to your computer and use it in GitHub Desktop.
Save ShawnHuang/9f52e1399fd37d31350de946466f22df to your computer and use it in GitHub Desktop.
simple WebSocket Server make use of netcat
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 3714
Date: Sun, 16 Mar 2014 11:24:33 GMT
Server: lighttpd/1.4.30
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<script type="text/javascript">
sock=new WebSocket("ws://lfs7:WEB_SOCKET_PORT")
sock.onmessage = function (event) {
document.write(event.data);
}
</script>
</head>
<body>
</body>
</html>
#!/bin/ksh
typeset port=$((RANDOM % 60000))
while ((port < 30000)); do
port=$((RANDOM % 60000))
done
typeset pipe=`mktemp -u`
mkfifo $pipe
trap "rm -f $pipe" INT
cat test.html | m4 -DWEB_SOCKET_PORT=$port | nc -l localhost $((port+1)) >/dev/null &
sleep 2 && firefox http://localhost:$((port+1)) &
typeset data={}
function Dec2Hex {
typeset num=`echo 'obase=16; ibase=10; '"$1" | bc`
if ((${#num} == 1)); then
num=0"$num"
fi
printf "0x%s" $num
}
# see RFC6455 "Base Framing Protocol"
function send_encoded_frame {
typeset data="$1"
# 1st nible: 0x8 -> the final frame
# 2nd bible: 0x1 -> textual frame
typeset first_byte="0x81"
typeset payload_length=${#data}
typeset second_byte=`Dec2Hex $payload_length` # no mask
printf "%s%s" $first_byte $second_byte | xxd -r -p
printf "%s" "$data"
}
function response {
echo "${data.key}" >x
outkey=`printf %s "${data.key}" | dos2unix`
outkey+="258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
#outkey=`printf %s "$outkey" | sha1sum | cut -d ' ' -f 1 | xxd -r -p | base64`
outkey=`printf %s "$outkey" | openssl dgst -binary -sha1 | openssl base64`
printf "HTTP/1.1 101 Switching Protocols\r\n"
printf "Upgrade: websocket\r\n"
printf "Connection: Upgrade\r\n"
printf "Sec-WebSocket-Accept: %s\r\n" "$outkey"
printf "\r\n"
# data frame
send_encoded_frame "From WebSocket: hello world"
}
function get_arg {
echo "$1" | cut -d' ' -f 2
}
function handshake {
typeset line="$1"
if printf %s "$line" | grep -q $'^\r$'; then
echo "handshake completed" >&2
response
else
case "$line" in
User-Agent*)
data.agent=`get_arg "$line"`
;;
Sec-WebSocket-Key*)
data.key=`get_arg "$line"`
;;
Origin*)
data.origin=`get_arg "$line"`
;;
esac
fi
}
function server {
echo "server listening on $port" >&2
typeset line
cat $pipe | nc -l localhost "$port" | while read line; do
handshake "$line"
done
}
function loopback {
cat - > $pipe
}
server | loopback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment