class WebSocket::Handshake::Server
Construct or parse a server WebSocket
handshake.
@example
handshake = WebSocket::Handshake::Server.new # Parse client request @handshake << <<EOF GET /demo HTTP/1.1\r Upgrade: websocket\r Connection: Upgrade\r Host: example.com\r Origin: http://example.com\r Sec-WebSocket-Version: 13\r Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r \r EOF # All data received? @handshake.finished? # No parsing errors? @handshake.valid? # Create response @handshake.to_s # HTTP/1.1 101 Switching Protocols # Upgrade: websocket # Connection: Upgrade # Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Constants
- PATH
Public Class Methods
Initialize new WebSocket
Server
@param [Hash] args Arguments for server
@option args [Boolean] :secure If true then server will use wss:// protocol @option args [Array<String>] :protocols an array of supported sub-protocols
@example
Websocket::Handshake::Server.new(secure: true)
WebSocket::Handshake::Base::new
# File lib/websocket/handshake/server.rb, line 44 def initialize(args = {}) super @secure ||= false end
Public Instance Methods
Add text of request from Client
. This method will parse content immediately and update version, state and error(if neccessary)
@param [String] data Data to add
@example
@handshake << <<EOF GET /demo HTTP/1.1 Upgrade: websocket Connection: Upgrade Host: example.com Origin: http://example.com Sec-WebSocket-Version: 13 Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== EOF
WebSocket::Handshake::Base#<<
# File lib/websocket/handshake/server.rb, line 64 def <<(data) super set_version if parse_data end
Parse the request from hash @param hash Hash to import data @option hash [Hash] :headers HTTP headers of request, downcased @option hash [String] :path Path for request(without host and query string) @option hash [String] :query Query string for request @option hash [String] :body Body of request(if exists)
@example
@handshake.from_hash(hash)
# File lib/websocket/handshake/server.rb, line 113 def from_hash(hash) @headers = hash[:headers] || {} @path = hash[:path] || '/' @query = hash[:query] || '' @leftovers = hash[:body] set_version @state = :finished end
Parse the request from a rack environment @param env Rack Environment
@example
@handshake.from_rack(env)
# File lib/websocket/handshake/server.rb, line 75 def from_rack(env) @headers = env.select { |key, _value| key.to_s.start_with? 'HTTP_' }.each_with_object({}) do |tuple, memo| key, value = tuple memo[key.gsub(/\AHTTP_/, '').tr('_', '-').downcase] = value end @path = env['REQUEST_PATH'] @query = env['QUERY_STRING'] set_version # Passenger is blocking on read # Unicorn doesn't support readpartial # Maybe someone is providing even plain string? # Better safe than sorry... if @version == 76 input = env['rack.input'] @leftovers = if input.respond_to?(:readpartial) input.readpartial elsif input.respond_to?(:read) input.read else input.to_s end end @state = :finished end
Host of server according to client header @return [String] host
# File lib/websocket/handshake/server.rb, line 131 def host @host || @headers['host'].to_s.split(':')[0].to_s end
Port of server according to client header @return [Integer] port
# File lib/websocket/handshake/server.rb, line 137 def port (@port || @headers['host'].to_s.split(':')[1] || default_port).to_i end
Should send content to client after finished parsing? @return [Boolean] true
# File lib/websocket/handshake/server.rb, line 125 def should_respond? true end
Private Instance Methods
Include set of methods for selected protocol version @return [Boolean] false if protocol number is unknown, otherwise true
# File lib/websocket/handshake/server.rb, line 154 def include_version @handler = case @version when 75 then Handler::Server75.new(self) when 76, 0..3 then Handler::Server76.new(self) when 4..17 then Handler::Server04.new(self) else raise WebSocket::Error::Handshake::UnknownVersion end end
Parse first line of Client
response. @param [String] line Line to parse @return [Boolean] True if parsed correctly. False otherwise
# File lib/websocket/handshake/server.rb, line 168 def parse_first_line(line) line_parts = line.match(PATH) raise WebSocket::Error::Handshake::InvalidHeader unless line_parts method = line_parts[1].strip raise WebSocket::Error::Handshake::GetRequestRequired unless method == 'GET' resource_name = line_parts[2].strip @path, @query = resource_name.split('?', 2) end
Set version of protocol basing on client requets. AFter cotting method calls include_version.
# File lib/websocket/handshake/server.rb, line 144 def set_version @version = @headers['sec-websocket-version'].to_i if @headers['sec-websocket-version'] @version ||= @headers['sec-websocket-draft'].to_i if @headers['sec-websocket-draft'] @version ||= 76 if @headers['sec-websocket-key1'] @version ||= 75 include_version end