mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
5ac6ec54a6
### Summary This PR changes .rubocop.yml. Regarding the code using `if ... else ... end`, I think the coding style that Rails expects is as follows. ```ruby var = if cond a else b end ``` However, the current .rubocop.yml setting does not offense for the following code. ```ruby var = if cond a else b end ``` I think that the above code expects offense to be warned. Moreover, the layout by autocorrect is unnatural. ```ruby var = if cond a else b end ``` This PR adds a setting to .rubocop.yml to make an offense warning and autocorrect as expected by the coding style. And this change also fixes `case ... when ... end` together. Also this PR itself is an example that arranges the layout using `rubocop -a`. ### Other Information Autocorrect of `Lint/EndAlignment` cop is `false` by default. https://github.com/bbatsov/rubocop/blob/v0.51.0/config/default.yml#L1443 This PR changes this value to `true`. Also this PR has changed it together as it is necessary to enable `Layout/ElseAlignment` cop to make this behavior.
157 lines
3.9 KiB
Ruby
157 lines
3.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "websocket/driver"
|
|
|
|
module ActionCable
|
|
module Connection
|
|
#--
|
|
# This class is heavily based on faye-websocket-ruby
|
|
#
|
|
# Copyright (c) 2010-2015 James Coglan
|
|
class ClientSocket # :nodoc:
|
|
def self.determine_url(env)
|
|
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"
|
|
|
|
false
|
|
end
|
|
|
|
CONNECTING = 0
|
|
OPEN = 1
|
|
CLOSING = 2
|
|
CLOSED = 3
|
|
|
|
attr_reader :env, :url
|
|
|
|
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]
|
|
|
|
@ready_state = CONNECTING
|
|
|
|
# The driver calls +env+, +url+, and +write+
|
|
@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(@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
|
|
|
|
def rack_response
|
|
start_driver
|
|
[ -1, {}, [] ]
|
|
end
|
|
|
|
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)
|
|
else false
|
|
end
|
|
end
|
|
|
|
def close(code = nil, reason = nil)
|
|
code ||= 1000
|
|
reason ||= ""
|
|
|
|
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."
|
|
end
|
|
|
|
@ready_state = CLOSING unless @ready_state == CLOSED
|
|
@driver.close(reason, code)
|
|
end
|
|
|
|
def parse(data)
|
|
@driver.parse(data)
|
|
end
|
|
|
|
def client_gone
|
|
finalize_close
|
|
end
|
|
|
|
def alive?
|
|
@ready_state == OPEN
|
|
end
|
|
|
|
def protocol
|
|
@driver.protocol
|
|
end
|
|
|
|
private
|
|
def open
|
|
return unless @ready_state == CONNECTING
|
|
@ready_state = OPEN
|
|
|
|
@event_target.on_open
|
|
end
|
|
|
|
def receive_message(data)
|
|
return unless @ready_state == OPEN
|
|
|
|
@event_target.on_message(data)
|
|
end
|
|
|
|
def emit_error(message)
|
|
return if @ready_state >= CLOSING
|
|
|
|
@event_target.on_error(message)
|
|
end
|
|
|
|
def begin_close(reason, code)
|
|
return if @ready_state == CLOSED
|
|
@ready_state = CLOSING
|
|
@close_params = [reason, code]
|
|
|
|
@stream.shutdown if @stream
|
|
finalize_close
|
|
end
|
|
|
|
def finalize_close
|
|
return if @ready_state == CLOSED
|
|
@ready_state = CLOSED
|
|
|
|
@event_target.on_close(*@close_params)
|
|
end
|
|
end
|
|
end
|
|
end
|