Created
July 24, 2012 20:23
-
-
Save testingbot/3172407 to your computer and use it in GitHub Desktop.
websockify.rb with SSL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- a/other/websocket.rb | |
+++ b/other/websocket.rb | |
@@ -13,11 +13,12 @@ require 'stringio' | |
require 'digest/md5' | |
require 'digest/sha1' | |
require 'base64' | |
+require 'openssl' | |
class EClose < Exception | |
end | |
-class WebSocketServer < GServer | |
+class WebSocketServer | |
@@Buffer_size = 65536 | |
# | |
@@ -43,12 +44,28 @@ Sec-WebSocket-Accept: %s\r | |
port = opts['listen_port'] | |
host = opts['listen_host'] || GServer::DEFAULT_HOST | |
- super(port, host) | |
- | |
+ server = TCPServer.new(port) | |
+ sslContext = OpenSSL::SSL::SSLContext.new | |
+ sslContext.cert = OpenSSL::X509::Certificate.new(File.open("/Users/jochen/websockify/other/server.crt")) | |
+ sslContext.key = OpenSSL::PKey::RSA.new(File.open("/Users/jochen/websockify/other/server.key")) | |
+ sslServer = OpenSSL::SSL::SSLServer.new(server, sslContext) | |
+ | |
@@client_id = 0 # Track client number total on class | |
@verbose = opts['verbose'] | |
@opts = opts | |
+ | |
+ | |
+ loop do | |
+ connection = sslServer.accept | |
+ Thread.new { | |
+ begin | |
+ serve(connection) | |
+ rescue | |
+ $stderr.puts $! | |
+ end | |
+ } | |
+ end | |
end | |
def serve(io) | |
@@ -237,7 +254,7 @@ Sec-WebSocket-Accept: %s\r | |
while t[:send_parts].length > 0 | |
buf = t[:send_parts].shift | |
- sent = t[:client].send(buf, 0) | |
+ sent = t[:client].syswrite(buf) | |
if sent == buf.length | |
traffic "<" | |
@@ -257,7 +274,7 @@ Sec-WebSocket-Accept: %s\r | |
closed = false | |
bufs = [] | |
- buf = t[:client].recv(@@Buffer_size) | |
+ buf = t[:client].sysread(@@Buffer_size) | |
if buf.length == 0 | |
return bufs, "Client closed abrubtly" | |
@@ -286,10 +303,10 @@ Sec-WebSocket-Accept: %s\r | |
end | |
end | |
else | |
- if buf[0...2] == "\xff\x00": | |
+ if buf[0...2] == "\xff\x00" | |
closed = "Client sent orderly close frame" | |
break | |
- elsif buf[0...2] == "\x00\xff": | |
+ elsif buf[0...2] == "\x00\xff" | |
buf = buf[2...buf.length] | |
continue # No-op frame | |
elsif buf.count("\xff") == 0 | |
@@ -308,7 +325,7 @@ Sec-WebSocket-Accept: %s\r | |
bufs << frame['payload'] | |
- if frame['left'] > 0: | |
+ if frame['left'] > 0 | |
buf = buf[-frame['left']...buf.length] | |
else | |
buf = '' | |
@@ -328,10 +345,10 @@ Sec-WebSocket-Accept: %s\r | |
end | |
buf, lenh, lent = encode_hybi(msg, opcode=0x08, base64=false) | |
- t[:client].send(buf, 0) | |
+ t[:client].syswrite(buf) | |
elsif t[:version] == "hixie-76" | |
buf = "\xff\x00" | |
- t[:client].send(buf, 0) | |
+ t[:client].syswrite(buf) | |
end | |
end | |
@@ -343,8 +360,16 @@ Sec-WebSocket-Accept: %s\r | |
if !IO.select([sock], nil, nil, 3) | |
raise EClose, "ignoring socket not ready" | |
end | |
+ | |
+ handshake = "" | |
+ while ((lineIn = sock.gets) && !lineIn[0..1].empty?) | |
+ #$stdout.puts "=> " + lineIn | |
+ handshake += lineIn.chomp + "|" | |
+ if lineIn[0..1].chomp.empty? | |
+ break | |
+ end | |
+ end | |
- handshake = sock.recv(1024, Socket::MSG_PEEK) | |
#msg "Handshake [#{handshake.inspect}]" | |
if handshake == "" | |
@@ -353,19 +378,21 @@ Sec-WebSocket-Accept: %s\r | |
stype = "Plain non-SSL (ws://)" | |
scheme = "ws" | |
retsock = sock | |
- sock.recv(1024) | |
+ # sock.sysread(1024) | |
end | |
h = t[:headers] = {} | |
- hlines = handshake.split("\r\n") | |
+ hlines = handshake.split("|") | |
req_split = hlines.shift.match(/^(\w+) (\/[^\s]*) HTTP\/1\.1$/) | |
t[:path] = req_split[2].strip | |
hlines.each do |hline| | |
break if hline == "" | |
hsplit = hline.match(/^([^:]+):\s*(.+)$/) | |
- h[hsplit[1].strip.downcase] = hsplit[2] | |
+ if !hsplit.nil? | |
+ h[hsplit[1].strip.downcase] = hsplit[2] | |
+ end | |
end | |
- #puts "Headers: #{h.inspect}" | |
+ puts "Headers: #{h.inspect}" | |
unless h.has_key?('upgrade') && | |
h['upgrade'].downcase == 'websocket' | |
@@ -445,7 +472,7 @@ Sec-WebSocket-Accept: %s\r | |
if t[:path] then msg "Path: '%s'" % [t[:path]] end | |
#puts "sending reponse #{response.inspect}" | |
- retsock.send(response, 0) | |
+ retsock.syswrite(response) | |
# Return the WebSocket socket which may be SSL wrapped | |
return retsock |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment