cloudflare-rails 4.1.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 60ed180dedad2fcf57532cced88e34d37be0add173ab41d14265b26a19f708d8
4
- data.tar.gz: 38032a3aa5e0e8050b57d46d6959a08ae3a6b8535441a1e1cd5192b53d26db50
3
+ metadata.gz: f4d8ab5a9f56ae053e1647298c77b9a1616834b89d72467d09938f27ea9063d6
4
+ data.tar.gz: 123877f4dfc33b4c276cbfa91a718e14e9d92f8244ea618e21c12b57a84b203c
5
5
  SHA512:
6
- metadata.gz: 83e0c04af97a4cdd8376ab8d7fe32453b36564d23807c15b3d3e753b7e0b6ab18f161148f4817ea1c62fa48931826b2809b09bf26b1e492051399f07811b1185
7
- data.tar.gz: dc2376bf386241d45c92924db349cb6c8e7716eba1c10cf04460ed48f0679ffb52d72b7e1321cce5110f4bb6e93e7b911151676b8dcea359090fb024b51dba81
6
+ metadata.gz: b2814703b862fd8c88e89a40fa4d84dfcf1b71e2b90d823a74d450f54a69edc3ea14e0056f0442dcca837a460d4c253b21fa6e156b21d72148b53d47723b39ab
7
+ data.tar.gz: 66a1dbe16f14fce0562e34b4a694fc681299014afcf4d20785ea58467cc932e382c5df57a461e2cfc928c7a7aebe7ff524b29d020d759778ca2680b5ea153655
@@ -0,0 +1,55 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ pull_request:
12
+ branches: [main]
13
+
14
+ jobs:
15
+ test:
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: "3.2" # Not needed with a .ruby-version file
22
+ - uses: actions/cache@v3
23
+ with:
24
+ path: vendor/bundle
25
+ key: ${{ runner.os }}-gems-${{ hashFiles('**/cloudflare-rails.gemspec') }}
26
+ restore-keys: |
27
+ ${{ runner.os }}-gems-
28
+ - name: Bundle install
29
+ run: |
30
+ bundle config path vendor/bundle
31
+ bundle install --jobs 4 --retry 3
32
+ - name: Appraisal install
33
+ run: |
34
+ bundle exec appraisal install
35
+ - name: Run tests
36
+ run: bundle exec appraisal rake
37
+ lint:
38
+ runs-on: ubuntu-latest
39
+ steps:
40
+ - uses: actions/checkout@v4
41
+ - uses: ruby/setup-ruby@v1
42
+ with:
43
+ ruby-version: "3.2" # Not needed with a .ruby-version file
44
+ - uses: actions/cache@v3
45
+ with:
46
+ path: vendor/bundle
47
+ key: ${{ runner.os }}-gems-${{ hashFiles('**/cloudflare-rails.gemspec') }}
48
+ restore-keys: |
49
+ ${{ runner.os }}-gems-
50
+ - name: Bundle install
51
+ run: |
52
+ bundle config path vendor/bundle
53
+ bundle install --jobs 4 --retry 3
54
+ - name: Rubocop
55
+ run: bundle exec rubocop
data/.rubocop.yml CHANGED
@@ -1,6 +1,17 @@
1
1
  inherit_from:
2
- - .rubocop_airbnb.yml
3
2
  - .rubocop_todo.yml
3
+ require:
4
+ - rubocop-rails
5
+ - rubocop-performance
6
+ - rubocop-rspec
7
+
4
8
  AllCops:
5
9
  NewCops: enable
10
+ TargetRubyVersion: 2.5
6
11
  SuggestExtensions: false
12
+
13
+ Style/Documentation:
14
+ Enabled: false
15
+
16
+ Gemspec/DevelopmentDependencies:
17
+ Enabled: false
data/.rubocop_todo.yml CHANGED
@@ -1,51 +1,174 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2022-04-14 23:18:15 UTC using RuboCop version 0.93.1.
3
+ # on 2023-12-11 04:03:08 UTC using RuboCop version 1.58.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 4
10
- # Cop supports --auto-correct.
11
- Layout/MultilineBlockLayout:
9
+ # Offense count: 1
10
+ # Configuration parameters: AllowedMethods.
11
+ # AllowedMethods: enums
12
+ Lint/ConstantDefinitionInBlock:
12
13
  Exclude:
13
14
  - 'spec/cloudflare/rails_spec.rb'
14
15
 
15
- # Offense count: 4
16
- # Cop supports --auto-correct.
17
- # Configuration parameters: EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
18
- # SupportedStyles: space, no_space
19
- # SupportedStylesForEmptyBraces: space, no_space
20
- Layout/SpaceInsideBlockBraces:
21
- EnforcedStyle: space
16
+ # Offense count: 1
17
+ # This cop supports unsafe autocorrection (--autocorrect-all).
18
+ # Configuration parameters: AllowedMethods.
19
+ # AllowedMethods: instance_of?, kind_of?, is_a?, eql?, respond_to?, equal?, presence, present?
20
+ Lint/RedundantSafeNavigation:
21
+ Exclude:
22
+ - 'spec/cloudflare/rails_spec.rb'
23
+
24
+ # Offense count: 1
25
+ # Configuration parameters: AllowComments, AllowNil.
26
+ Lint/SuppressedException:
27
+ Exclude:
28
+ - 'lib/cloudflare_rails/check_trusted_proxies.rb'
22
29
 
