sitehub 0.4.2 → 0.4.3
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 +4 -4
- data/.rubocop.yml +17 -0
- data/Gemfile +0 -2
- data/Gemfile.lock +15 -1
- data/README.md +23 -0
- data/Rakefile +3 -9
- data/circle.yml +6 -0
- data/lib/sitehub/builder.rb +19 -19
- data/lib/sitehub/collection/route_collection.rb +7 -9
- data/lib/sitehub/collection/split_route_collection/split.rb +7 -5
- data/lib/sitehub/collection/split_route_collection.rb +13 -10
- data/lib/sitehub/collection.rb +26 -21
- data/lib/sitehub/constants/http_header_keys.rb +2 -6
- data/lib/sitehub/constants/rack_http_header_keys.rb +2 -2
- data/lib/sitehub/constants.rb +3 -3
- data/lib/sitehub/cookie/attribute.rb +4 -4
- data/lib/sitehub/cookie/flag.rb +4 -5
- data/lib/sitehub/cookie.rb +10 -14
- data/lib/sitehub/cookie_rewriting.rb +11 -13
- data/lib/sitehub/forward_proxies.rb +12 -13
- data/lib/sitehub/forward_proxy.rb +38 -24
- data/lib/sitehub/forward_proxy_builder.rb +38 -21
- data/lib/sitehub/http_headers.rb +39 -26
- data/lib/sitehub/logging/access_logger.rb +39 -35
- data/lib/sitehub/logging/error_logger.rb +7 -7
- data/lib/sitehub/logging/log_entry.rb +6 -5
- data/lib/sitehub/logging/log_stash.rb +2 -2
- data/lib/sitehub/logging/log_wrapper.rb +5 -5
- data/lib/sitehub/logging.rb +1 -1
- data/lib/sitehub/middleware.rb +2 -2
- data/lib/sitehub/path_directive.rb +10 -10
- data/lib/sitehub/path_directives.rb +5 -4
- data/lib/sitehub/request_mapping.rb +13 -11
- data/lib/sitehub/resolver.rb +5 -6
- data/lib/sitehub/reverse_proxy.rb +16 -12
- data/lib/sitehub/rules.rb +2 -2
- data/lib/sitehub/string_sanitiser.rb +1 -1
- data/lib/sitehub/transaction_id.rb +3 -3
- data/lib/sitehub/version.rb +1 -1
- data/lib/sitehub.rb +1 -1
- data/sitehub.gemspec +27 -29
- data/spec/sitehub/builder_spec.rb +18 -20
- data/spec/sitehub/collection/route_collection_spec.rb +16 -14
- data/spec/sitehub/collection/split_route_collection_spec.rb +8 -10
- data/spec/sitehub/collection_spec.rb +7 -7
- data/spec/sitehub/cookie/attribute_spec.rb +3 -3
- data/spec/sitehub/cookie/flag_spec.rb +2 -2
- data/spec/sitehub/cookie_rewriting_spec.rb +15 -12
- data/spec/sitehub/cookie_spec.rb +7 -18
- data/spec/sitehub/error_handling_spec.rb +2 -3
- data/spec/sitehub/forward_proxies_spec.rb +16 -12
- data/spec/sitehub/forward_proxy_builder_spec.rb +53 -30
- data/spec/sitehub/forward_proxy_spec.rb +26 -22
- data/spec/sitehub/http_headers_spec.rb +17 -18
- data/spec/sitehub/integration_spec.rb +4 -5
- data/spec/sitehub/logging/access_logger_spec.rb +25 -24
- data/spec/sitehub/logging/error_logger_spec.rb +5 -7
- data/spec/sitehub/logging/log_entry_spec.rb +2 -5
- data/spec/sitehub/logging/log_stash_spec.rb +1 -3
- data/spec/sitehub/logging/log_wrapper_spec.rb +0 -4
- data/spec/sitehub/middleware_spec.rb +1 -5
- data/spec/sitehub/path_directive_spec.rb +4 -7
- data/spec/sitehub/path_directives_spec.rb +6 -7
- data/spec/sitehub/request_mapping_spec.rb +2 -5
- data/spec/sitehub/resolver_spec.rb +1 -1
- data/spec/sitehub/reverse_proxy_spec.rb +37 -31
- data/spec/sitehub/transaction_id_spec.rb +3 -3
- data/spec/sitehub_spec.rb +2 -4
- data/spec/support/async/callback.rb +11 -0
- data/spec/support/async/middleware.rb +25 -0
- data/spec/support/async/response_handler.rb +16 -0
- data/spec/support/async.rb +4 -0
- data/spec/support/patch/rack/response.rb +13 -21
- data/spec/support/shared_contexts/async_context.rb +3 -58
- data/spec/support/shared_contexts/middleware_context.rb +15 -17
- data/spec/support/shared_contexts/rack_test_context.rb +3 -3
- data/spec/support/shared_contexts/sitehub_context.rb +9 -4
- data/spec/support/silent_warnings.rb +2 -3
- data/tasks/code_quality.rake +15 -0
- data/tasks/gem_tasks.rake +1 -0
- data/tasks/support/console.rb +7 -0
- data/tasks/testing.rake +4 -0
- data/tasks/util_tasks.rake +7 -0
- metadata +27 -3
- data/spec/basket_spec.rb +0 -30
@@ -2,13 +2,12 @@ describe 'error handling' do
|
|
2
2
|
include_context :site_hub
|
3
3
|
include_context :async
|
4
4
|
|
5
|
-
|
6
5
|
before do
|
7
6
|
WebMock.enable!
|
8
7
|
end
|
9
8
|
context 'connectivity error' do
|
10
9
|
def app
|
11
|
-
@app||=
|
10
|
+
@app ||= Async::Middleware.new(rack_application)
|
12
11
|
ensure
|
13
12
|
WebMock.disable!
|
14
13
|
end
|
@@ -18,4 +17,4 @@ describe 'error handling' do
|
|
18
17
|
expect(last_response.status).to eq(500)
|
19
18
|
end
|
20
19
|
end
|
21
|
-
end
|
20
|
+
end
|
@@ -2,7 +2,6 @@ require 'sitehub/forward_proxies'
|
|
2
2
|
|
3
3
|
class SiteHub
|
4
4
|
describe ForwardProxies do
|
5
|
-
|
6
5
|
let(:base_url) { 'http://google.com' }
|
7
6
|
let(:application_root) { '/application_url' }
|
8
7
|
let(:forward_proxy_builder) do
|
@@ -29,27 +28,33 @@ class SiteHub
|
|
29
28
|
end
|
30
29
|
|
31
30
|
describe '#mapped_route' do
|
32
|
-
|
33
31
|
let(:request) { Rack::Request.new({}) }
|
34
|
-
let(:more_specific_proxy_builder)
|
32
|
+
let(:more_specific_proxy_builder) do
|
33
|
+
ForwardProxyBuilder.new(url: "#{base_url}/sub_url", mapped_path: "#{application_root}/sub_url")
|
34
|
+
end
|
35
35
|
|
36
36
|
context 'regex match on path' do
|
37
|
-
let(:fuzzy_matcher)
|
37
|
+
let(:fuzzy_matcher) do
|
38
|
+
ForwardProxyBuilder.new(url: "#{base_url}/$1/view", mapped_path: %r{#{application_root}/(.*)/view})
|
39
|
+
end
|
38
40
|
subject do
|
39
41
|
described_class.new.tap do |route_set|
|
40
|
-
|
41
42
|
route_set << fuzzy_matcher
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
46
|
it 'matches and subsitutes the captured group' do
|
46
|
-
|
47
|
+
mapped_endpoint = subject.mapped_route(path: "#{application_root}/123/view", request: request)
|
48
|
+
expected_endpoint = fuzzy_matcher.resolve(env: {})
|
49
|
+
expect(mapped_endpoint).to eq(expected_endpoint)
|
47
50
|
end
|
48
51
|
end
|
49
52
|
|
50
53
|
context 'exact match on path' do
|
51
54
|
it 'proxies to the requested path' do
|
52
|
-
|
55
|
+
mapped_endpoint = subject.mapped_route(path: application_root, request: request)
|
56
|
+
expected_endpoint = forward_proxy_builder.resolve(env: {})
|
57
|
+
expect(mapped_endpoint).to eq(expected_endpoint)
|
53
58
|
end
|
54
59
|
end
|
55
60
|
|
@@ -62,14 +67,14 @@ class SiteHub
|
|
62
67
|
end
|
63
68
|
|
64
69
|
it 'matches the first endpoint' do
|
65
|
-
|
70
|
+
expected_endpoint = more_specific_proxy_builder.resolve(env: {})
|
71
|
+
mapped_endpoint = subject.mapped_route(path: "#{application_root}/sub_url", request: request)
|
72
|
+
expect(mapped_endpoint).to eq(expected_endpoint)
|
66
73
|
end
|
67
74
|
end
|
68
75
|
end
|
69
76
|
|
70
|
-
|
71
77
|
describe '#call' do
|
72
|
-
|
73
78
|
context 'mapped_route not found' do
|
74
79
|
let(:app) do
|
75
80
|
subject
|
@@ -94,6 +99,5 @@ class SiteHub
|
|
94
99
|
end
|
95
100
|
end
|
96
101
|
end
|
97
|
-
|
98
102
|
end
|
99
|
-
end
|
103
|
+
end
|
@@ -1,9 +1,8 @@
|
|
1
|
+
# rubocop:disable Metrics/ClassLength
|
1
2
|
require 'sitehub/forward_proxy_builder'
|
2
3
|
|
3
4
|
class SiteHub
|
4
|
-
|
5
5
|
describe ForwardProxyBuilder do
|
6
|
-
|
7
6
|
include_context :middleware_test
|
8
7
|
|
9
8
|
subject do
|
@@ -58,30 +57,65 @@ class SiteHub
|
|
58
57
|
end
|
59
58
|
end
|
60
59
|
end
|
61
|
-
|
62
60
|
end
|
63
61
|
|
64
62
|
describe '#split' do
|
65
63
|
context 'duplicate label used' do
|
66
64
|
it 'raises an error' do
|
67
65
|
subject.split percentage: 10, url: :url, label: :label
|
68
|
-
|
66
|
+
|
67
|
+
expect { subject.split percentage: 10, url: :url, label: :label }
|
68
|
+
.to raise_exception(Collection::DuplicateVersionException, 'supply unique labels')
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
|
73
72
|
context 'split supplied' do
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
73
|
+
context 'block supplied' do
|
74
|
+
it 'stores a forward proxy builder' do
|
75
|
+
proc = proc do
|
76
|
+
default url: :url
|
77
|
+
end
|
78
|
+
|
79
|
+
subject.split(percentage: 50, &proc)
|
80
|
+
|
81
|
+
expected_builder = described_class.new(mapped_path: subject.mapped_path, &proc)
|
82
|
+
expected_split = SiteHub::Collection::SplitRouteCollection::Split.new(0, 50, expected_builder)
|
83
|
+
expect(subject.endpoints.values).to eq([expected_split])
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'block not supplied' do
|
88
|
+
it 'stores a split for the version' do
|
89
|
+
subject.split url: :url, label: :label, percentage: 50
|
90
|
+
|
91
|
+
expected_proxy = { ForwardProxy.new(url: :url, id: :label, sitehub_cookie_name: :cookie_name) => 50 }
|
92
|
+
expected = Collection::SplitRouteCollection.new(expected_proxy)
|
93
|
+
|
94
|
+
expect(subject.endpoints).to eq(expected)
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'label not supplied' do
|
98
|
+
it 'raises an error' do
|
99
|
+
expect { subject.split(url: :url, percentage: 50) }
|
100
|
+
.to raise_error(ForwardProxyBuilder::InvalidDefinitionException)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'url not supplied' do
|
105
|
+
it 'raises an error' do
|
106
|
+
expect { subject.split(label: :label, percentage: 50) }
|
107
|
+
.to raise_error(ForwardProxyBuilder::InvalidDefinitionException)
|
108
|
+
end
|
109
|
+
end
|
78
110
|
end
|
79
111
|
end
|
80
112
|
|
81
113
|
context 'routes defined' do
|
82
114
|
it 'throws and error' do
|
83
115
|
subject.route url: :url, label: :label
|
84
|
-
|
116
|
+
|
117
|
+
expect { subject.split(url: :url, label: :label, percentage: 50) }
|
118
|
+
.to raise_error(ForwardProxyBuilder::InvalidDefinitionException)
|
85
119
|
end
|
86
120
|
end
|
87
121
|
end
|
@@ -90,26 +124,27 @@ class SiteHub
|
|
90
124
|
it 'accepts a rule' do
|
91
125
|
subject.route url: :url, label: :current, rule: :rule
|
92
126
|
expected_route = ForwardProxy.new(url: :url, id: :current, rule: :rule, sitehub_cookie_name: :cookie_name)
|
93
|
-
expect(subject.endpoints).to eq(
|
127
|
+
expect(subject.endpoints).to eq(expected_route.id => expected_route)
|
94
128
|
end
|
95
129
|
|
96
130
|
context 'block supplied' do
|
97
131
|
context 'rule not supplied' do
|
98
132
|
it 'raise an error' do
|
99
|
-
|
133
|
+
expected_message = described_class::INVALID_ROUTE_DEF_MSG
|
134
|
+
expect { subject.route {} }.to raise_exception described_class::InvalidDefinitionException, expected_message
|
100
135
|
end
|
101
136
|
end
|
102
137
|
|
103
|
-
it '
|
138
|
+
it 'stores a proxy builder' do
|
104
139
|
rule = proc { true }
|
105
|
-
|
140
|
+
proc = proc do
|
106
141
|
route url: :url, label: :label1
|
107
142
|
end
|
108
143
|
|
109
|
-
subject.
|
144
|
+
subject.route(rule: rule, &proc)
|
110
145
|
|
111
|
-
|
112
|
-
expect(subject.
|
146
|
+
expected_builder = described_class.new(mapped_path: subject.mapped_path, &proc)
|
147
|
+
expect(subject.endpoints.values).to eq([expected_builder])
|
113
148
|
end
|
114
149
|
|
115
150
|
context 'invalid definitions inside block' do
|
@@ -125,9 +160,7 @@ class SiteHub
|
|
125
160
|
end
|
126
161
|
end
|
127
162
|
|
128
|
-
|
129
163
|
describe '#build' do
|
130
|
-
|
131
164
|
let(:rule) { proc {} }
|
132
165
|
|
133
166
|
context 'middleware not specified' do
|
@@ -144,12 +177,10 @@ class SiteHub
|
|
144
177
|
subject.route url: :url, label: :current, rule: rule
|
145
178
|
expect(subject.endpoints[:current]).to_not receive(:extend).with(Resolver)
|
146
179
|
subject.build
|
147
|
-
|
148
180
|
end
|
149
181
|
end
|
150
182
|
|
151
183
|
context 'middleware specified' do
|
152
|
-
|
153
184
|
before do
|
154
185
|
subject.use middleware
|
155
186
|
subject.route url: :url, label: :current, rule: rule
|
@@ -162,7 +193,6 @@ class SiteHub
|
|
162
193
|
proxy_after_build = subject.endpoints[:current]
|
163
194
|
expect(proxy_after_build).to be_a(middleware)
|
164
195
|
expect(proxy_after_build.app).to be(proxy_before_build)
|
165
|
-
|
166
196
|
end
|
167
197
|
|
168
198
|
it 'extends the middleware with Resolver' do
|
@@ -192,10 +222,8 @@ class SiteHub
|
|
192
222
|
expect(default_proxy_after_build.app).to be(default_proxy_before_build)
|
193
223
|
end
|
194
224
|
end
|
195
|
-
|
196
225
|
end
|
197
226
|
describe '#resolve' do
|
198
|
-
|
199
227
|
subject { described_class.new(mapped_path: '/') }
|
200
228
|
|
201
229
|
context 'routes defined' do
|
@@ -239,12 +267,9 @@ class SiteHub
|
|
239
267
|
expect { subject.endpoints(:collection2) }.to raise_exception described_class::InvalidDefinitionException
|
240
268
|
end
|
241
269
|
end
|
242
|
-
|
243
270
|
end
|
244
271
|
|
245
|
-
|
246
272
|
context 'version selected' do
|
247
|
-
|
248
273
|
context 'version applies to a route' do
|
249
274
|
before do
|
250
275
|
subject.split percentage: 50, url: :url1, label: :new
|
@@ -270,7 +295,6 @@ class SiteHub
|
|
270
295
|
end
|
271
296
|
end
|
272
297
|
end
|
273
|
-
|
274
298
|
end
|
275
299
|
end
|
276
300
|
|
@@ -291,5 +315,4 @@ class SiteHub
|
|
291
315
|
end
|
292
316
|
end
|
293
317
|
end
|
294
|
-
|
295
|
-
end
|
318
|
+
end
|
@@ -1,13 +1,22 @@
|
|
1
|
+
# rubocop:disable Metrics/ClassLength
|
1
2
|
require 'sitehub/forward_proxy'
|
2
3
|
|
3
4
|
class SiteHub
|
4
5
|
describe ForwardProxy do
|
5
|
-
|
6
|
-
let(:current_version_url) { 'http://does.not.exist.com' }
|
6
|
+
let(:current_version_url) { 'http://127.0.0.1:10111' }
|
7
7
|
let(:mapped_path) { '/path' }
|
8
8
|
|
9
|
+
let(:expected_mapping) do
|
10
|
+
RequestMapping.new(source_url: "http://example.org#{mapped_path}",
|
11
|
+
mapped_url: current_version_url,
|
12
|
+
mapped_path: mapped_path)
|
13
|
+
end
|
14
|
+
|
9
15
|
subject do
|
10
|
-
described_class.new(id: :id,
|
16
|
+
described_class.new(id: :id,
|
17
|
+
url: current_version_url,
|
18
|
+
mapped_path: mapped_path,
|
19
|
+
sitehub_cookie_name: :cookie_name)
|
11
20
|
end
|
12
21
|
|
13
22
|
let(:app) do
|
@@ -25,7 +34,7 @@ class SiteHub
|
|
25
34
|
describe '#call' do
|
26
35
|
before do
|
27
36
|
WebMock.enable!
|
28
|
-
stub_request(:get, current_version_url).to_return(:
|
37
|
+
stub_request(:get, current_version_url).to_return(body: 'body')
|
29
38
|
end
|
30
39
|
|
31
40
|
context 'recorded routes cookie' do
|
@@ -42,8 +51,7 @@ class SiteHub
|
|
42
51
|
end
|
43
52
|
|
44
53
|
context 'recorded_routes_cookie_path set' do
|
45
|
-
|
46
|
-
let(:expected_path){'/expected_path'}
|
54
|
+
let(:expected_path) { '/expected_path' }
|
47
55
|
|
48
56
|
subject do
|
49
57
|
described_class.new(id: :id,
|
@@ -60,11 +68,9 @@ class SiteHub
|
|
60
68
|
end
|
61
69
|
end
|
62
70
|
|
63
|
-
|
64
|
-
|
65
71
|
it 'passes request mapping information in to the environment hash' do
|
66
72
|
get(mapped_path, {})
|
67
|
-
expect(last_request.env[REQUEST_MAPPING]).to eq(
|
73
|
+
expect(last_request.env[REQUEST_MAPPING]).to eq(expected_mapping)
|
68
74
|
end
|
69
75
|
|
70
76
|
context 'downstream call' do
|
@@ -73,15 +79,15 @@ class SiteHub
|
|
73
79
|
WebMock.disable!
|
74
80
|
end
|
75
81
|
it 'adds an error to be logged' do
|
76
|
-
env = {ERRORS.to_s => []}
|
82
|
+
env = { ERRORS.to_s => [] }
|
77
83
|
get(mapped_path, {}, env)
|
78
|
-
expect(last_request.env[ERRORS]).
|
84
|
+
expect(last_request.env[ERRORS]).to_not be_empty
|
79
85
|
end
|
80
86
|
|
81
87
|
describe 'parameters to callback' do
|
82
88
|
it 'calls the callback with an error response' do
|
83
89
|
expect(described_class::ERROR_RESPONSE).to receive(:dup).and_return(described_class::ERROR_RESPONSE)
|
84
|
-
env = {ERRORS.to_s => []}
|
90
|
+
env = { ERRORS.to_s => [] }
|
85
91
|
get(mapped_path, {}, env)
|
86
92
|
|
87
93
|
expect(last_response.body).to eq(described_class::ERROR_RESPONSE.body.join)
|
@@ -90,14 +96,13 @@ class SiteHub
|
|
90
96
|
end
|
91
97
|
|
92
98
|
it 'passes the request mapping' do
|
93
|
-
env = { ERRORS.to_s => []}
|
99
|
+
env = { ERRORS.to_s => [] }
|
94
100
|
get(mapped_path, {}, env)
|
95
|
-
expect(last_request.env[REQUEST_MAPPING]).to eq(
|
101
|
+
expect(last_request.env[REQUEST_MAPPING]).to eq(expected_mapping)
|
96
102
|
end
|
97
103
|
end
|
98
104
|
end
|
99
105
|
|
100
|
-
|
101
106
|
it 'translates the header names back in to the http compatible names' do
|
102
107
|
get(mapped_path, {})
|
103
108
|
expect(last_response.headers).to include('Content-Length')
|
@@ -108,31 +113,30 @@ class SiteHub
|
|
108
113
|
context 'when not present in the original request' do
|
109
114
|
it 'appends original request url with port' do
|
110
115
|
get(mapped_path, {})
|
111
|
-
assert_requested :get, current_version_url, headers: {'X-FORWARDED-HOST' => 'example.org:80'}
|
116
|
+
assert_requested :get, current_version_url, headers: { 'X-FORWARDED-HOST' => 'example.org:80' }
|
112
117
|
end
|
113
118
|
end
|
114
119
|
|
115
120
|
context 'when present in the original request' do
|
116
121
|
it 'appends original request url without port' do
|
117
122
|
get(mapped_path, {}, 'HTTP_X_FORWARDED_HOST' => 'staging.com')
|
118
|
-
assert_requested :get, current_version_url, headers: {'X-FORWARDED-HOST' => 'staging.com,staging.com'}
|
123
|
+
assert_requested :get, current_version_url, headers: { 'X-FORWARDED-HOST' => 'staging.com,staging.com' }
|
119
124
|
end
|
120
125
|
end
|
121
126
|
|
122
127
|
it 'preserves the body when forwarding request' do
|
123
|
-
body = {
|
124
|
-
stub_request(:put, current_version_url).with(:
|
128
|
+
body = { 'key' => 'value' }
|
129
|
+
stub_request(:put, current_version_url).with(body: body)
|
125
130
|
|
126
131
|
put(mapped_path, body)
|
127
132
|
end
|
128
133
|
|
129
134
|
it 'preserves the headers when forwarding request' do
|
130
135
|
get(mapped_path, '', 'HTTP_HEADER' => 'value')
|
131
|
-
assert_requested :get, current_version_url, headers: {'Header' => 'value'}
|
136
|
+
assert_requested :get, current_version_url, headers: { 'Header' => 'value' }
|
132
137
|
end
|
133
138
|
end
|
134
|
-
|
135
139
|
end
|
136
140
|
end
|
137
141
|
end
|
138
|
-
end
|
142
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'sitehub/http_headers'
|
2
2
|
class SiteHub
|
3
3
|
describe HttpHeaders do
|
4
|
-
|
5
4
|
subject do
|
6
5
|
Object.new.tap do |o|
|
7
6
|
o.extend(described_class)
|
@@ -9,27 +8,26 @@ class SiteHub
|
|
9
8
|
end
|
10
9
|
|
11
10
|
let(:headers_underscored) do
|
12
|
-
{'CONNECTION' => 'close',
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
11
|
+
{ 'CONNECTION' => 'close',
|
12
|
+
'KEEP_ALIVE' => 'something',
|
13
|
+
'PROXY_AUTHENTICATE' => 'something',
|
14
|
+
'PROXY_AUTHORIZATION' => 'something',
|
15
|
+
'TE' => 'something',
|
16
|
+
'TRAILERS' => 'something',
|
17
|
+
'TRANSFER_ENCODING' => 'something',
|
18
|
+
'CONTENT_ENCODING' => 'something',
|
19
|
+
'PROXY_CONNECTION' => 'something' }
|
21
20
|
end
|
22
21
|
|
23
22
|
let(:headers_hyphonised) do
|
24
|
-
|
23
|
+
{}.tap do |hash|
|
25
24
|
headers_underscored.each do |key, value|
|
26
|
-
hash[key.
|
25
|
+
hash[key.tr('_', '-')] = value
|
27
26
|
end
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
31
30
|
describe '#sanitise_headers' do
|
32
|
-
|
33
31
|
context 'port 80 present in url' do
|
34
32
|
it 'removes the port' do
|
35
33
|
headers_hyphonised['location'] = 'http://mysite.com:80/redirect_endpoint'
|
@@ -60,12 +58,13 @@ class SiteHub
|
|
60
58
|
end
|
61
59
|
|
62
60
|
it 'filters out connections' do
|
63
|
-
headers = subject.sanitise_headers('connection' => 'a, b',
|
61
|
+
headers = subject.sanitise_headers('connection' => 'a, b',
|
62
|
+
'a' => 'value_a',
|
63
|
+
'b' => 'value_b', 'c' => 'value_c')
|
64
|
+
|
64
65
|
expect(headers).to eq('c' => 'value_c')
|
65
66
|
end
|
66
67
|
end
|
67
68
|
end
|
68
|
-
|
69
|
-
|
70
69
|
end
|
71
|
-
end
|
70
|
+
end
|
@@ -3,19 +3,18 @@ describe 'proxying calls' do
|
|
3
3
|
include_context :async
|
4
4
|
|
5
5
|
describe 'supported HTTP verbs' do
|
6
|
-
|
7
6
|
before do
|
8
7
|
WebMock.enable!
|
9
8
|
end
|
10
9
|
|
11
|
-
let(:app){
|
10
|
+
let(:app) { Async::Middleware.new(rack_application) }
|
12
11
|
|
13
12
|
%i(get post put delete).each do |verb|
|
14
|
-
it
|
15
|
-
stub_request(verb, downstream_url).to_return(:
|
13
|
+
it 'forwards the downstream' do
|
14
|
+
stub_request(verb, downstream_url).to_return(body: 'hello')
|
16
15
|
send(verb, '/endpoint')
|
17
16
|
expect(app.last_response.body).to eq(['hello'])
|
18
17
|
end
|
19
18
|
end
|
20
19
|
end
|
21
|
-
end
|
20
|
+
end
|
@@ -1,16 +1,19 @@
|
|
1
|
+
require 'sitehub/constants'
|
1
2
|
require 'sitehub/logging/access_logger'
|
2
3
|
require 'stringio'
|
3
4
|
|
4
5
|
class SiteHub
|
5
6
|
module Logging
|
6
7
|
describe AccessLogger do
|
8
|
+
RackHttpHeaderKeys = Constants::RackHttpHeaderKeys
|
9
|
+
HttpHeaderKeys = Constants::HttpHeaderKeys
|
7
10
|
|
8
11
|
let(:logger) do
|
9
12
|
StringIO.new
|
10
13
|
end
|
11
14
|
|
12
15
|
let(:app) do
|
13
|
-
proc{[200, {}, []]}
|
16
|
+
proc { [200, {}, []] }
|
14
17
|
end
|
15
18
|
|
16
19
|
subject do
|
@@ -18,7 +21,6 @@ class SiteHub
|
|
18
21
|
end
|
19
22
|
|
20
23
|
describe '#initialize' do
|
21
|
-
|
22
24
|
context 'logger supplied' do
|
23
25
|
it 'sets logger to that logger' do
|
24
26
|
expect(described_class.new(:app, :custom_logger).logger).to eq(LogWrapper.new(:custom_logger))
|
@@ -35,19 +37,20 @@ class SiteHub
|
|
35
37
|
|
36
38
|
describe '#call' do
|
37
39
|
let(:env) do
|
38
|
-
{
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
}
|
40
|
+
{ REQUEST_MAPPING => request_mapping,
|
41
|
+
RackHttpHeaderKeys::QUERY_STRING => '',
|
42
|
+
RackHttpHeaderKeys::PATH_INFO => 'path_info',
|
43
|
+
RackHttpHeaderKeys::TRANSACTION_ID => :transaction_id,
|
44
|
+
RackHttpHeaderKeys::HTTP_VERSION => '1.1' }
|
45
|
+
end
|
45
46
|
|
47
|
+
let(:request_mapping) do
|
48
|
+
RequestMapping.new(source_url: :source_url, mapped_url: :mapped_url.to_s, mapped_path: :mapped_path.to_s)
|
46
49
|
end
|
47
|
-
|
50
|
+
|
48
51
|
before { subject.call(env) }
|
49
52
|
|
50
|
-
let(:args) { {request_mapping: request_mapping, downstream_response: Rack::Response.new} }
|
53
|
+
let(:args) { { request_mapping: request_mapping, downstream_response: Rack::Response.new } }
|
51
54
|
it 'logs the request / response details in the required format' do
|
52
55
|
expect(subject).to receive(:log_template).and_return(:template.to_s)
|
53
56
|
expect(logger).to receive(:write).with(:template.to_s)
|
@@ -56,19 +59,19 @@ class SiteHub
|
|
56
59
|
end
|
57
60
|
|
58
61
|
context 'query string' do
|
59
|
-
let(:query_string) {
|
62
|
+
let(:query_string) { RackHttpHeaderKeys::QUERY_STRING }
|
60
63
|
context 'present' do
|
61
64
|
it 'logs it' do
|
62
65
|
env[query_string] = 'query'
|
63
66
|
subject.call(env)
|
64
|
-
expect(logger.string).to include(
|
67
|
+
expect(logger.string).to include('?query')
|
65
68
|
end
|
66
69
|
end
|
67
70
|
|
68
71
|
context 'not present' do
|
69
72
|
it 'is not logged' do
|
70
73
|
subject.call(env)
|
71
|
-
expect(logger.string).to_not include(
|
74
|
+
expect(logger.string).to_not include('?')
|
72
75
|
end
|
73
76
|
end
|
74
77
|
end
|
@@ -76,7 +79,7 @@ class SiteHub
|
|
76
79
|
it 'logs the transaction id' do
|
77
80
|
subject.call(env)
|
78
81
|
|
79
|
-
expect(logger.string).to include(
|
82
|
+
expect(logger.string).to include('transaction_id:transaction_id')
|
80
83
|
end
|
81
84
|
|
82
85
|
it 'logs the response status' do
|
@@ -85,22 +88,21 @@ class SiteHub
|
|
85
88
|
expect(logger.string).to include(args[:downstream_response].status.to_s)
|
86
89
|
end
|
87
90
|
|
88
|
-
|
89
91
|
it 'logs the downstream url that was proxied to' do
|
90
92
|
subject.call(env)
|
91
93
|
|
92
|
-
expect(logger.string).to include("#{env[
|
94
|
+
expect(logger.string).to include("#{env[RackHttpHeaderKeys::PATH_INFO]} => mapped_url")
|
93
95
|
end
|
94
96
|
|
95
97
|
context '404 returned, i.e. no downstream call made' do
|
96
98
|
let(:request_mapping) { nil }
|
97
99
|
it 'does not log the down stream url' do
|
98
100
|
subject.call(env)
|
99
|
-
expect(logger.string).to include("=> #{EMPTY_STRING} #{env[
|
101
|
+
expect(logger.string).to include("=> #{EMPTY_STRING} #{env[RackHttpHeaderKeys::HTTP_VERSION]}")
|
100
102
|
end
|
101
103
|
end
|
102
|
-
|
103
104
|
end
|
105
|
+
|
104
106
|
describe '#extract_content_length' do
|
105
107
|
context 'content length header not present' do
|
106
108
|
it 'returns -' do
|
@@ -109,19 +111,18 @@ class SiteHub
|
|
109
111
|
end
|
110
112
|
|
111
113
|
context 'content length header not present' do
|
112
|
-
let(:content_length) {
|
114
|
+
let(:content_length) { HttpHeaderKeys::CONTENT_LENGTH }
|
113
115
|
context 'it is 0' do
|
114
116
|
it 'returns -' do
|
115
|
-
expect(subject.extract_content_length(
|
117
|
+
expect(subject.extract_content_length(content_length => 0)).to eq('-')
|
116
118
|
end
|
117
119
|
end
|
118
120
|
context 'it is set to a number other than 0'
|
119
121
|
it 'returns the number' do
|
120
|
-
expect(subject.extract_content_length(
|
122
|
+
expect(subject.extract_content_length(content_length => 5)).to eq(5)
|
121
123
|
end
|
122
124
|
end
|
123
|
-
|
124
125
|
end
|
125
126
|
end
|
126
127
|
end
|
127
|
-
end
|
128
|
+
end
|