sitehub 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|