23
30
  # Offense count: 1
24
- # Cop supports --auto-correct.
31
+ # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
32
+ Metrics/AbcSize:
33
+ Max: 18
34
+
35
+ # Offense count: 2
36
+ # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
37
+ Metrics/MethodLength:
38
+ Max: 11
39
+
40
+ # Offense count: 2
41
+ # Configuration parameters: ForbiddenDelimiters.
42
+ # ForbiddenDelimiters: (?i-mx:(^|\s)(EO[A-Z]{1}|END)(\s|$))
43
+ Naming/HeredocDelimiterNaming:
44
+ Exclude:
45
+ - 'lib/cloudflare_rails/fallback_ips.rb'
46
+
47
+ # Offense count: 3
48
+ RSpec/AnyInstance:
49
+ Exclude:
50
+ - 'spec/cloudflare/rails_spec.rb'
51
+
52
+ # Offense count: 1
53
+ # Configuration parameters: Prefixes, AllowedPatterns.
54
+ # Prefixes: when, with, without
55
+ RSpec/ContextWording:
56
+ Exclude:
57
+ - 'spec/cloudflare/rails_spec.rb'
58
+
59
+ # Offense count: 2
60
+ # This cop supports safe autocorrection (--autocorrect).
61
+ # Configuration parameters: CustomTransform, IgnoredWords, DisallowedExamples.
62
+ # DisallowedExamples: works
63
+ RSpec/ExampleWording:
64
+ Exclude:
65
+ - 'spec/cloudflare/rails_spec.rb'
66
+
67
+ # Offense count: 1
68
+ # Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
69
+ # Include: **/*_spec*rb*, **/spec/**/*
70
+ RSpec/FilePath:
71
+ Exclude:
72
+ - 'spec/cloudflare/rails_spec.rb'
73
+
74
+ # Offense count: 1
75
+ RSpec/LeakyConstantDeclaration:
76
+ Exclude:
77
+ - 'spec/cloudflare/rails_spec.rb'
78
+
79
+ # Offense count: 5
80
+ RSpec/MultipleExpectations:
81
+ Max: 2
82
+
83
+ # Offense count: 15
84
+ # Configuration parameters: AllowSubject.
85
+ RSpec/MultipleMemoizedHelpers:
86
+ Max: 14
87
+
88
+ # Offense count: 3
89
+ # Configuration parameters: EnforcedStyle, IgnoreSharedExamples.
90
+ # SupportedStyles: always, named_only
91
+ RSpec/NamedSubject:
92
+ Exclude:
93
+ - 'spec/cloudflare/rails_spec.rb'
94
+
95
+ # Offense count: 16
96
+ # Configuration parameters: AllowedGroups.
97
+ RSpec/NestedGroups:
98
+ Max: 6
99
+
100
+ # Offense count: 1
101
+ # Configuration parameters: Include, CustomTransform, IgnoreMethods, IgnoreMetadata.
102
+ # Include: **/*_spec.rb
103
+ RSpec/SpecFilePathFormat:
104
+ Exclude:
105
+ - 'spec/cloudflare/rails_spec.rb'
106
+
107
+ # Offense count: 1
108
+ # This cop supports unsafe autocorrection (--autocorrect-all).
25
109
  Rails/ApplicationController:
26
110
  Exclude:
27
111
  - 'spec/cloudflare/rails_spec.rb'
28
112
 
29
113
  # Offense count: 1
30
- # Cop supports --auto-correct.
31
- Rails/NegateInclude:
114
+ # This cop supports unsafe autocorrection (--autocorrect-all).
115
+ Rails/CompactBlank:
116
+ Exclude:
117
+ - 'lib/cloudflare_rails/importer.rb'
118
+
119
+ # Offense count: 3
120
+ # This cop supports unsafe autocorrection (--autocorrect-all).
121
+ # Configuration parameters: Include.
122
+ # Include: **/Rakefile, **/*.rake
123
+ Rails/RakeEnvironment:
124
+ Exclude:
125
+ - 'Rakefile'
126
+
127
+ # Offense count: 1
128
+ # This cop supports safe autocorrection (--autocorrect).
129
+ # Configuration parameters: AllowOnConstant, AllowOnSelfClass.
130
+ Style/CaseEquality:
32
131
  Exclude:
33
- - 'lib/cloudflare/rails/railtie.rb'
132
+ - 'lib/cloudflare_rails/check_trusted_proxies.rb'
133
+
134
+ # Offense count: 2
135
+ # This cop supports safe autocorrection (--autocorrect).
136
+ # Configuration parameters: MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns.
137
+ # SupportedStyles: annotated, template, unannotated
138
+ # AllowedMethods: redirect
139
+ Style/FormatStringToken:
140
+ EnforcedStyle: unannotated
34
141
 
35
- # Offense count: 4
36
- # Cop supports --auto-correct.
37
- # Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, IgnoredMethods, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
38
- # SupportedStyles: line_count_based, semantic, braces_for_chaining
39
- # ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
40
- # FunctionalMethods: let, let!, subject, watch
41
- # IgnoredMethods: lambda, proc, it
42
- Style/BlockDelimiters:
142
+ # Offense count: 15
143
+ # This cop supports unsafe autocorrection (--autocorrect-all).
144
+ # Configuration parameters: EnforcedStyle.
145
+ # SupportedStyles: always, always_true, never
146
+ Style/FrozenStringLiteralComment:
43
147
  Exclude:
