aboutsummaryrefslogtreecommitdiffstats
path: root/actioncable/lib/action_cable/connection/client_socket.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actioncable/lib/action_cable/connection/client_socket.rb')
-rw-r--r--actioncable/lib/action_cable/connection/client_socket.rb61
1 files changed, 33 insertions, 28 deletions
diff --git a/actioncable/lib/action_cable/connection/client_socket.rb b/actioncable/lib/action_cable/connection/client_socket.rb
index ef937d7c16..70a2bbecb1 100644
--- a/actioncable/lib/action_cable/connection/client_socket.rb
+++ b/actioncable/lib/action_cable/connection/client_socket.rb
@@ -1,4 +1,4 @@
-require 'websocket/driver'
+require "websocket/driver"
module ActionCable
module Connection
@@ -8,16 +8,16 @@ module ActionCable
# Copyright (c) 2010-2015 James Coglan
class ClientSocket # :nodoc:
def self.determine_url(env)
- scheme = secure_request?(env) ? 'wss:' : 'ws:'
+ scheme = secure_request?(env) ? "wss:" : "ws:"
"#{ scheme }//#{ env['HTTP_HOST'] }#{ env['REQUEST_URI'] }"
end
def self.secure_request?(env)
- return true if env['HTTPS'] == 'on'
- return true if env['HTTP_X_FORWARDED_SSL'] == 'on'
- return true if env['HTTP_X_FORWARDED_SCHEME'] == 'https'
- return true if env['HTTP_X_FORWARDED_PROTO'] == 'https'
- return true if env['rack.url_scheme'] == 'https'
+ return true if env["HTTPS"] == "on"
+ return true if env["HTTP_X_FORWARDED_SSL"] == "on"
+ return true if env["HTTP_X_FORWARDED_SCHEME"] == "https"
+ return true if env["HTTP_X_FORWARDED_PROTO"] == "https"
+ return true if env["rack.url_scheme"] == "https"
return false
end
@@ -29,35 +29,37 @@ module ActionCable
attr_reader :env, :url
- def initialize(env, event_target, stream_event_loop)
- @env = env
- @event_target = event_target
- @stream_event_loop = stream_event_loop
+ def initialize(env, event_target, event_loop, protocols)
+ @env = env
+ @event_target = event_target
+ @event_loop = event_loop
@url = ClientSocket.determine_url(@env)
@driver = @driver_started = nil
- @close_params = ['', 1006]
+ @close_params = ["", 1006]
@ready_state = CONNECTING
# The driver calls +env+, +url+, and +write+
- @driver = ::WebSocket::Driver.rack(self)
+ @driver = ::WebSocket::Driver.rack(self, protocols: protocols)
@driver.on(:open) { |e| open }
@driver.on(:message) { |e| receive_message(e.data) }
@driver.on(:close) { |e| begin_close(e.reason, e.code) }
@driver.on(:error) { |e| emit_error(e.message) }
- @stream = ActionCable::Connection::Stream.new(@stream_event_loop, self)
-
- if callback = @env['async.callback']
- callback.call([101, {}, @stream])
- end
+ @stream = ActionCable::Connection::Stream.new(@event_loop, self)
end
def start_driver
return if @driver.nil? || @driver_started
+ @stream.hijack_rack_socket
+
+ if callback = @env["async.callback"]
+ callback.call([101, {}, @stream])
+ end
+
@driver_started = true
@driver.start
end
@@ -69,23 +71,25 @@ module ActionCable
def write(data)
@stream.write(data)
+ rescue => e
+ emit_error e.message
end
def transmit(message)
return false if @ready_state > OPEN
case message
- when Numeric then @driver.text(message.to_s)
- when String then @driver.text(message)
- when Array then @driver.binary(message)
+ when Numeric then @driver.text(message.to_s)
+ when String then @driver.text(message)
+ when Array then @driver.binary(message)
else false
end
end
def close(code = nil, reason = nil)
code ||= 1000
- reason ||= ''
+ reason ||= ""
- unless code == 1000 or (code >= 3000 and code <= 4999)
+ unless code == 1000 || (code >= 3000 && code <= 4999)
raise ArgumentError, "Failed to execute 'close' on WebSocket: " +
"The code must be either 1000, or between 3000 and 4999. " +
"#{code} is neither."
@@ -107,6 +111,10 @@ module ActionCable
@ready_state == OPEN
end
+ def protocol
+ @driver.protocol
+ end
+
private
def open
return unless @ready_state == CONNECTING
@@ -132,11 +140,8 @@ module ActionCable
@ready_state = CLOSING
@close_params = [reason, code]
- if @stream
- @stream.shutdown
- else
- finalize_close
- end
+ @stream.shutdown if @stream
+ finalize_close
end
def finalize_close