lib/thin_extensions.rb in faye-0.6.3 vs lib/thin_extensions.rb in faye-0.6.4

- old
+ new

@@ -1,10 +1,10 @@ # WebSocket extensions for Thin # Based on code from the Cramp project # http://github.com/lifo/cramp -# Copyright (c) 2009-2010 Pratik Naik +# Copyright (c) 2009-2011 Pratik Naik # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, @@ -21,12 +21,10 @@ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -require 'digest/md5' - class Thin::Connection def receive_data(data) trace { data } case @serving @@ -53,11 +51,13 @@ class Thin::Request WEBSOCKET_RECEIVE_CALLBACK = 'websocket.receive_callback'.freeze def websocket? - @env['HTTP_CONNECTION'] == 'Upgrade' && @env['HTTP_UPGRADE'] == 'WebSocket' + @env['HTTP_CONNECTION'] and + @env['HTTP_CONNECTION'].split(/\s*,\s*/).include?('Upgrade') and + ['WebSocket', 'websocket'].include?(@env['HTTP_UPGRADE']) end def secure_websocket? if @env.has_key?('HTTP_X_FORWARDED_PROTO') @env['HTTP_X_FORWARDED_PROTO'] == 'https' @@ -66,76 +66,15 @@ end end def websocket_url scheme = secure_websocket? ? 'wss:' : 'ws:' - @env['websocket.url'] = "#{ scheme }//#{ @env['HTTP_HOST'] }#{ @env['REQUEST_PATH'] }" + @env['websocket.url'] = "#{ scheme }//#{ @env['HTTP_HOST'] }#{ @env['REQUEST_URI'] }" end def websocket_upgrade_data - handler = if @env['HTTP_SEC_WEBSOCKET_KEY1'] and @env['HTTP_SEC_WEBSOCKET_KEY2'] - Protocol76 - else - Protocol75 - end - handler.new(self).handshake - end - - class WebSocketHandler - def initialize(request) - @request = request - end - end - - class Protocol75 < WebSocketHandler - def handshake - upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" - upgrade << "Upgrade: WebSocket\r\n" - upgrade << "Connection: Upgrade\r\n" - upgrade << "WebSocket-Origin: #{@request.env['HTTP_ORIGIN']}\r\n" - upgrade << "WebSocket-Location: #{@request.websocket_url}\r\n\r\n" - upgrade - end - end - - class Protocol76 < WebSocketHandler - def handshake - key1 = @request.env['HTTP_SEC_WEBSOCKET_KEY1'] - value1 = number_from_key(key1) / spaces_in_key(key1) - - key2 = @request.env['HTTP_SEC_WEBSOCKET_KEY2'] - value2 = number_from_key(key2) / spaces_in_key(key2) - - hash = Digest::MD5.digest(big_endian(value1) + - big_endian(value2) + - @request.body.read) - - upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" - upgrade << "Upgrade: WebSocket\r\n" - upgrade << "Connection: Upgrade\r\n" - upgrade << "Sec-WebSocket-Origin: #{@request.env['HTTP_ORIGIN']}\r\n" - upgrade << "Sec-WebSocket-Location: #{@request.websocket_url}\r\n\r\n" - upgrade << hash - upgrade - end - - private - - def number_from_key(key) - key.scan(/[0-9]/).join('').to_i(10) - end - - def spaces_in_key(key) - key.scan(/ /).size - end - - def big_endian(number) - string = '' - [24,16,8,0].each do |offset| - string << (number >> offset & 0xFF).chr - end - string - end + parser = Faye::WebSocket.parser(self) + parser.handshake(self) end end class Thin::Response # Headers for sending Websocket upgrade