148
+ - 'Appraisals'
149
+ - 'Gemfile'
150
+ - 'Rakefile'
151
+ - 'cloudflare-rails.gemspec'
152
+ - 'gemfiles/rails_6.1.gemfile'
153
+ - 'gemfiles/rails_7.0.gemfile'
154
+ - 'gemfiles/rails_7.1.gemfile'
155
+ - 'lib/cloudflare_rails.rb'
156
+ - 'lib/cloudflare_rails/check_trusted_proxies.rb'
157
+ - 'lib/cloudflare_rails/importer.rb'
158
+ - 'lib/cloudflare_rails/railtie.rb'
159
+ - 'lib/cloudflare_rails/remote_ip_proxies.rb'
160
+ - 'lib/cloudflare_rails/version.rb'
44
161
  - 'spec/cloudflare/rails_spec.rb'
162
+ - 'spec/spec_helper.rb'
163
+
164
+ # Offense count: 1
165
+ Style/MultilineBlockChain:
166
+ Exclude:
167
+ - 'lib/cloudflare_rails/railtie.rb'
45
168
 
46
- # Offense count: 9
47
- # Cop supports --auto-correct.
48
- # Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
169
+ # Offense count: 2
170
+ # This cop supports safe autocorrection (--autocorrect).
171
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
49
172
  # URISchemes: http, https
50
173
  Layout/LineLength:
51
174
  Max: 126
data/Appraisals CHANGED
@@ -1,11 +1,11 @@
1
- appraise "rails-6.1" do
2
- gem "rails", "~> 6.1.0"
1
+ appraise 'rails-6.1' do
2
+ gem 'rails', '~> 6.1.0'
3
3
  end
4
4
 
5
- appraise "rails-7.0" do
6
- gem "rails", "~> 7.0.0"
5
+ appraise 'rails-7.0' do
6
+ gem 'rails', '~> 7.0.0'
7
7
  end
8
8
 
9
- appraise "rails-7.1" do
10
- gem "rails", "~> 7.1.0"
9
+ appraise 'rails-7.1' do
10
+ gem 'rails', '~> 7.1.0'
11
11
  end
