request_headers_middleware 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rubocop.yml +27 -0
- data/.ruby-version +1 -0
- data/.travis.yml +18 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +65 -0
- data/LICENSE.txt +22 -0
- data/README.md +123 -0
- data/Rakefile +42 -0
- data/bin/travis +12 -0
- data/lib/request_headers_middleware.rb +28 -0
- data/lib/request_headers_middleware/middleware.rb +61 -0
- data/lib/request_headers_middleware/railtie.rb +18 -0
- data/lib/request_headers_middleware/version.rb +5 -0
- data/request_headers_middleware.gemspec +28 -0
- data/spec/request_headers_middleware_spec.rb +86 -0
- data/spec/spec_helper.rb +45 -0
- data/spec/support/mock_rack_app.rb +19 -0
- metadata +150 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 482bdde0e0b23e5af93e73940c52e48c51f2ccbd
|
4
|
+
data.tar.gz: 6d52bb7f30b71e12b55dc160d3b0687a2956c6d8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7d26b9d1958e822e4fb4e45bf5fb8fa8f485586bbd01fba3e2c93987891fdfbd06bba9cb34ea96f3a94e10e2b8d1cf40f9cd83cb9df14c1547e9785e21981356
|
7
|
+
data.tar.gz: 105f929b62dab5f7dccc415a11bde7099bfdf28f82de17efb39a7be8b239ddcd6831dfcc8546fddfa7e4d6f7985b3de63eed601e4fb08106fac9082f716869e3
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- '.git-hooks/**/*'
|
4
|
+
- 'bin/*'
|
5
|
+
- 'db/schema.rb'
|
6
|
+
- 'db/migrate/*'
|
7
|
+
- 'vendor/bundle/**/*'
|
8
|
+
- 'config/environments/*'
|
9
|
+
- 'Rakefile'
|
10
|
+
|
11
|
+
Style/ModuleFunction:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Metrics/BlockLength:
|
15
|
+
Exclude:
|
16
|
+
- 'Rakefile'
|
17
|
+
- '**/*.rake'
|
18
|
+
- 'spec/**/*.rb'
|
19
|
+
|
20
|
+
Metrics/LineLength:
|
21
|
+
Max: 100
|
22
|
+
|
23
|
+
Style/Documentation:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Lint/UnusedBlockArgument:
|
27
|
+
Enabled: false
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.3
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
request_headers_middleware (0.0.4)
|
5
|
+
request_store
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ast (2.4.0)
|
11
|
+
byebug (9.0.6)
|
12
|
+
diff-lcs (1.2.5)
|
13
|
+
docile (1.1.5)
|
14
|
+
json (2.1.0)
|
15
|
+
parallel (1.12.1)
|
16
|
+
parser (2.5.0.2)
|
17
|
+
ast (~> 2.4.0)
|
18
|
+
powerpack (0.1.1)
|
19
|
+
rack (1.6.5)
|
20
|
+
rainbow (3.0.0)
|
21
|
+
rake (12.0.0)
|
22
|
+
request_store (1.4.0)
|
23
|
+
rack (>= 1.4)
|
24
|
+
rspec (3.5.0)
|
25
|
+
rspec-core (~> 3.5.0)
|
26
|
+
rspec-expectations (~> 3.5.0)
|
27
|
+
rspec-mocks (~> 3.5.0)
|
28
|
+
rspec-core (3.5.4)
|
29
|
+
rspec-support (~> 3.5.0)
|
30
|
+
rspec-expectations (3.5.0)
|
31
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
32
|
+
rspec-support (~> 3.5.0)
|
33
|
+
rspec-mocks (3.5.0)
|
34
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
35
|
+
rspec-support (~> 3.5.0)
|
36
|
+
rspec-support (3.5.0)
|
37
|
+
rubocop (0.53.0)
|
38
|
+
parallel (~> 1.10)
|
39
|
+
parser (>= 2.5)
|
40
|
+
powerpack (~> 0.1)
|
41
|
+
rainbow (>= 2.2.2, < 4.0)
|
42
|
+
ruby-progressbar (~> 1.7)
|
43
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
44
|
+
ruby-progressbar (1.9.0)
|
45
|
+
simplecov (0.12.0)
|
46
|
+
docile (~> 1.1.0)
|
47
|
+
json (>= 1.8, < 3)
|
48
|
+
simplecov-html (~> 0.10.0)
|
49
|
+
simplecov-html (0.10.0)
|
50
|
+
unicode-display_width (1.3.0)
|
51
|
+
|
52
|
+
PLATFORMS
|
53
|
+
ruby
|
54
|
+
|
55
|
+
DEPENDENCIES
|
56
|
+
byebug
|
57
|
+
rack
|
58
|
+
rake
|
59
|
+
request_headers_middleware!
|
60
|
+
rspec
|
61
|
+
rubocop
|
62
|
+
simplecov
|
63
|
+
|
64
|
+
BUNDLED WITH
|
65
|
+
1.16.1
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2017 Marc Grimme
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
# RequestHeaderMiddleware [](https://travis-ci.org/MarcGrimme/request_headers_middleware) [](https://codeclimate.com/github/MarcGrimme/request_headers_middleware)
|
2
|
+
|
3
|
+
If you decided to go the microservice approach and services are growing everywhere you will release challenges as soon as more
|
4
|
+
service are interconnected and you need to figure out problems.
|
5
|
+
|
6
|
+
For example how can you connect a request over multiple micro service hubs? Imagine services connected synchronous or asynchronously then the
|
7
|
+
whole challenge grows.
|
8
|
+
|
9
|
+
For this issue the *X-Request-Id* HTTP header was introduced. In Rails the *ActionDispatch::RequestId* middleware helps create a unique ID
|
10
|
+
for each request if not already defined by the *X-Request-Id* header. Unfortunatelly if your service connects to another service the passing
|
11
|
+
over of this unique id is not in the scope of the *ActionDispatch::RequestId* middleware.
|
12
|
+
|
13
|
+
For that issue this middleware will help you to use the same 'X-Request-Id' for multiple requests to in the end help you figure out the
|
14
|
+
request path also over multiple services. But it will not do the whole game. It will mainly just store the *X-Request-Id* header in a globally
|
15
|
+
available throughout the application (and not only in the controller when getting a request).
|
16
|
+
|
17
|
+
The middleware can be extended to store more information from the header. For example you might want to reuse a *Bearer* token or the
|
18
|
+
*X-Forward* header or more. For this you can either introduce whitelists - to only filter the headers you want to store - or a blacklist
|
19
|
+
to definitely not forward specific headers.
|
20
|
+
|
21
|
+
Default is the whilelist. It is initialized with *X-Request-Id*.
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
### Rails
|
26
|
+
|
27
|
+
So how does it work with Rails.
|
28
|
+
|
29
|
+
Add this line to your application's Gemfile:
|
30
|
+
|
31
|
+
``
|
32
|
+
gem 'request_headers_middleware'
|
33
|
+
``
|
34
|
+
|
35
|
+
And then execute:
|
36
|
+
|
37
|
+
``
|
38
|
+
$ bundle
|
39
|
+
``
|
40
|
+
|
41
|
+
Or install it yourself as:
|
42
|
+
|
43
|
+
``
|
44
|
+
$ gem install request_headers_middleware
|
45
|
+
``
|
46
|
+
|
47
|
+
That's it now you can access the request headers (all you filtered - by default just the *X-Request-Id*) through the
|
48
|
+
|
49
|
+
``
|
50
|
+
RequestHeadersMiddleware.store
|
51
|
+
``
|
52
|
+
|
53
|
+
### ActiveResource::Base
|
54
|
+
|
55
|
+
For example to make *ActiveResource::Base* reuse the headers use:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
class BaseResource < ActiveResource::Base
|
59
|
+
def self.headers
|
60
|
+
RequestHeadersMiddleware.store.merge(ActiveResource::Base.headers)
|
61
|
+
end
|
62
|
+
|
63
|
+
..
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
### Faraday
|
68
|
+
|
69
|
+
In *Faraday* you can do it as follows:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
Faraday.new(
|
73
|
+
url: host,
|
74
|
+
headers: RequestHeadersMiddleware.store,
|
75
|
+
..
|
76
|
+
)
|
77
|
+
```
|
78
|
+
|
79
|
+
### JsonApiClient
|
80
|
+
|
81
|
+
For a class extended from *JsonApiClient* it could work like this. Let's call the class *MyJsonApiClient*.
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
MyJsonApiClient.with_headers(RequestHeadersMiddleware.store) do
|
85
|
+
.. # Do the request by the MyJsonApiClient
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
### Whitelist
|
90
|
+
|
91
|
+
Per default the middleware applies a whitelist to only filter *X-Request-Id* header. Generally this is just as follows:
|
92
|
+
|
93
|
+
``
|
94
|
+
Rails.configuration.request_headers_middleware.whitelist = [ 'X-Request-Id' ]
|
95
|
+
``
|
96
|
+
|
97
|
+
As this is just a list it can be easily overwriten in an initilizer.
|
98
|
+
|
99
|
+
### Blacklist
|
100
|
+
|
101
|
+
The same holds for the blacklist but first you need to disable the whitelist by setting it to nil or empty as follows.
|
102
|
+
|
103
|
+
``
|
104
|
+
Rails.configuration.request_headers_middleware.whitelist = [ 'X-Request-Id' ]
|
105
|
+
``
|
106
|
+
|
107
|
+
### Callbacks
|
108
|
+
|
109
|
+
TODO: when I remeber why I thought this might make sense.
|
110
|
+
|
111
|
+
## Development
|
112
|
+
|
113
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
114
|
+
|
115
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
116
|
+
|
117
|
+
## Contributing
|
118
|
+
|
119
|
+
1. Fork it ( https://github.com/marcgrimme/request_headers_middleware/fork )
|
120
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
121
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
122
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
123
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
# Add default task. When you type just rake command this would run. Travis CI runs this. Making this run spec
|
7
|
+
desc 'Default: run specs.'
|
8
|
+
task :default => :spec
|
9
|
+
|
10
|
+
# Defining spec task for running spec
|
11
|
+
desc "Run specs"
|
12
|
+
RSpec::Core::RakeTask.new('spec') do |spec|
|
13
|
+
# Pattern filr for spec files to run. This is default btw.
|
14
|
+
spec.pattern = "./spec/**/*_spec.rb"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Run the rdoc task to generate rdocs for this gem
|
18
|
+
require 'rdoc/task'
|
19
|
+
RDoc::Task.new do |rdoc|
|
20
|
+
require File.expand_path("../lib/request_headers_middleware/version", __FILE__)
|
21
|
+
version = RequestHeadersMiddleware::VERSION
|
22
|
+
|
23
|
+
rdoc.rdoc_dir = 'rdoc'
|
24
|
+
rdoc.title = "release_headers_middleware #{version}"
|
25
|
+
rdoc.rdoc_files.include('README*')
|
26
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "Code coverage detail"
|
30
|
+
task :coverage do
|
31
|
+
ENV['COVERAGE'] = "true"
|
32
|
+
Rake::Task['spec'].execute
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Console for checking things"
|
36
|
+
task :console do
|
37
|
+
require 'irb'
|
38
|
+
require 'irb/completion'
|
39
|
+
require 'logger_instrumentation'
|
40
|
+
ARGV.clear
|
41
|
+
IRB.start
|
42
|
+
end
|
data/bin/travis
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'request_headers_middleware/railtie' if defined?(Rails)
|
4
|
+
require 'request_headers_middleware/middleware'
|
5
|
+
|
6
|
+
module RequestHeadersMiddleware # :nodoc:
|
7
|
+
extend self
|
8
|
+
|
9
|
+
attr_accessor :blacklist, :whitelist, :callbacks
|
10
|
+
@whitelist = ['x-request-id'.to_sym]
|
11
|
+
@blacklist = []
|
12
|
+
@callbacks = []
|
13
|
+
|
14
|
+
def store
|
15
|
+
RequestStore[:headers] ||= {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def store=(store)
|
19
|
+
RequestStore[:headers] = store
|
20
|
+
end
|
21
|
+
|
22
|
+
def setup(config)
|
23
|
+
@whitelist = config.whitelist.map { |key| key.downcase.to_sym } if config.whitelist
|
24
|
+
@blacklist = config.blacklist.map { |key| key.downcase.to_sym } if config.blacklist
|
25
|
+
|
26
|
+
config.callbacks && @callbacks = config.callbacks
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'request_store'
|
4
|
+
|
5
|
+
module RequestHeadersMiddleware # :nodoc:
|
6
|
+
# The Middleware that stores the header. Default is only to store the
|
7
|
+
# X-Request-Id or the action_dispatch.request_id from environment if not set.
|
8
|
+
class Middleware
|
9
|
+
def initialize(app)
|
10
|
+
@app = app
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
RequestStore.store[:headers] = filter(headers(env))
|
15
|
+
RequestHeadersMiddleware.callbacks.each { |cb| cb.call(env) }
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def headers(env)
|
22
|
+
default_headers(env)
|
23
|
+
.merge(Hash[*sanitize_headers(select_headers(env)).sort.flatten])
|
24
|
+
end
|
25
|
+
|
26
|
+
def filter(headers)
|
27
|
+
if RequestHeadersMiddleware.whitelist &&
|
28
|
+
!RequestHeadersMiddleware.whitelist.empty?
|
29
|
+
whitelist(headers)
|
30
|
+
else
|
31
|
+
blacklist(headers)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def select_headers(env)
|
36
|
+
env.select { |k, _v| k.start_with? 'HTTP_' }
|
37
|
+
end
|
38
|
+
|
39
|
+
def sanitize_headers(headers)
|
40
|
+
headers.collect { |k, v| [k.sub(/^HTTP_/, ''), v] }.collect do |k, v|
|
41
|
+
[k.split('_').collect(&:capitalize).join('-').to_sym, v]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def whitelist(headers)
|
46
|
+
headers.select do |key, _|
|
47
|
+
RequestHeadersMiddleware.whitelist.include?(key.downcase)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def blacklist(headers)
|
52
|
+
headers.reject do |key, _|
|
53
|
+
RequestHeadersMiddleware.blacklist.include?(key.downcase)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def default_headers(env)
|
58
|
+
{ "X-Request-Id": env['action_dispatch.request_id'] }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RequestHeadersMiddleware
|
4
|
+
# The Railtie triggering a setup from RAILs to make it configurable
|
5
|
+
class Railtie < ::Rails::Railtie
|
6
|
+
config.request_headers_middleware = ::ActiveSupport::OrderedOptions.new
|
7
|
+
config.request_headers_middleware.blacklist = []
|
8
|
+
config.request_headers_middleware.callbacks = []
|
9
|
+
|
10
|
+
initializer 'request_headers_middleware.insert_middleware' do
|
11
|
+
config.app_middleware.insert_after ActionDispatch::RequestId,
|
12
|
+
RequestHeadersMiddleware::Middleware
|
13
|
+
config.after_initialize do
|
14
|
+
RequestHeadersMiddleware.setup(config.request_headers_middleware)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'request_headers_middleware/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |gem|
|
8
|
+
gem.name = 'request_headers_middleware'
|
9
|
+
gem.version = RequestHeadersMiddleware::VERSION
|
10
|
+
gem.authors = ['Marc Grimme']
|
11
|
+
gem.email = ['marc.grimme@gmail.com']
|
12
|
+
gem.description = 'RequestHeader gives you per-req global header storage.'
|
13
|
+
gem.summary = 'RequestStore gives you per-reqt global header storage.'
|
14
|
+
gem.homepage = 'http://github.com/marcgrimme/request_headers_middleware'
|
15
|
+
gem.licenses = ['MIT']
|
16
|
+
|
17
|
+
gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
|
+
gem.require_paths = ['lib']
|
21
|
+
|
22
|
+
gem.add_dependency 'request_store'
|
23
|
+
gem.add_development_dependency 'rack'
|
24
|
+
gem.add_development_dependency 'rake'
|
25
|
+
gem.add_development_dependency 'rspec'
|
26
|
+
gem.add_development_dependency 'rubocop'
|
27
|
+
gem.add_development_dependency 'simplecov'
|
28
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe RequestHeadersMiddleware::Middleware do
|
6
|
+
let(:app) { MockRackApp.new }
|
7
|
+
subject { described_class.new(app) }
|
8
|
+
|
9
|
+
context 'when MockRackApp called with a request' do
|
10
|
+
let(:env) do
|
11
|
+
Rack::MockRequest.env_for('/some/path', 'HTTP_X_REQUEST_ID' => '1234',
|
12
|
+
'HTTP_X_FORWARD' => '123',
|
13
|
+
'HTTP_X_REQUEST_ID1' => '12',
|
14
|
+
'CONTENT_TYPE' => 'text/plain')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns an empty Hash by default' do
|
18
|
+
expect(RequestHeadersMiddleware.store).to eq({})
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'only saves the X-Request-Id in RequestHeadersMiddleware.store' do
|
22
|
+
subject.call(env)
|
23
|
+
expect(app['CONTENT_TYPE']).to eq('text/plain')
|
24
|
+
expect(RequestHeadersMiddleware.store).to match('X-Request-Id': '1234')
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with whitelist' do
|
28
|
+
before do
|
29
|
+
RequestHeadersMiddleware.whitelist = [:'x-forward']
|
30
|
+
RequestHeadersMiddleware.blacklist = []
|
31
|
+
end
|
32
|
+
after do
|
33
|
+
RequestHeadersMiddleware.whitelist = []
|
34
|
+
RequestHeadersMiddleware.blacklist = []
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'only saves the X-Forward in RequestHeadersMiddleware.store' do
|
38
|
+
subject.call(env)
|
39
|
+
expect(app['CONTENT_TYPE']).to eq('text/plain')
|
40
|
+
expect(RequestHeadersMiddleware.store).to match('X-Forward': '123')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'with blacklist' do
|
45
|
+
before do
|
46
|
+
RequestHeadersMiddleware.whitelist = []
|
47
|
+
RequestHeadersMiddleware.blacklist = [:'x-forward']
|
48
|
+
end
|
49
|
+
after do
|
50
|
+
RequestHeadersMiddleware.whitelist = []
|
51
|
+
RequestHeadersMiddleware.blacklist = []
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'only saves the X-Forward in RequestHeadersMiddleware.store' do
|
55
|
+
subject.call(env)
|
56
|
+
expect(app['CONTENT_TYPE']).to eq('text/plain')
|
57
|
+
expect(RequestHeadersMiddleware.store)
|
58
|
+
.to match('X-Request-Id1': '12', 'X-Request-Id': '1234')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'with callbacks' do
|
63
|
+
before do
|
64
|
+
RequestHeadersMiddleware.whitelist = %I[x-request-id x-request-id1]
|
65
|
+
RequestHeadersMiddleware.blacklist = []
|
66
|
+
RequestHeadersMiddleware.callbacks = [
|
67
|
+
proc { |env| env['HTTP_X_REQUEST_ID'] = '4321' },
|
68
|
+
proc { |env| env['HTTP_X_REQUEST_ID1'] = '21' }
|
69
|
+
]
|
70
|
+
end
|
71
|
+
after do
|
72
|
+
RequestHeadersMiddleware.whitelist = []
|
73
|
+
RequestHeadersMiddleware.blacklist = []
|
74
|
+
RequestHeadersMiddleware.callbacks = nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'only saves the X-Forward in RequestHeadersMiddleware.store' do
|
78
|
+
subject.call(env)
|
79
|
+
expect(app['CONTENT_TYPE']).to eq('text/plain')
|
80
|
+
expect(app['HTTP_X_REQUEST_ID']).to eq('4321')
|
81
|
+
expect(RequestHeadersMiddleware.store)
|
82
|
+
.to match('X-Request-Id1': '12', 'X-Request-Id': '1234')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Notice there is a .rspec file in the root folder. It defines rspec arguments
|
4
|
+
|
5
|
+
# Ruby 1.9 uses simplecov. The ENV['COVERAGE'] is set when rake coverage
|
6
|
+
# is run in ruby 1.9
|
7
|
+
if ENV['COVERAGE']
|
8
|
+
require 'simplecov'
|
9
|
+
SimpleCov.start do
|
10
|
+
# Remove the spec folder from coverage. By default all code files are
|
11
|
+
# included.
|
12
|
+
# For more config options see
|
13
|
+
# https://github.com/colszowka/simplecov
|
14
|
+
add_filter File.expand_path('../spec', __dir__)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Modify load path so you can require 'ogstasher directly.
|
19
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
20
|
+
|
21
|
+
require 'rubygems'
|
22
|
+
# Loads bundler setup tasks. Now if I run spec without installing gems then it
|
23
|
+
# would say gem not installed and do bundle install instead of ugly load error
|
24
|
+
# on require.
|
25
|
+
require 'bundler/setup'
|
26
|
+
|
27
|
+
# This will require me all the gems automatically for the groups. If I do only
|
28
|
+
# .setup then I will have to require gems manually. Note that you have still
|
29
|
+
# have to require some gems if they are part of bigger gem like ActiveRecord
|
30
|
+
# which is part of Rails. You can say :require => false in gemfile to always
|
31
|
+
# use explicit requiring
|
32
|
+
Bundler.require(:test)
|
33
|
+
|
34
|
+
Dir[File.join('./spec/support/**/*.rb')].each { |f| require f }
|
35
|
+
|
36
|
+
# Set Rails environment as test
|
37
|
+
ENV['RAILS_ENV'] = 'test'
|
38
|
+
|
39
|
+
require 'request_headers_middleware'
|
40
|
+
require 'rack/mock'
|
41
|
+
|
42
|
+
RSpec.configure do |config|
|
43
|
+
config.run_all_when_everything_filtered = true
|
44
|
+
config.filter_run :focus
|
45
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MockRackApp
|
4
|
+
attr_reader :request_body
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@request_headers = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
@env = env
|
12
|
+
@request_body = env['rack.input'].read
|
13
|
+
[200, { 'Content-Type' => 'text/plain' }, ['OK']]
|
14
|
+
end
|
15
|
+
|
16
|
+
def [](key)
|
17
|
+
@env[key]
|
18
|
+
end
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: request_headers_middleware
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Marc Grimme
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-03-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: request_store
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rack
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: RequestHeader gives you per-req global header storage.
|
98
|
+
email:
|
99
|
+
- marc.grimme@gmail.com
|
100
|
+
executables:
|
101
|
+
- travis
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- ".rubocop.yml"
|
107
|
+
- ".ruby-version"
|
108
|
+
- ".travis.yml"
|
109
|
+
- Gemfile
|
110
|
+
- Gemfile.lock
|
111
|
+
- LICENSE.txt
|
112
|
+
- README.md
|
113
|
+
- Rakefile
|
114
|
+
- bin/travis
|
115
|
+
- lib/request_headers_middleware.rb
|
116
|
+
- lib/request_headers_middleware/middleware.rb
|
117
|
+
- lib/request_headers_middleware/railtie.rb
|
118
|
+
- lib/request_headers_middleware/version.rb
|
119
|
+
- request_headers_middleware.gemspec
|
120
|
+
- spec/request_headers_middleware_spec.rb
|
121
|
+
- spec/spec_helper.rb
|
122
|
+
- spec/support/mock_rack_app.rb
|
123
|
+
homepage: http://github.com/marcgrimme/request_headers_middleware
|
124
|
+
licenses:
|
125
|
+
- MIT
|
126
|
+
metadata: {}
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
requirements: []
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 2.5.2
|
144
|
+
signing_key:
|
145
|
+
specification_version: 4
|
146
|
+
summary: RequestStore gives you per-reqt global header storage.
|
147
|
+
test_files:
|
148
|
+
- spec/request_headers_middleware_spec.rb
|
149
|
+
- spec/spec_helper.rb
|
150
|
+
- spec/support/mock_rack_app.rb
|