lib/anycable/rails/actioncable/connection.rb in anycable-rails-0.5.5 vs lib/anycable/rails/actioncable/connection.rb in anycable-rails-0.6.0.rc1
- old
+ new
@@ -4,14 +4,18 @@
require "anycable/rails/refinements/subscriptions"
require "anycable/rails/actioncable/channel"
module ActionCable
module Connection
- # rubocop:disable Metrics/ClassLength
+ # rubocop: disable Metrics/ClassLength
class Base # :nodoc:
- using Anycable::Refinements::Subscriptions
+ # We store logger tags in identifiers to be able
+ # to re-use them in the subsequent calls
+ LOG_TAGS_IDENTIFIER = "__ltags__"
+ using AnyCable::Refinements::Subscriptions
+
attr_reader :socket
class << self
def call(socket, **options)
new(socket, options)
@@ -25,13 +29,15 @@
end
end
end
end
- def initialize(socket, identifiers: '{}', subscriptions: [])
+ def initialize(socket, identifiers: "{}", subscriptions: [])
@ids = ActiveSupport::JSON.decode(identifiers)
+ @ltags = ids.delete(LOG_TAGS_IDENTIFIER)
+
@cached_ids = {}
@env = socket.env
@coder = ActiveSupport::JSON
@socket = socket
@subscriptions = ActionCable::Connection::Subscriptions.new(self)
@@ -41,15 +47,16 @@
end
def handle_open
logger.info started_request_message if access_logs?
+ verify_origin!
+
connect if respond_to?(:connect)
send_welcome_message
rescue ActionCable::Connection::Authorization::UnauthorizedError
- logger.info finished_request_message('Rejected') if access_logs?
- close
+ reject_request
end
def handle_close
logger.info finished_request_message if access_logs?
@@ -86,58 +93,85 @@
end
# Generate identifiers info.
# Converts GlobalID compatible vars to corresponding global IDs params.
def identifiers_hash
- identifiers.each_with_object({}) do |id, acc|
+ obj = { LOG_TAGS_IDENTIFIER => fetch_ltags }
+
+ identifiers.each_with_object(obj) do |id, acc|
obj = instance_variable_get("@#{id}")
next unless obj
acc[id] = obj.try(:to_gid_param) || obj
- end
+ end.compact
end
def identifiers_json
identifiers_hash.to_json
end
# Fetch identifier and deserialize if neccessary
def fetch_identifier(name)
@cached_ids[name] ||= @cached_ids.fetch(name) do
- val = @ids[name.to_s]
+ val = ids[name.to_s]
next val unless val.is_a?(String)
GlobalID::Locator.locate(val) || val
end
end
def logger
- Anycable.logger
+ @logger ||= TaggedLoggerProxy.new(AnyCable.logger, tags: ltags || [])
end
private
+ attr_reader :ids, :ltags
+
def started_request_message
- 'Started "%s"%s for %s at %s' % [
- request.filtered_path,
- " [Anycable]",
- request.ip,
- Time.now.to_s
- ]
+ format(
+ 'Started "%s"%s for %s at %s',
+ request.filtered_path, " [AnyCable]", request.ip, Time.now.to_s
+ )
end
def finished_request_message(reason = "Closed")
- 'Finished "%s"%s for %s at %s (%s)' % [
- request.filtered_path,
- " [Anycable]",
- request.ip,
- Time.now.to_s,
- reason
- ]
+ format(
+ 'Finished "%s"%s for %s at %s (%s)',
+ request.filtered_path, " [AnyCable]", request.ip, Time.now.to_s, reason
+ )
end
def access_logs?
- Anycable.config.access_logs_disabled == false
+ AnyCable.config.access_logs_disabled == false
+ end
+
+ def fetch_ltags
+ if instance_variable_defined?(:@logger)
+ logger.tags
+ else
+ ltags
+ end
+ end
+
+ def server
+ ActionCable.server
+ end
+
+ def verify_origin!
+ return unless socket.env.key?("HTTP_ORIGIN")
+
+ return if allow_request_origin?
+
+ raise(
+ ActionCable::Connection::Authorization::UnauthorizedError,
+ "Origin is not allowed"
+ )
+ end
+
+ def reject_request
+ logger.info finished_request_message("Rejected") if access_logs?
+ close
end
end
# rubocop:enable Metrics/ClassLength
end
end