data/CHANGELOG.md CHANGED
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [5.0.0] - 2023-12-15
8
+ ### Breaking Changes
9
+ - Change namespace from `Cloudflare::Rails` to `CloudflareRails`. This avoids issues with the [cloudflare](https://github.com/socketry/cloudflare) gem as well as the global `Rails` namespace.
10
+ - A static set of Cloudflare IP addresses will now be used as a fallback value in the case of Cloudflare API failures. These will not be stored in `Rails.cache` so each subsequent result will retry the Cloudflare calls. Once one suceeds the response will be cached and used.
11
+
12
+ ### Added
13
+ - Use `zeitwerk` to manage file loading.
14
+
7
15
  ## [4.1.0] - 2023-10-06
8
16
  - Add support for `rails` version `7.1.0`
9
17
 
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Cloudflare::Rails [![Gem Version](https://badge.fury.io/rb/cloudflare-rails.svg)](https://badge.fury.io/rb/cloudflare-rails) [![CircleCI](https://circleci.com/gh/modosc/cloudflare-rails/tree/main.svg?style=shield)](https://circleci.com/gh/modosc/cloudflare-rails/tree/main)
1
+ # CloudflareRails [![Gem Version](https://badge.fury.io/rb/cloudflare-rails.svg)](https://badge.fury.io/rb/cloudflare-rails)
2
2
  This gem correctly configures Rails for [CloudFlare](https://www.cloudflare.com) so that `request.remote_ip` / `request.ip` both work correctly.
3
3
 
4
4
  ## Rails Compatibility
@@ -36,9 +36,17 @@ Using Cloudflare means it's hard to identify the IP address of incoming requests
36
36
 
37
37
  `cloudflare-rails` mitigates this attack by checking that the originating ip address of any incoming connection is from one of Cloudflare's ip address ranges. If so, the incoming `X-Forwarded-For` header is trusted and used as the ip address provided to `rack` and `rails` (via `request.ip` and `request.remote_ip`). If the incoming connection does not originate from a Cloudflare server then the `X-Forwarded-For` header is ignored and the actual remote ip address is used.
38
38
 
39
- ## Usage
40
- This code will fetch CloudFlare's current [IPv4](https://www.cloudflare.com/ips-v4) and [IPv6](https://www.cloudflare.com/ips-v6) lists, store them in `Rails.cache`, and add them to `config.cloudflare.ips`. The `X-Forwarded-For` header will then be trusted only from those ip addresses.
39
+ ## How it works
40
+ This code fetches and caches CloudFlare's current [IPv4](https://www.cloudflare.com/ips-v4) and [IPv6](https://www.cloudflare.com/ips-v6) lists. It then patches `Rack::Request::Helpers` and `ActionDispatch::RemoteIP` to treat these addresses as trusted proxies. The `X-Forwarded-For` header will then be trusted only from those ip addresses.
41
+
42
+ ### Why not use `config.action_dispatch.trusted_proxies` or `Rack::Request.ip_filter?`
43
+ By default Rails includes the [ActionDispatch::RemoteIp](https://api.rubyonrails.org/classes/ActionDispatch/RemoteIp.html) middleware. This middleware uses a default list of [trusted proxies](https://github.com/rails/rails/blob/6b93fff8af32ef5e91f4ec3cfffb081d0553faf0/actionpack/lib/action_dispatch/middleware/remote_ip.rb#L36C5-L42). Any values from `config.action_dispatch.trusted_proxies` are appended to this list. If you were to set `config.action_dispatch.trusted_proxies` to the current list of Cloudflare IP addresses `request.remote_ip` would work correctly.
44
+
45
+ Unfortunately this does not fix `request.ip`. This method comes from the [Rack::Request](https://github.com/rack/rack/blob/main/lib/rack/request.rb) middleware. It has a separate implementation of [trusted proxies](https://github.com/rack/rack/blob/main/lib/rack/request.rb#L48-L56) and [ip filtering](https://github.com/rack/rack/blob/main/lib/rack/request.rb#L58C1-L59C1). The only way to use a different implementation is to set `Rack::Request.ip_filter` which expects a callable value. Providing a new one will override the old one so you'd lose the default values (all of which should be there). Those values aren't exported anywhere so your callable would now have to maintain _that_ list on top of the Cloudflare IPs.
41
46
 
47
+ These issues are why this gem patches both `Rack::Request::Helpers` and `ActionDispatch::RemoteIP` rather than using the built-in configuration methods.
48
+
49
+ ## Usage
42
50
  You can configure the HTTP `timeout` and `expires_in` cache parameters inside of your rails config:
43
51
  ```ruby
44
52
  config.cloudflare.expires_in = 12.hours # default value
data/Rakefile CHANGED
@@ -1,24 +1,24 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
6
  task :without_rack_attack do
7
7
  ENV.delete 'RACK_ATTACK'
8
- Rake::Task["spec"].reenable
9
- Rake::Task["spec"].invoke
8
+ Rake::Task['spec'].reenable
9
+ Rake::Task['spec'].invoke
10
10
  end
11
11
 
12
12
  task :with_rack_attack_first do
13
13
  ENV['RACK_ATTACK'] = 'first'
14
- Rake::Task["spec"].reenable
15
- Rake::Task["spec"].invoke
14
+ Rake::Task['spec'].reenable
15
+ Rake::Task['spec'].invoke
16
16
  end
17
17
 
18
18
  task :with_rack_attack_last do
19
19
  ENV['RACK_ATTACK'] = 'last'
20
- Rake::Task["spec"].reenable
21
- Rake::Task["spec"].invoke
20
+ Rake::Task['spec'].reenable
21
+ Rake::Task['spec'].invoke
22
22
  end
23
23
 
24
- task :default => [:without_rack_attack, :with_rack_attack_first, :with_rack_attack_last]
24
+ task default: %i[without_rack_attack with_rack_attack_first with_rack_attack_last]
@@ -1,40 +1,42 @@
1
- # coding: utf-8
2
-
3
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
4
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'cloudflare/rails/version'
3
+ require 'cloudflare_rails/version'
6
4
 
7
5
  Gem::Specification.new do |spec|
8
- spec.name = "cloudflare-rails"
9
- spec.version = Cloudflare::Rails::VERSION
10
- spec.authors = ["jonathan schatz"]
11
- spec.email = ["modosc@users.noreply.github.com"]
12
-
13
- spec.summary = "This gem configures Rails for CloudFlare so that request.ip and request.remote_ip and work correctly."
14
- spec.description = ""
15
- spec.homepage = "https://github.com/modosc/cloudflare-rails"
16
- spec.license = "MIT"
6
+ spec.name = 'cloudflare-rails'
7
+ spec.version = CloudflareRails::VERSION
8
+ spec.authors = ['jonathan schatz']
9
+ spec.email = ['modosc@users.noreply.github.com']
10
+ spec.summary = 'This gem configures Rails for CloudFlare so that request.ip and request.remote_ip and work correctly.'
11
+ spec.description = ''
12
+ spec.homepage = 'https://github.com/modosc/cloudflare-rails'
13
+ spec.license = 'MIT'
17
14
 
18
15
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
- spec.bindir = "exe"
16
+ spec.bindir = 'exe'
20
17
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
- spec.require_paths = ["lib"]
18
+ spec.require_paths = ['lib']
22
19
 
23
- spec.add_development_dependency "bundler", ">= 2.1.2"
24
- spec.add_development_dependency "rake", "~> 13.0.1"
25
- spec.add_development_dependency "rspec_junit_formatter", "~> 0.6.0"
26
- spec.add_development_dependency "rspec-rails", "~> 6.0.0"
27
- spec.add_development_dependency "rspec", "~> 3.12.0"
28
- spec.add_development_dependency "rubocop-airbnb", "~> 6.0.0"
29
- spec.add_development_dependency "webmock", "~> 3.19.1"
30
- spec.add_development_dependency "rack-attack", "~> 6.7.0"
31
- spec.add_development_dependency "pry-byebug"
32
- spec.add_development_dependency "appraisal", "~> 2.5.0"
20
+ spec.add_development_dependency 'appraisal', '~> 2.5.0'
21
+ spec.add_development_dependency 'bundler', '>= 2.1.2'
22
+ spec.add_development_dependency 'pry-byebug'
23
+ spec.add_development_dependency 'rack-attack', '~> 6.7.0'
24
+ spec.add_development_dependency 'rake', '~> 13.1.0'
25
+ spec.add_development_dependency 'rspec', '~> 3.12.0'
26
+ spec.add_development_dependency 'rspec_junit_formatter', '~> 0.6.0'
27
+ spec.add_development_dependency 'rspec-rails', '~> 6.1.0'
28
+ spec.add_development_dependency 'rubocop', '~> 1.58.0'
29
+ spec.add_development_dependency 'rubocop-performance', '~> 1.19.1'
30
+ spec.add_development_dependency 'rubocop-rails', '~> 2.22.2'
31
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.25.0'
32
+ spec.add_development_dependency 'webmock', '~> 3.19.1'
33
33
 
34
- spec.add_dependency "railties", ">= 6.1", "< 7.2.0"
35
- spec.add_dependency "activesupport", ">= 6.1", "< 7.2.0"
36
- spec.add_dependency "actionpack", ">= 6.1", "< 7.2.0"
34
+ spec.add_dependency 'actionpack', '>= 6.1', '< 7.2.0'
35
+ spec.add_dependency 'activesupport', '>= 6.1', '< 7.2.0'
36
+ spec.add_dependency 'railties', '>= 6.1', '< 7.2.0'
37
+ spec.add_dependency 'zeitwerk', '>= 2.5.0'
37
38
 
38
- # we need Module#prepend
39
- spec.required_ruby_version = '>= 2.0'
39
+ # rails 6.1 lists this as the minimum
40
+ spec.required_ruby_version = '>= 2.5.0'
41
+ spec.metadata['rubygems_mfa_required'] = 'true'
40
42
  end
@@ -1,7 +1,7 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
- gem "rails", "~> 6.1.0"
5
+ gem 'rails', '~> 6.1.0'
6
6
 
7
- gemspec path: "../"
7
+ gemspec path: '../'
@@ -1,7 +1,7 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
- gem "rails", "~> 7.0.0"
5
+ gem 'rails', '~> 7.0.0'
6
6
 
7
- gemspec path: "../"
7
+ gemspec path: '../'
@@ -1,7 +1,7 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
- gem "rails", "~> 7.1.0"
5
+ gem 'rails', '~> 7.1.0'
6
6
 
7
- gemspec path: "../"
7
+ gemspec path: '../'
@@ -0,0 +1,13 @@
1
+ module CloudflareRails
2
+ # patch rack::request::helpers to use our cloudflare ips - this way request.ip is
3
+ # correct inside of rack and rails
4
+ module CheckTrustedProxies
5
+ def trusted_proxy?(ip)
6
+ matching = Importer.cloudflare_ips.any? do |proxy|
7
+ proxy === ip
8
+ rescue IPAddr::InvalidAddressError
9
+ end
10
+ matching || super
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CloudflareRails
4
+ module FallbackIps
5
+ # fetched from https://www.cloudflare.com/ips-v4/ on 2023-12-10
6
+ IPS_V4_BODY = <<~EOM
7
+ 173.245.48.0/20
8
+ 103.21.244.0/22
9
+ 103.22.200.0/22
10
+ 103.31.4.0/22
11
+ 141.101.64.0/18
12
+ 108.162.192.0/18
13
+ 190.93.240.0/20
14
+ 188.114.96.0/20
15
+ 197.234.240.0/22
16
+ 198.41.128.0/17
17
+ 162.158.0.0/15
18
+ 104.16.0.0/13
19
+ 104.24.0.0/14
20
+ 172.64.0.0/13
21
+ 131.0.72.0/22
22
+ EOM
23
+
24
+ # convert our body into a list of IpAddrs
25
+ IPS_V4 = IPS_V4_BODY.split("\n").map { |ip| IPAddr.new ip }.freeze
26
+
27
+ # from https://www.cloudflare.com/ips-v6/ on 2023-12-10
28
+ IPS_V6_BODY = <<~EOM
29
+ 2400:cb00::/32
30
+ 2606:4700::/32
31
+ 2803:f800::/32
32
+ 2405:b500::/32
33
+ 2405:8100::/32
34
+ 2a06:98c0::/29
35
+ 2c0f:f248::/32
36
+ EOM
37
+
38
+ # convert our body into a list of IpAddrs
39
+ IPS_V6 = IPS_V6_BODY.split("\n").map { |ip| IPAddr.new ip }.freeze
40
+ end
41
+ end
@@ -0,0 +1,67 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ module CloudflareRails
5
+ class Importer
6
+ # Exceptions contain the Net::HTTP
7
+ # response object accessible via the {#response} method.
8
+ class ResponseError < StandardError
9
+ # Returns the response of the last request
10
+ # @return [Net::HTTPResponse] A subclass of Net::HTTPResponse, e.g.
11
+ # Net::HTTPOK
12
+ attr_reader :response
13
+
14
+ # Instantiate an instance of ResponseError with a Net::HTTPResponse object
15
+ # @param [Net::HTTPResponse]
16
+ def initialize(response)
17
+ @response = response
18
+ super(response)
19
+ end
20
+ end
21
+
22
+ BASE_URL = 'https://www.cloudflare.com'.freeze
23
+ IPS_V4_URL = '/ips-v4/'.freeze
24
+ IPS_V6_URL = '/ips-v6/'.freeze
25
+
26
+ class << self
27
+ def ips_v6
28
+ fetch IPS_V6_URL
29
+ end
30
+
31
+ def ips_v4
32
+ fetch IPS_V4_URL
33
+ end
34
+
35
+ def fetch(url)
36
+ uri = URI("#{BASE_URL}#{url}")
37
+
38
+ resp = Net::HTTP.start(uri.host,
39
+ uri.port,
40
+ use_ssl: true,
41
+ read_timeout: Rails.application.config.cloudflare.timeout) do |http|
42
+ req = Net::HTTP::Get.new(uri)
43
+
44
+ http.request(req)
45
+ end
46
+
47
+ raise ResponseError, resp unless resp.is_a?(Net::HTTPSuccess)
48
+
49
+ resp.body.split("\n").reject(&:blank?).map { |ip| IPAddr.new ip }
50
+ end
51
+
52
+ def fetch_with_cache(type)
53
+ Rails.cache.fetch("cloudflare-rails:#{type}", expires_in: Rails.application.config.cloudflare.expires_in) do
54
+ send type
55
+ end
56
+ end
57
+
58
+ def cloudflare_ips(refresh: false)
59
+ @ips = nil if refresh
60
+ @ips ||= (Importer.fetch_with_cache(:ips_v4) + Importer.fetch_with_cache(:ips_v6)).freeze
61
+ rescue StandardError => e
62
+ Rails.logger.error "cloudflare-rails: error fetching ip addresses from Cloudflare (#{e}), falling back to defaults"
63
+ CloudflareRails::FallbackIps::IPS_V4 + CloudflareRails::FallbackIps::IPS_V6
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,29 @@
1
+ require 'active_support/core_ext/integer/time'
2
+
3
+ module CloudflareRails
4
+ class Railtie < Rails::Railtie
5
+ # setup defaults before we configure our app.
6
+ DEFAULTS = {
7
+ expires_in: 12.hours,
8
+ timeout: 5.seconds
9
+ }.freeze
10
+
11
+ config.before_configuration do |app|
12
+ app.config.cloudflare = ActiveSupport::OrderedOptions.new
13
+ app.config.cloudflare.reverse_merge! DEFAULTS
14
+ end
15
+
16
+ initializer 'cloudflare_rails.configure_rails_initialization' do
17
+ Rack::Request::Helpers.prepend CheckTrustedProxies
18
+
19
+ ObjectSpace.each_object(Class)
20
+ .select do |c|
21
+ c.included_modules.include?(Rack::Request::Helpers) &&
22
+ c.included_modules.exclude?(CheckTrustedProxies)
23
+ end
24
+ .map { |c| c.prepend CheckTrustedProxies }
25
+
26
+ ActionDispatch::RemoteIp.prepend RemoteIpProxies
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,9 @@
1
+ module CloudflareRails
2
+ # patch ActionDispatch::RemoteIP to use our cloudflare ips - this way
3
+ # request.remote_ip is correct inside of rails
4
+ module RemoteIpProxies
5
+ def proxies
6
+ super + Importer.cloudflare_ips
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module CloudflareRails
2
+ VERSION = '5.0.0'.freeze
3
+ end
@@ -0,0 +1,7 @@
1
+ require 'zeitwerk'
2
+ loader = Zeitwerk::Loader.for_gem
3
+ loader.setup
4
+ loader.eager_load
5
+
6
+ module CloudflareRails
7
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudflare-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - jonathan schatz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-06 00:00:00.000000000 Z
11
+ date: 2023-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: appraisal
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.5.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.5.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -25,47 +39,47 @@ dependencies:
25
39
  - !ruby/object:Gem::Version
26
40
  version: 2.1.2
27
41
  - !ruby/object:Gem::Dependency
28
- name: rake
42
+ name: pry-byebug
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - "~>"
45
+ - - ">="
32
46
  - !ruby/object:Gem::Version
33
- version: 13.0.1
47
+ version: '0'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - "~>"
52
+ - - ">="
39
53
  - !ruby/object:Gem::Version
40
- version: 13.0.1
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
- name: rspec_junit_formatter
56
+ name: rack-attack
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: 0.6.0
61
+ version: 6.7.0
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: 0.6.0
68
+ version: 6.7.0
55
69
  - !ruby/object:Gem::Dependency
56
- name: rspec-rails
70
+ name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: 6.0.0
75
+ version: 13.1.0
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: 6.0.0
82
+ version: 13.1.0
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -81,77 +95,105 @@ dependencies:
81
95
  - !ruby/object:Gem::Version
82
96
  version: 3.12.0
83
97
  - !ruby/object:Gem::Dependency
84
- name: rubocop-airbnb
98
+ name: rspec_junit_formatter
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: 6.0.0
103
+ version: 0.6.0
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: 6.0.0
110
+ version: 0.6.0
97
111
  - !ruby/object:Gem::Dependency
98
- name: webmock
112
+ name: rspec-rails
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: 3.19.1
117
+ version: 6.1.0
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: 3.19.1
124
+ version: 6.1.0
111
125
  - !ruby/object:Gem::Dependency
112
- name: rack-attack
126
+ name: rubocop
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - "~>"
116
130
  - !ruby/object:Gem::Version
117
- version: 6.7.0
131
+ version: 1.58.0
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
136
  - - "~>"
123
137
  - !ruby/object:Gem::Version
124
- version: 6.7.0
138
+ version: 1.58.0
125
139
  - !ruby/object:Gem::Dependency
126
- name: pry-byebug
140
+ name: rubocop-performance
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
- - - ">="
143
+ - - "~>"
130
144
  - !ruby/object:Gem::Version
131
- version: '0'
145
+ version: 1.19.1
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
- - - ">="
150
+ - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: '0'
152
+ version: 1.19.1
139
153
  - !ruby/object:Gem::Dependency
140
- name: appraisal
154
+ name: rubocop-rails
141
155
  requirement: !ruby/object:Gem::Requirement
142
156
  requirements:
143
157
  - - "~>"
144
158
  - !ruby/object:Gem::Version
145
- version: 2.5.0
159
+ version: 2.22.2
146
160
  type: :development
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
164
  - - "~>"
151
165
  - !ruby/object:Gem::Version
152
- version: 2.5.0
166
+ version: 2.22.2
153
167
  - !ruby/object:Gem::Dependency
154
- name: railties
168
+ name: rubocop-rspec
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: 2.25.0
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 2.25.0
181
+ - !ruby/object:Gem::Dependency
182
+ name: webmock
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: 3.19.1
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: 3.19.1
195
+ - !ruby/object:Gem::Dependency
196
+ name: actionpack
155
197
  requirement: !ruby/object:Gem::Requirement
156
198
  requirements:
157
199
  - - ">="
@@ -191,7 +233,7 @@ dependencies:
191
233
  - !ruby/object:Gem::Version
192
234
  version: 7.2.0
193
235
  - !ruby/object:Gem::Dependency
194
- name: actionpack
236
+ name: railties
195
237
  requirement: !ruby/object:Gem::Requirement
196
238
  requirements:
197
239
  - - ">="
@@ -210,6 +252,20 @@ dependencies:
210
252
  - - "<"
211
253
  - !ruby/object:Gem::Version
212
254
  version: 7.2.0
255
+ - !ruby/object:Gem::Dependency
256
+ name: zeitwerk
257
+ requirement: !ruby/object:Gem::Requirement
258
+ requirements:
259
+ - - ">="
260
+ - !ruby/object:Gem::Version
261
+ version: 2.5.0
262
+ type: :runtime
263
+ prerelease: false
264
+ version_requirements: !ruby/object:Gem::Requirement
265
+ requirements:
266
+ - - ">="
267
+ - !ruby/object:Gem::Version
268
+ version: 2.5.0
213
269
  description: ''
214
270
  email:
215
271
  - modosc@users.noreply.github.com
@@ -217,12 +273,11 @@ executables: []
217
273
  extensions: []
218
274
  extra_rdoc_files: []
219
275
  files:
220
- - ".circleci/config.yml"
221
276
  - ".github/dependabot.yml"
277
+ - ".github/workflows/ruby.yml"
222
278
  - ".gitignore"
223
279
  - ".rspec"
224
280
  - ".rubocop.yml"
225
- - ".rubocop_airbnb.yml"
226
281
  - ".rubocop_todo.yml"
227
282
  - ".ruby-version"
228
283
  - Appraisals
@@ -238,13 +293,18 @@ files:
238
293
  - gemfiles/rails_6.1.gemfile
239
294
  - gemfiles/rails_7.0.gemfile
240
295
  - gemfiles/rails_7.1.gemfile
241
- - lib/cloudflare/rails.rb
242
- - lib/cloudflare/rails/railtie.rb
243
- - lib/cloudflare/rails/version.rb
296
+ - lib/cloudflare_rails.rb
297
+ - lib/cloudflare_rails/check_trusted_proxies.rb
298
+ - lib/cloudflare_rails/fallback_ips.rb
299
+ - lib/cloudflare_rails/importer.rb
300
+ - lib/cloudflare_rails/railtie.rb
301
+ - lib/cloudflare_rails/remote_ip_proxies.rb
302
+ - lib/cloudflare_rails/version.rb
244
303
  homepage: https://github.com/modosc/cloudflare-rails
245
304
  licenses:
246
305
  - MIT
247
- metadata: {}
306
+ metadata:
307
+ rubygems_mfa_required: 'true'
248
308
  post_install_message:
249
309
  rdoc_options: []
250
310
  require_paths:
@@ -253,7 +313,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
253
313
  requirements:
254
314
  - - ">="
255
315
  - !ruby/object:Gem::Version
256
- version: '2.0'
316
+ version: 2.5.0
257
317
  required_rubygems_version: !ruby/object:Gem::Requirement
258
318
  requirements:
259
319
  - - ">="
data/.circleci/config.yml DELETED
@@ -1,54 +0,0 @@
1
- # Ruby CircleCI 2.0 configuration file
2
- #
3
- # Check https://circleci.com/docs/2.0/language-ruby/ for more details
4
- #
5
- version: 2
6
- jobs:
7
- build:
8
- docker:
9
- # specify the version you desire here
10
- - image: cimg/ruby:2.7
11
-
12
- working_directory: ~/repo
13
-
14
- steps:
15
- - checkout
16
-
17
- # Download and cache dependencies
18
- - restore_cache:
19
- keys:
20
- - v1-dependencies-{{ checksum "cloudflare-rails.gemspec" }}-{{ checksum "Appraisals" }}
21
- # fallback to using the latest cache if no exact match is found
22
- - v1-dependencies-
23
-
24
- - run:
25
- name: install bundler
26
- command: |
27
- gem install bundler -v $(grep bundler cloudflare-rails.gemspec |awk {'print $4'}|sed 's/"//g')
28
-
29
- - run:
30
- name: install dependencies
31
- command: |
32
- bundle install --jobs=4 --retry=3 --path vendor/bundle
33
-
34
- - run:
35
- name: install appraisal versions
36
- command: |
37
- bundle exec appraisal install
38
-
39
- - save_cache:
40
- paths:
41
- - ./vendor/bundle
42
- key: v1-dependencies-{{ checksum "cloudflare-rails.gemspec" }}-{{ checksum "Appraisals" }}
43
-
44
- # run tests!
45
- - run:
46
- name: run tests
47
- command: |
48
- bundle exec appraisal rake
49
- # collect reports
50
- - store_test_results:
51
- path: tmp/rspec
52
- - store_artifacts:
53
- path: tmp/rspec
54
- destination: test-results
data/.rubocop_airbnb.yml DELETED
@@ -1,2 +0,0 @@
1
- require:
2
- - rubocop-airbnb
@@ -1,117 +0,0 @@
1
- require "active_support/core_ext/integer/time"
2
-
3
- module Cloudflare
4
- module Rails
5
- class Railtie < ::Rails::Railtie
6
- # patch rack::request::helpers to use our cloudflare ips - this way request.ip is
7
- # correct inside of rack and rails
8
- module CheckTrustedProxies
9
- def trusted_proxy?(ip)
10
- matching = Importer.cloudflare_ips.any? do |proxy|
11
- proxy === ip
12
- rescue IPAddr::InvalidAddressError
13
- end
14
- matching || super
15
- end
16
- end
17
-
18
- # patch ActionDispatch::RemoteIP to use our cloudflare ips - this way
19
- # request.remote_ip is correct inside of rails
20
- module RemoteIpProxies
21
- def proxies
22
- super + Importer.cloudflare_ips
23
- end
24
- end
25
-
26
- class Importer
27
- # Exceptions contain the Net::HTTP
28
- # response object accessible via the {#response} method.
29
- class ResponseError < StandardError
30
- # Returns the response of the last request
31
- # @return [Net::HTTPResponse] A subclass of Net::HTTPResponse, e.g.
32
- # Net::HTTPOK
33
- attr_reader :response
34
-
35
- # Instantiate an instance of ResponseError with a Net::HTTPResponse object
36
- # @param [Net::HTTPResponse]
37
- def initialize(response)
38
- @response = response
39
- super(response)
40
- end
41
- end
42
-
43
- BASE_URL = 'https://www.cloudflare.com'.freeze
44
- IPS_V4_URL = '/ips-v4/'.freeze
45
- IPS_V6_URL = '/ips-v6/'.freeze
46
-
47
- class << self
48
- def ips_v6
49
- fetch IPS_V6_URL
50
- end
51
-
52
- def ips_v4
53
- fetch IPS_V4_URL
54
- end
55
-
56
- def fetch(url)
57
- uri = URI("#{BASE_URL}#{url}")
58
-
59
- resp = Net::HTTP.start(uri.host,
60
- uri.port,
61
- use_ssl: true,
62
- read_timeout: ::Rails.application.config.cloudflare.timeout) do |http|
63
- req = Net::HTTP::Get.new(uri)
64
-
65
- http.request(req)
66
- end
67
-
68
- if resp.is_a?(Net::HTTPSuccess)
69
- resp.body.split("\n").reject(&:blank?).map { |ip| IPAddr.new ip }
70
- else
71
- raise ResponseError, resp
72
- end
73
- end
74
-
75
- def fetch_with_cache(type)
76
- ::Rails.cache.fetch("cloudflare-rails:#{type}", expires_in: ::Rails.application.config.cloudflare.expires_in) do
77
- send type
78
- end
79
- end
80
-
81
- def cloudflare_ips(refresh: false)
82
- @ips = nil if refresh
83
- @ips ||= (Importer.fetch_with_cache(:ips_v4) + Importer.fetch_with_cache(:ips_v6)).freeze
84
- rescue StandardError => e
85
- ::Rails.logger.error(e)
86
- []
87
- end
88
- end
89
- end
90
-
91
- # setup defaults before we configure our app.
92
- DEFAULTS = {
93
- expires_in: 12.hours,
94
- timeout: 5.seconds,
95
- ips: [],
96
- }.freeze
97
-
98
- config.before_configuration do |app|
99
- app.config.cloudflare = ActiveSupport::OrderedOptions.new
100
- app.config.cloudflare.reverse_merge! DEFAULTS
101
- end
102
-
103
- initializer "cloudflare_rails.configure_rails_initialization" do
104
- Rack::Request::Helpers.prepend CheckTrustedProxies
105
-
106
- ObjectSpace.each_object(Class).
107
- select do |c|
108
- c.included_modules.include?(Rack::Request::Helpers) &&
109
- !c.included_modules.include?(CheckTrustedProxies)
110
- end.
111
- map { |c| c .prepend CheckTrustedProxies }
112
-
113
- ActionDispatch::RemoteIp.prepend RemoteIpProxies
114
- end
115
- end
116
- end
117
- end
@@ -1,5 +0,0 @@
1
- module Cloudflare
2
- module Rails
3
- VERSION = "4.1.0".freeze
4
- end
5
- end
@@ -1,10 +0,0 @@
1
- require "cloudflare/rails/version"
2
- require 'net/http'
3
- require 'uri'
4
-
5
- module Cloudflare
6
- module Rails
7
- end
8
- end
9
-
10
- require "cloudflare/rails/railtie"