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, PORTS, 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
# 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

  path      = (uri.path == '') ? '/' : uri.path
  @pathname = path + (uri.query ? '?' + uri.query : '')

  @headers['Host']                  = Driver.host_header(uri)
  @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



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

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



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

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

#startObject



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

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

#versionObject



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

def version
  "hybi-#{ VERSION }"
end