lib/em-websocket/handler76.rb in em-websocket-0.1.4 vs lib/em-websocket/handler76.rb in em-websocket-0.2.0
- old
+ new
@@ -1,64 +1,11 @@
-require 'digest/md5'
-
module EventMachine
module WebSocket
class Handler76 < Handler
+ include Handshake76
+ include Framing76
+
# "\377\000" is octet version and "\xff\x00" is hex version
TERMINATE_STRING = "\xff\x00"
-
- def handshake
- challenge_response = solve_challenge(
- @request['Sec-WebSocket-Key1'],
- @request['Sec-WebSocket-Key2'],
- @request['Third-Key']
- )
-
- location = "#{@request['Host'].scheme}://#{@request['Host'].host}"
- location << ":#{@request['Host'].port}" if @request['Host'].port
- location << @request['Path']
-
- upgrade = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
- upgrade << "Upgrade: WebSocket\r\n"
- upgrade << "Connection: Upgrade\r\n"
- upgrade << "Sec-WebSocket-Location: #{location}\r\n"
- upgrade << "Sec-WebSocket-Origin: #{@request['Origin']}\r\n"
- if protocol = @request['Sec-WebSocket-Protocol']
- validate_protocol!(protocol)
- upgrade << "Sec-WebSocket-Protocol: #{protocol}\r\n"
- end
- upgrade << "\r\n"
- upgrade << challenge_response
-
- debug [:upgrade_headers, upgrade]
-
- return upgrade
- end
-
- private
-
- def solve_challenge(first, second, third)
- # Refer to 5.2 4-9 of the draft 76
- sum = [(extract_nums(first) / count_spaces(first))].pack("N*") +
- [(extract_nums(second) / count_spaces(second))].pack("N*") +
- third
- Digest::MD5.digest(sum)
- end
-
- def extract_nums(string)
- string.scan(/[0-9]/).join.to_i
- end
-
- def count_spaces(string)
- spaces = string.scan(/ /).size
- # As per 5.2.5, abort the connection if spaces are zero.
- raise HandshakeError, "Websocket Key1 or Key2 does not contain spaces - this is a symptom of a cross-protocol attack" if spaces == 0
- return spaces
- end
-
- def validate_protocol!(protocol)
- raise HandshakeError, "Invalid WebSocket-Protocol: empty" if protocol.empty?
- # TODO: Validate characters
- end
end
end
end