Class: Rack::Cloudflare::Headers
- Inherits:
-
Object
- Object
- Rack::Cloudflare::Headers
- Defined in:
- lib/rack/cloudflare/headers.rb
Constant Summary collapse
- NAMES =
%w[ HTTP_CF_IPCOUNTRY HTTP_CF_CONNECTING_IP HTTP_CF_RAY HTTP_CF_VISITOR ].freeze
- STANDARD =
%w[ HTTP_X_FORWARDED_FOR HTTP_X_FORWARDED_PROTO REMOTE_ADDR ].freeze
- ALL =
(NAMES + STANDARD).freeze
Class Attribute Summary collapse
-
.backup ⇒ Object
Returns the value of attribute backup.
-
.original_forwarded_for ⇒ Object
Returns the value of attribute original_forwarded_for.
-
.original_remote_addr ⇒ Object
Returns the value of attribute original_remote_addr.
Class Method Summary collapse
Instance Method Summary collapse
- #backup_headers ⇒ Object
-
#connecting_ip ⇒ Object
“CF-Connecting-IP: A.B.C.D”.
-
#forwarded_for ⇒ Object
“X-Forwarded-For: A.B.C.D” “X-Forwarded-For: A.B.C.D”.
-
#forwarded_proto ⇒ Object
“X-Forwarded-Proto: https”.
- #has?(header) ⇒ Boolean
-
#initialize(headers) ⇒ Headers
constructor
A new instance of Headers.
-
#ip_country ⇒ Object
“Cf-Ipcountry: US”.
-
#ray ⇒ Object
“Cf-Ray: 230b030023ae2822-SJC”.
- #remote_addr ⇒ Object
- #rewrite ⇒ Object
- #rewritten_headers ⇒ Object
- #rewritten_target_headers ⇒ Object
-
#target_headers ⇒ Object
Headers that relate to Cloudflare See: support.cloudflare.com/hc/en-us/articles/200170986-How-does-Cloudflare-handle-HTTP-Request-headers-.
-
#trusted? ⇒ Boolean
Indicates if the headers passed through Cloudflare.
-
#visitor ⇒ Object
“Cf-Visitor: { "scheme":"https"}”.
Constructor Details
#initialize(headers) ⇒ Headers
Returns a new instance of Headers.
39 40 41 |
# File 'lib/rack/cloudflare/headers.rb', line 39 def initialize(headers) @headers = headers end |
Class Attribute Details
.backup ⇒ Object
Returns the value of attribute backup.
28 29 30 |
# File 'lib/rack/cloudflare/headers.rb', line 28 def backup @backup end |
.original_forwarded_for ⇒ Object
Returns the value of attribute original_forwarded_for.
28 29 30 |
# File 'lib/rack/cloudflare/headers.rb', line 28 def original_forwarded_for @original_forwarded_for end |
.original_remote_addr ⇒ Object
Returns the value of attribute original_remote_addr.
28 29 30 |
# File 'lib/rack/cloudflare/headers.rb', line 28 def original_remote_addr @original_remote_addr end |
Class Method Details
Instance Method Details
#backup_headers ⇒ Object
84 85 86 87 88 89 90 91 |
# File 'lib/rack/cloudflare/headers.rb', line 84 def backup_headers return {} unless Headers.backup {}.tap do |headers| headers[Headers.original_remote_addr] = @headers[REMOTE_ADDR] headers[Headers.original_forwarded_for] = @headers[HTTP_X_FORWARDED_FOR] end end |
#connecting_ip ⇒ Object
“CF-Connecting-IP: A.B.C.D”
49 50 51 |
# File 'lib/rack/cloudflare/headers.rb', line 49 def connecting_ip @connecting_ip ||= IPs.parse(@headers[HTTP_CF_CONNECTING_IP]).first end |
#forwarded_for ⇒ Object
“X-Forwarded-For: A.B.C.D” “X-Forwarded-For: A.B.C.D”
55 56 57 |
# File 'lib/rack/cloudflare/headers.rb', line 55 def forwarded_for @forwarded_for ||= IPs.parse(@headers[HTTP_X_FORWARDED_FOR]) end |
#forwarded_proto ⇒ Object
“X-Forwarded-Proto: https”
60 61 62 |
# File 'lib/rack/cloudflare/headers.rb', line 60 def forwarded_proto @headers[HTTP_X_FORWARDED_PROTO] end |
#has?(header) ⇒ Boolean
126 127 128 |
# File 'lib/rack/cloudflare/headers.rb', line 126 def has?(header) @headers.key?(header) end |
#ip_country ⇒ Object
“Cf-Ipcountry: US”
44 45 46 |
# File 'lib/rack/cloudflare/headers.rb', line 44 def ip_country @headers.fetch(HTTP_CF_IPCOUNTRY, 'XX') end |
#ray ⇒ Object
“Cf-Ray: 230b030023ae2822-SJC”
65 66 67 |
# File 'lib/rack/cloudflare/headers.rb', line 65 def ray @headers[HTTP_CF_RAY] end |
#remote_addr ⇒ Object
75 76 77 |
# File 'lib/rack/cloudflare/headers.rb', line 75 def remote_addr @remote_addr ||= IPs.parse(@headers[REMOTE_ADDR]).first end |
#rewrite ⇒ Object
122 123 124 |
# File 'lib/rack/cloudflare/headers.rb', line 122 def rewrite @headers.merge(rewritten_headers) end |
#rewritten_headers ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/rack/cloudflare/headers.rb', line 93 def rewritten_headers # Only rewrites headers if it's a Cloudflare request return {} unless trusted? {}.tap do |headers| headers.merge! backup_headers # Overwrite the original remote IP based on # Cloudflare's specified original remote IP headers[REMOTE_ADDR] = connecting_ip.to_s if connecting_ip # Add HTTP_X_FORWARDED_FOR if it wasn't present. # Cloudflare will already have modified the header if # it was present in the original request. # See: https://support.cloudflare.com/hc/en-us/articles/200170986-How-does-Cloudflare-handle-HTTP-Request-headers- headers[HTTP_X_FORWARDED_FOR] = "#{connecting_ip}, #{remote_addr}" if forwarded_for.none? end end |
#rewritten_target_headers ⇒ Object
118 119 120 |
# File 'lib/rack/cloudflare/headers.rb', line 118 def rewritten_target_headers target_headers.merge(rewritten_headers) end |
#target_headers ⇒ Object
Headers that relate to Cloudflare See: support.cloudflare.com/hc/en-us/articles/200170986-How-does-Cloudflare-handle-HTTP-Request-headers-
114 115 116 |
# File 'lib/rack/cloudflare/headers.rb', line 114 def target_headers @headers.select { |k, _| ALL.include? k } end |
#trusted? ⇒ Boolean
Indicates if the headers passed through Cloudflare
80 81 82 |
# File 'lib/rack/cloudflare/headers.rb', line 80 def trusted? IPs.list.any? { |range| range.include? remote_addr } end |
#visitor ⇒ Object
“Cf-Visitor: { "scheme":"https"}”
70 71 72 73 |
# File 'lib/rack/cloudflare/headers.rb', line 70 def visitor return unless has?(HTTP_CF_VISITOR) ::JSON.parse @headers[HTTP_CF_VISITOR] end |