Class: WebSocket::Driver::Client

Inherits:
Hybi show all
Defined in:
lib/websocket/driver/client.rb

Constant Summary collapse

VALID_SCHEMES =
%w[ws wss]

Constants inherited from Hybi

Hybi::BYTE, Hybi::DEFAULT_ERROR_CODE, Hybi::ERRORS, Hybi::ERROR_CODES, Hybi::FIN, Hybi::GUID, Hybi::LENGTH, Hybi::MAX_RESERVED_ERROR, Hybi::MESSAGE_OPCODES, Hybi::MIN_RESERVED_ERROR, Hybi::OPCODE, Hybi::OPCODES, Hybi::OPCODE_CODES, Hybi::OPENING_OPCODES, Hybi::PACK_FORMATS, Hybi::RSV1, Hybi::RSV2, Hybi::RSV3, Hybi::VERSION

Constants inherited from WebSocket::Driver

ConfigurationError, MAX_LENGTH, ProtocolError, STATES, URIError

Instance Attribute Summary collapse

Attributes inherited from WebSocket::Driver

#protocol, #ready_state

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Hybi

#add_extension, #binary, #close, #frame, generate_accept, #ping, #pong

Methods inherited from WebSocket::Driver

#add_extension, #binary, #close, #ping, #pong, #set_header, #state, #text

Methods included from EventEmitter

#add_listener, #emit, #listener_count, #listeners, #on, #remove_all_listeners, #remove_listener

Constructor Details

#initialize(socket, options = {}) ⇒ Client

Returns a new instance of Client.


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/websocket/driver/client.rb', line 13

def initialize(socket, options = {})
  super

  @ready_state = -1
  @key         = Client.generate_key
  @accept      = Hybi.generate_accept(@key)
  @http        = HTTP::Response.new

  uri = URI.parse(@socket.url)
  unless VALID_SCHEMES.include?(uri.scheme)
    raise URIError, "#{ socket.url } is not a valid WebSocket URL"
  end

  host      = uri.host + (uri.port ? ":#{ uri.port }" : '')
  path      = (uri.path == '') ? '/' : uri.path
  @pathname = path + (uri.query ? '?' + uri.query : '')

  @headers['Host']                  = host
  @headers['Upgrade']               = 'websocket'
  @headers['Connection']            = 'Upgrade'
  @headers['Sec-WebSocket-Key']     = @key
  @headers['Sec-WebSocket-Version'] = VERSION

  if @protocols.size > 0
    @headers['Sec-WebSocket-Protocol'] = @protocols * ', '
  end

  if uri.user
    auth = Base64.strict_encode64([uri.user, uri.password] * ':')
    @headers['Authorization'] = 'Basic ' + auth
  end
end

Instance Attribute Details

#headersObject (readonly)

Returns the value of attribute headers


11
12
13
# File 'lib/websocket/driver/client.rb', line 11

def headers
  @headers
end

#statusObject (readonly)

Returns the value of attribute status


11
12
13
# File 'lib/websocket/driver/client.rb', line 11

def status
  @status
end

Class Method Details

.generate_keyObject


7
8
9
# File 'lib/websocket/driver/client.rb', line 7

def self.generate_key
  Base64.strict_encode64(SecureRandom.random_bytes(16))
end

Instance Method Details

#parse(chunk) ⇒ Object


61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/websocket/driver/client.rb', line 61

def parse(chunk)
  return if @ready_state == 3
  return super if @ready_state > 0

  @http.parse(chunk)
  return fail_handshake('Invalid HTTP response') if @http.error?
  return unless @http.complete?

  validate_handshake
  return if @ready_state == 3

  open
  parse(@http.body)
end

#proxy(origin, options = {}) ⇒ Object


50
51
52
# File 'lib/websocket/driver/client.rb', line 50

def proxy(origin, options = {})
  Proxy.new(self, origin, options)
end

#startObject


54
55
56
57
58
59
# File 'lib/websocket/driver/client.rb', line 54

def start
  return false unless @ready_state == -1
  @socket.write(handshake_request)
  @ready_state = 0
  true
end

#versionObject


46
47
48
# File 'lib/websocket/driver/client.rb', line 46

def version
  "hybi-#{ VERSION }"
end