I've a rails app and I'm trying to overload the request.remote_ip and request.ip in order to use the cloudflare header (HTTP_CF_CONNECTING_IP) if it's present... I've tried these, but none of them work:
module Rack
class Request
class << self
def ip
@ip ||= (@env['HTTP_CF_CONNECTING_IP'] || super)
end
end
end
end
module ActionDispatch
class Request < Rack::Request
class << self
def remote_ip
@remote_ip ||= (@env['HTTP_CF_CONNECTING_IP'] || super)
end
end
end
end
I can't use an extra method like
def connecting_ip
@env['HTTP_CF_CONNECTING_IP'] || request.remote_ip
end
in the application_controller because I've some other gems (like devise) which use request.ip
Thank you!
I believe request
is an instance. But you are defining class methods. Remove the class << self
nonsense and you instead be redefining instance methods.
Just a note though, this sounds kind of crazy. Be careful in there. Frameworks dont always like having their guts rearranged.
Your error message when using instance methods means something else is going on. super
calls the superclass implementation. But when you reopen a class and override things, you are literally overwriting the original implementation. Since the method doesn't exist in the superclass, super
doesn't work.
Instead you can use alias
to save the original implementation before you declare the new method that would replace it.
module ActionDispatch
class Request < Rack::Request
alias :remote_ip_orig :remote_ip
def remote_ip
@remote_ip ||= (@env['HTTP_CF_CONNECTING_IP'] || remote_ip_orig)
end
end
end