Class: UnXF
- Inherits:
-
Object
- Object
- UnXF
- Defined in:
- lib/unxf.rb
Overview
Rack middleware to remove “HTTP_X_FORWARDED_FOR” in the Rack environment and replace “REMOTE_ADDR” with the value of the original client address.
Constant Summary collapse
- REMOTE_ADDR =
:stopdoc: reduce garbage overhead by using constant strings
"REMOTE_ADDR".freeze
- HTTP_X_FORWARDED_FOR =
"HTTP_X_FORWARDED_FOR"
- HTTP_X_FORWARDED_PROTO =
"HTTP_X_FORWARDED_PROTO"
- RACK_URL_SCHEME =
"rack.url_scheme".freeze
- UNXF_FOR =
"unxf.for".freeze
- UNXF_PROTO =
"unxf.proto".freeze
- HTTPS =
"https"
- RFC_1918 =
local LAN addresses described in RFC 1918
%w(10.0.0.0/8 172.16.0.0/12 192.168.0.0/16)
- LOCALHOST =
IPv4 localhost addresses (127.0.0.0/8)
%w(127.0.0.0/8)
- LOCALHOST6 =
IPv6 localhost address (::1/128)
%w(::1/128)
Instance Method Summary collapse
-
#call(env) ⇒ Object
Rack entry point.
-
#initialize(app, trusted = [:RFC_1918, :LOCALHOST, :LOCALHOST6]) ⇒ UnXF
constructor
In your Rack config.ru:.
-
#on_broken_addr(env, xff_str) ⇒ Object
Our default action on a broken address is to just fall back to calling the app without modifying the env.
-
#on_untrusted_addr(env, xff_str) ⇒ Object
Our default action on an untrusted address is to just fall back to calling the app without modifying the env.
-
#unxf!(env) ⇒ Object
returns
nil
on success and a Rack response triplet on failure This allows existing applications to use UnXF without putting it into the middleware stack (to avoid increasing stack depth and GC time).
Constructor Details
#initialize(app, trusted = [:RFC_1918, :LOCALHOST, :LOCALHOST6]) ⇒ UnXF
40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/unxf.rb', line 40 def initialize(app, trusted = [:RFC_1918, :LOCALHOST, :LOCALHOST6]) @app = app @trusted = Patricia.new @trusted6 = Patricia.new(:AF_INET6) Array(trusted).each do |mask| mask = UnXF.const_get(mask) if Symbol === mask Array(mask).each do |prefix| (/:/ =~ prefix ? @trusted6 : @trusted).add(prefix, true) end end end |
Instance Method Details
#call(env) ⇒ Object
Rack entry point
53 54 55 |
# File 'lib/unxf.rb', line 53 def call(env) # :nodoc: unxf!(env) || @app.call(env) end |
#on_broken_addr(env, xff_str) ⇒ Object
Our default action on a broken address is to just fall back to calling the app without modifying the env
91 92 93 |
# File 'lib/unxf.rb', line 91 def on_broken_addr(env, xff_str) @app.call(env) end |
#on_untrusted_addr(env, xff_str) ⇒ Object
Our default action on an untrusted address is to just fall back to calling the app without modifying the env
97 98 99 |
# File 'lib/unxf.rb', line 97 def on_untrusted_addr(env, xff_str) @app.call(env) end |
#unxf!(env) ⇒ Object
returns nil
on success and a Rack response triplet on failure This allows existing applications to use UnXF without putting it into the middleware stack (to avoid increasing stack depth and GC time)
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/unxf.rb', line 60 def unxf!(env) if xff_str = env.delete(HTTP_X_FORWARDED_FOR) env[UNXF_FOR] = xff_str xff = xff_str.split(/\s*,\s*/) addr = env[REMOTE_ADDR] begin while (/:/ =~ addr ? @trusted6 : @trusted).include?(addr) && tmp = xff.pop addr = tmp end rescue ArgumentError return on_broken_addr(env, xff_str) end # it's stupid to have https at any point other than the first # proxy in the chain, so we don't support that if xff.empty? env[REMOTE_ADDR] = addr if xfp = env.delete(HTTP_X_FORWARDED_PROTO) env[UNXF_PROTO] = xfp /\Ahttps\b/ =~ xfp and env[RACK_URL_SCHEME] = HTTPS end else return on_untrusted_addr(env, xff_str) end end nil end |