sitehub 0.4.3 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +31 -0
  3. data/.gitignore +2 -1
  4. data/.reek +41 -0
  5. data/.simplecov +7 -0
  6. data/Gemfile.lock +61 -33
  7. data/README.md +4 -0
  8. data/Rakefile +1 -1
  9. data/circle.yml +1 -1
  10. data/lib/sitehub/builder.rb +19 -36
  11. data/lib/sitehub/collection/split_route_collection.rb +18 -13
  12. data/lib/sitehub/collection/split_route_collection/split.rb +6 -4
  13. data/lib/sitehub/constants.rb +2 -1
  14. data/lib/sitehub/constants/http_header_keys.rb +2 -0
  15. data/lib/sitehub/constants/rack_http_header_keys.rb +2 -0
  16. data/lib/sitehub/cookie.rb +4 -13
  17. data/lib/sitehub/cookie/attribute.rb +10 -9
  18. data/lib/sitehub/cookie/flag.rb +5 -8
  19. data/lib/sitehub/cookie_rewriting.rb +12 -5
  20. data/lib/sitehub/downstream_client.rb +37 -0
  21. data/lib/sitehub/equality.rb +28 -0
  22. data/lib/sitehub/forward_proxy.rb +19 -62
  23. data/lib/sitehub/forward_proxy_builder.rb +70 -49
  24. data/lib/sitehub/getter_setter_methods.rb +21 -0
  25. data/lib/sitehub/http_headers.rb +45 -48
  26. data/lib/sitehub/location_rewriter.rb +29 -0
  27. data/lib/sitehub/location_rewriters.rb +23 -0
  28. data/lib/sitehub/memoize.rb +25 -0
  29. data/lib/sitehub/middleware.rb +16 -6
  30. data/lib/sitehub/middleware/error_handling.rb +20 -0
  31. data/lib/sitehub/middleware/forward_proxies.rb +54 -0
  32. data/lib/sitehub/{logging.rb → middleware/logging.rb} +0 -0
  33. data/lib/sitehub/middleware/logging/access_logger.rb +36 -0
  34. data/lib/sitehub/middleware/logging/error_logger.rb +38 -0
  35. data/lib/sitehub/middleware/logging/log_entry.rb +16 -0
  36. data/lib/sitehub/middleware/logging/log_stash.rb +12 -0
  37. data/lib/sitehub/middleware/logging/log_wrapper.rb +24 -0
  38. data/lib/sitehub/middleware/logging/request_log.rb +74 -0
  39. data/lib/sitehub/middleware/reverse_proxy.rb +37 -0
  40. data/lib/sitehub/middleware/transaction_id.rb +18 -0
  41. data/lib/sitehub/nil_location_rewriter.rb +7 -0
  42. data/lib/sitehub/nil_proxy.rb +11 -0
  43. data/lib/sitehub/request.rb +101 -0
  44. data/lib/sitehub/request_mapping.rb +16 -18
  45. data/lib/sitehub/resolver.rb +1 -1
  46. data/lib/sitehub/response.rb +10 -0
  47. data/lib/sitehub/string_utils.rb +13 -0
  48. data/lib/sitehub/version.rb +1 -1
  49. data/sitehub.gemspec +4 -1
  50. data/spec/equality_spec.rb +32 -0
  51. data/spec/sitehub/builder_spec.rb +29 -22
  52. data/spec/sitehub/collection/route_collection_spec.rb +15 -14
  53. data/spec/sitehub/collection/split_route_collection/split_spec.rb +26 -0
  54. data/spec/sitehub/collection/split_route_collection_spec.rb +15 -3
  55. data/spec/sitehub/cookie/flag_spec.rb +1 -1
  56. data/spec/sitehub/cookie_rewriting_spec.rb +6 -10
  57. data/spec/sitehub/downstream_client_spec.rb +72 -0
  58. data/spec/sitehub/equality_spec.rb +32 -0
  59. data/spec/sitehub/forward_proxy_builder_spec.rb +92 -55
  60. data/spec/sitehub/forward_proxy_spec.rb +29 -97
  61. data/spec/sitehub/http_headers_spec.rb +32 -52
  62. data/spec/sitehub/integration_spec.rb +1 -1
  63. data/spec/sitehub/location_rewriter_spec.rb +46 -0
  64. data/spec/sitehub/{path_directives_spec.rb → location_rewriters_spec.rb} +8 -8
  65. data/spec/sitehub/memoize_spec.rb +56 -0
  66. data/spec/sitehub/middleware/error_handling_spec.rb +34 -0
  67. data/spec/sitehub/middleware/forward_proxies_spec.rb +105 -0
  68. data/spec/sitehub/middleware/logging/access_logger_spec.rb +51 -0
  69. data/spec/sitehub/middleware/logging/error_logger_spec.rb +84 -0
  70. data/spec/sitehub/middleware/logging/log_entry_spec.rb +33 -0
  71. data/spec/sitehub/middleware/logging/log_stash_spec.rb +21 -0
  72. data/spec/sitehub/middleware/logging/log_wrapper_spec.rb +31 -0
  73. data/spec/sitehub/middleware/logging/request_log_spec.rb +108 -0
  74. data/spec/sitehub/middleware/reverse_proxy_spec.rb +113 -0
  75. data/spec/sitehub/middleware/transaction_id_spec.rb +30 -0
  76. data/spec/sitehub/middleware_spec.rb +23 -13
  77. data/spec/sitehub/nil_location_rewriter_spec.rb +10 -0
  78. data/spec/sitehub/nil_proxy_spec.rb +14 -0
  79. data/spec/sitehub/request_mapping_spec.rb +21 -23
  80. data/spec/sitehub/request_spec.rb +228 -0
  81. data/spec/sitehub/resolver_spec.rb +2 -5
  82. data/spec/sitehub/response_spec.rb +30 -0
  83. data/spec/spec_helper.rb +12 -6
  84. data/spec/support/async/middleware.rb +1 -0
  85. data/spec/support/patch/rack/response.rb +7 -5
  86. data/spec/support/shared_contexts.rb +3 -0
  87. data/spec/support/shared_contexts/http_proxy_rules_context.rb +36 -0
  88. data/spec/support/shared_contexts/middleware_context.rb +6 -6
  89. data/spec/support/shared_contexts/module_spec_context.rb +7 -0
  90. data/spec/support/shared_contexts/rack_request_context.rb +18 -0
  91. data/spec/support/shared_contexts/rack_test_context.rb +0 -1
  92. data/spec/support/shared_examples.rb +3 -0
  93. data/spec/support/shared_examples/memoized_helpers.rb +7 -0
  94. data/spec/support/shared_examples/prohibited_http_header_filter.rb +16 -0
  95. data/spec/support/silent_warnings.rb +1 -1
  96. data/tasks/code_quality.rake +6 -0
  97. metadata +99 -29
  98. data/lib/sitehub/forward_proxies.rb +0 -49
  99. data/lib/sitehub/logging/access_logger.rb +0 -78
  100. data/lib/sitehub/logging/error_logger.rb +0 -36
  101. data/lib/sitehub/logging/log_entry.rb +0 -15
  102. data/lib/sitehub/logging/log_stash.rb +0 -10
  103. data/lib/sitehub/logging/log_wrapper.rb +0 -23
  104. data/lib/sitehub/path_directive.rb +0 -32
  105. data/lib/sitehub/path_directives.rb +0 -22
  106. data/lib/sitehub/reverse_proxy.rb +0 -57
  107. data/lib/sitehub/string_sanitiser.rb +0 -7
  108. data/lib/sitehub/transaction_id.rb +0 -16
  109. data/spec/sitehub/error_handling_spec.rb +0 -20
  110. data/spec/sitehub/forward_proxies_spec.rb +0 -103
  111. data/spec/sitehub/logging/access_logger_spec.rb +0 -128
  112. data/spec/sitehub/logging/error_logger_spec.rb +0 -78
  113. data/spec/sitehub/logging/log_entry_spec.rb +0 -31
  114. data/spec/sitehub/logging/log_stash_spec.rb +0 -19
  115. data/spec/sitehub/logging/log_wrapper_spec.rb +0 -29
  116. data/spec/sitehub/path_directive_spec.rb +0 -47
  117. data/spec/sitehub/reverse_proxy_spec.rb +0 -111
  118. data/spec/sitehub/transaction_id_spec.rb +0 -28
  119. data/spec/support/async/response_handler.rb +0 -16
  120. data/spec/support/shared_contexts/async_context.rb +0 -14
@@ -0,0 +1,105 @@
1
+ require 'sitehub/middleware/forward_proxies'
2
+
3
+ class SiteHub
4
+ module Middleware
5
+ describe ForwardProxies do
6
+ let(:base_url) { 'http://google.com' }
7
+ let(:application_root) { '/application_url' }
8
+ let(:forward_proxy_builder) do
9
+ ForwardProxyBuilder.new(mapped_path: application_root).tap do |builder|
10
+ builder.split url: base_url, label: :current, percentage: 100
11
+ end
12
+ end
13
+
14
+ subject do
15
+ described_class.new.tap do |route_set|
16
+ route_set << forward_proxy_builder
17
+ end
18
+ end
19
+
20
+ before do
21
+ subject.init
22
+ end
23
+
24
+ describe '#init' do
25
+ it 'builds all of the forward_proxies' do
26
+ expect(subject.forward_proxies[application_root]).to receive(:build).and_call_original
27
+ subject.init
28
+ end
29
+ end
30
+
31
+ describe '#mapped_route' do
32
+ let(:request) { Rack::Request.new({}) }
33
+ let(:more_specific_proxy_builder) do
34
+ ForwardProxyBuilder.new(url: "#{base_url}/sub_url", mapped_path: "#{application_root}/sub_url")
35
+ end
36
+
37
+ context 'regex match on path' do
38
+ let(:fuzzy_matcher) do
39
+ ForwardProxyBuilder.new(url: "#{base_url}/$1/view", mapped_path: %r{#{application_root}/(.*)/view})
40
+ end
41
+ subject do
42
+ described_class.new.tap do |route_set|
43
+ route_set << fuzzy_matcher
44
+ end
45
+ end
46
+
47
+ it 'matches and subsitutes the captured group' do
48
+ mapped_endpoint = subject.mapped_proxy(path: "#{application_root}/123/view", request: request)
49
+ expected_endpoint = fuzzy_matcher.resolve(env: {})
50
+ expect(mapped_endpoint).to eq(expected_endpoint)
51
+ end
52
+ end
53
+
54
+ context 'exact match on path' do
55
+ it 'proxies to the requested path' do
56
+ mapped_endpoint = subject.mapped_proxy(path: application_root, request: request)
57
+ expected_endpoint = forward_proxy_builder.resolve(env: {})
58
+ expect(mapped_endpoint).to eq(expected_endpoint)
59
+ end
60
+ end
61
+
62
+ context 'when more specific route is configured first' do
63
+ subject do
64
+ described_class.new.tap do |route_set|
65
+ route_set << more_specific_proxy_builder
66
+ route_set << forward_proxy_builder
67
+ end
68
+ end
69
+
70
+ it 'matches the first endpoint' do
71
+ expected_endpoint = more_specific_proxy_builder.resolve(env: {})
72
+ mapped_endpoint = subject.mapped_proxy(path: "#{application_root}/sub_url", request: request)
73
+ expect(mapped_endpoint).to eq(expected_endpoint)
74
+ end
75
+ end
76
+ end
77
+
78
+ describe '#call' do
79
+ context 'mapped_route not found' do
80
+ let(:app) do
81
+ subject
82
+ end
83
+
84
+ it 'returns a 404' do
85
+ expect(get('/missing').status).to eq(404)
86
+ end
87
+ end
88
+
89
+ context 'mapped_route found' do
90
+ let(:app) do
91
+ subject
92
+ end
93
+
94
+ it 'uses the forward proxy' do
95
+ subject
96
+ expect(forward_proxy_builder.endpoints[:current]).to receive(:call) do
97
+ [200, {}, []]
98
+ end
99
+ expect(get(application_root).status).to eq(200)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,51 @@
1
+ require 'sitehub/constants'
2
+ require 'sitehub/middleware/logging/access_logger'
3
+ require 'stringio'
4
+
5
+ class SiteHub
6
+ module Middleware
7
+ module Logging
8
+ describe AccessLogger do
9
+ include_context :rack_request
10
+
11
+ let(:logger) { StringIO.new }
12
+
13
+ let(:env) { env_for(path: '/') }
14
+
15
+ subject do
16
+ described_class.new(app, logger)
17
+ end
18
+
19
+ describe '#initialize' do
20
+ context 'logger supplied' do
21
+ it 'sets logger to that logger' do
22
+ expect(described_class.new(:app, :custom_logger).logger).to eq(LogWrapper.new(:custom_logger))
23
+ end
24
+ end
25
+
26
+ context 'logger not supplied' do
27
+ it 'sets the logger to go to STDERR' do
28
+ expect(::Logger).to receive(:new).with(STDOUT).and_return(:logging)
29
+ expect(described_class.new(:app).logger).to eq(LogWrapper.new(:logging))
30
+ end
31
+ end
32
+ end
33
+
34
+ describe '#call' do
35
+ let(:expected_response) { Response.new([], 200, {}) }
36
+
37
+ let(:app) do
38
+ proc { expected_response }
39
+ end
40
+
41
+ it 'logs the request / response details' do
42
+ expected_request = Request.new(env: env)
43
+
44
+ subject.call(env)
45
+ expect(logger.string).to eq(RequestLog.new(expected_request, expected_response).to_s)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,84 @@
1
+ require 'sitehub/middleware/logging/error_logger'
2
+
3
+ class SiteHub
4
+ module Middleware
5
+ module Logging
6
+ describe ErrorLogger do
7
+ let(:app) { proc { [200, {}, []] } }
8
+ subject { described_class.new(app) }
9
+
10
+ describe '#initialize' do
11
+ context 'logger supplied' do
12
+ it 'sets logger to that logger' do
13
+ expect(described_class.new(:app, :custom_logger).logger).to eq(LogWrapper.new(:custom_logger))
14
+ end
15
+ end
16
+
17
+ context 'logger not supplied' do
18
+ it 'sets the logger to go to STDERR' do
19
+ expect(::Logger).to receive(:new).with(STDERR).and_return(:logging)
20
+ expect(described_class.new(:app).logger).to eq(LogWrapper.new(:logging))
21
+ end
22
+ end
23
+ end
24
+
25
+ describe '#before_call' do
26
+ it 'adds a collection hold errors' do
27
+ env = {}
28
+ subject.call(env)
29
+ expect(env[ERRORS]).to eq([])
30
+ end
31
+ end
32
+
33
+ describe '#call' do
34
+ let(:output) { StringIO.new }
35
+ let(:logger) { Logger.new(output) }
36
+ let(:error_message) { 'error' }
37
+ let(:errors) do
38
+ Logging::LogStash.new.tap do |stash|
39
+ stash << error_message
40
+ end
41
+ end
42
+ subject { described_class.new(app, logger) }
43
+
44
+ context 'errors have occurred' do
45
+ it 'logs errors' do
46
+ log_message = subject.log_message(error: error_message, transaction_id: :transaction_id)
47
+ subject.call(ERRORS => errors, Constants::RackHttpHeaderKeys::TRANSACTION_ID => :transaction_id)
48
+ expect(output.string).to eq(log_message)
49
+ end
50
+ end
51
+
52
+ context 'no errors have occured' do
53
+ it 'does not log anything' do
54
+ expect(logger).to_not receive(:write)
55
+ subject.call(ERRORS => [])
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '#log_message' do
61
+ let(:error) { 'error' }
62
+
63
+ it 'contains the time and date' do
64
+ now = Time.now
65
+ expect(Time).to receive(:now).and_return(now)
66
+ log_message = subject.log_message(error: error, transaction_id: :transaction_id)
67
+ expected_time = now.strftime('%d/%b/%Y:%H:%M:%S %z')
68
+ expect(log_message).to start_with("[#{expected_time}]")
69
+ end
70
+
71
+ it 'logs statements made against blah' do
72
+ log_message = subject.log_message(error: error, transaction_id: :transaction_id)
73
+ expect(log_message).to match(/ERROR: .* - ?#{error}$/)
74
+ end
75
+
76
+ it 'contains the transation id of the request' do
77
+ log_message = subject.log_message(error: error, transaction_id: :transaction_id)
78
+ expect(log_message).to include('ERROR: transaction_id')
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,33 @@
1
+ require 'sitehub/middleware/logging/log_entry'
2
+ class SiteHub
3
+ module Middleware
4
+ module Logging
5
+ describe LogEntry do
6
+ describe '#initialize' do
7
+ let(:time) { Time.now }
8
+ subject do
9
+ described_class.new(:message, time)
10
+ end
11
+
12
+ it 'sets the message' do
13
+ expect(subject.message).to be(:message)
14
+ end
15
+
16
+ it 'sets the time' do
17
+ expect(subject.time).to be(time)
18
+ end
19
+
20
+ context 'time not supplied' do
21
+ subject do
22
+ described_class.new(:message)
23
+ end
24
+ it 'defaults the time' do
25
+ expect(Time).to receive(:now).and_return(:current_time)
26
+ expect(subject.time).to be(:current_time)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ require 'sitehub/middleware/logging/log_stash'
2
+
3
+ class SiteHub
4
+ module Middleware
5
+ module Logging
6
+ describe LogStash do
7
+ it 'inherits Array' do
8
+ expect(subject).to be_a_kind_of(Array)
9
+ end
10
+
11
+ describe '#<<' do
12
+ it 'adds a LogEntry' do
13
+ allow(Time).to receive(:now).and_return(:current_time)
14
+ subject << :message
15
+ expect(subject).to eq([LogEntry.new(:message)])
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ require 'sitehub/middleware/logging/log_wrapper'
2
+ class SiteHub
3
+ module Middleware
4
+ module Logging
5
+ describe LogWrapper do
6
+ describe '#write' do
7
+ let(:logger) { double('logger') }
8
+ subject do
9
+ described_class.new(logger)
10
+ end
11
+
12
+ context 'logger responds to <<' do
13
+ it 'calls << when writing out the log' do
14
+ message = 'message'
15
+ expect(logger).to receive(:<<).with(message)
16
+ subject.write(message)
17
+ end
18
+ end
19
+
20
+ context 'logger responds to write' do
21
+ it 'calls << when writing out the log' do
22
+ message = 'message'
23
+ expect(logger).to receive(:write).with(message)
24
+ subject.write(message)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,108 @@
1
+ require 'sitehub/middleware/logging/request_log'
2
+
3
+ class SiteHub
4
+ module Middleware
5
+ module Logging
6
+ describe RequestLog do
7
+ include_context :rack_request
8
+
9
+ let(:rack_http_header_keys) { Constants::RackHttpHeaderKeys }
10
+
11
+ let(:response_headers) do
12
+ env = { rack_http_header_keys::QUERY_STRING => '',
13
+ rack_http_header_keys::TRANSACTION_ID => :transaction_id,
14
+ rack_http_header_keys::HTTP_VERSION => '1.1' }
15
+ HttpHeaders.from_rack_env(env)
16
+ end
17
+
18
+ let(:request_headers) do
19
+ {}
20
+ end
21
+
22
+ let(:query_string) { '' }
23
+
24
+ let(:request) do
25
+ env = env_for(path: "/#{query_string}", env: request_headers)
26
+ Request.new(env: env).tap do |request|
27
+ request.map :mapped_path.to_s, :mapped_url.to_s
28
+ end
29
+ end
30
+
31
+ let(:response) do
32
+ headers = env_for(path: '/', env: response_headers)
33
+ Response.new([], 200, headers)
34
+ end
35
+
36
+ subject do
37
+ described_class.new(request, response)
38
+ end
39
+
40
+ describe '#to_s' do
41
+ context 'query string' do
42
+ let(:query_string) { rack_http_header_keys::QUERY_STRING }
43
+ context 'present' do
44
+ let(:query_string) { '?query' }
45
+ it 'logs it' do
46
+ expect(subject.to_s).to include(query_string)
47
+ end
48
+ end
49
+
50
+ context 'not present' do
51
+ let(:query_string) { '' }
52
+ it 'is not logged' do
53
+ expect(subject.to_s).to include(query_string)
54
+ end
55
+ end
56
+ end
57
+
58
+ it 'logs the transaction id' do
59
+ request_headers[rack_http_header_keys::TRANSACTION_ID] = :transaction_id
60
+ expect(subject.to_s).to include('transaction_id:transaction_id')
61
+ end
62
+
63
+ it 'logs the response status' do
64
+ expect(subject.to_s).to include(response.status.to_s)
65
+ end
66
+
67
+ it 'logs the downstream url that was proxied to' do
68
+ expect(subject.to_s).to include("#{request.path} => mapped_url")
69
+ end
70
+
71
+ context '404 returned, i.e. no downstream call made' do
72
+ let(:request) do
73
+ env = env_for(path: "/#{query_string}", env: request_headers)
74
+ Request.new(env: env)
75
+ end
76
+ it 'does not log the down stream url' do
77
+ expect(subject.to_s).to include("=> #{EMPTY_STRING} #{request.http_version}")
78
+ end
79
+ end
80
+ end
81
+
82
+ describe '#extract_content_length' do
83
+ context 'content length header not present' do
84
+ it 'returns -' do
85
+ expect(subject.extract_content_length).to eq('-')
86
+ end
87
+ end
88
+
89
+ context 'content length header not present' do
90
+ context 'it is 0' do
91
+ it 'returns -' do
92
+ response_headers[Constants::HttpHeaderKeys::CONTENT_LENGTH] = 0
93
+ expect(subject.extract_content_length).to eq('-')
94
+ end
95
+ end
96
+
97
+ context 'it is set to a number other than 0' do
98
+ it 'returns the number' do
99
+ response_headers[Constants::HttpHeaderKeys::CONTENT_LENGTH] = 5
100
+ expect(subject.extract_content_length).to eq(5)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,113 @@
1
+ class SiteHub
2
+ module Middleware
3
+ describe ReverseProxy do
4
+ include_context :rack_request
5
+ include_context :middleware_test
6
+ HttpHeaderKeys = Constants::HttpHeaderKeys
7
+
8
+ let(:mapped_path) { '/orders' }
9
+ let(:user_facing_app_url) { "http://example.org#{mapped_path}" }
10
+
11
+ let(:downstream_mapping) { 'https://downstream.com/app1/orders' }
12
+ let(:downstream_location) { "#{downstream_mapping}/123/confirmation" }
13
+
14
+ let(:env) { env_for(path: mapped_path) }
15
+
16
+ let(:request) do
17
+ Request.new(env: env).tap do |request|
18
+ request.map mapped_path, downstream_mapping
19
+ end
20
+ end
21
+ let(:request_mapping) { request.mapping }
22
+
23
+ let(:app) do
24
+ proc { downstream_response }
25
+ end
26
+
27
+ let(:downstream_response) { Rack::Response.new('downstream', 200, 'header1' => 'header1') }
28
+
29
+ subject(:reverse_proxy) { described_class.new(app, []) }
30
+
31
+ before do
32
+ env[REQUEST] = request
33
+ end
34
+
35
+ describe '#call' do
36
+ subject(:response) do
37
+ status, headers, body = reverse_proxy.call(env).to_a
38
+ Rack::Response.new(body, status, headers)
39
+ end
40
+
41
+ it 'copies the downstream body in to the response' do
42
+ expect(response.body).to eq(downstream_response.body)
43
+ end
44
+
45
+ it 'copies the downstream headers in to the response' do
46
+ expect(response.headers).to eq(downstream_response.headers)
47
+ end
48
+
49
+ it 'copies the downstream status in to the response' do
50
+ expect(response.status).to eq(downstream_response.status)
51
+ end
52
+
53
+ context 'cookies' do
54
+ context 'downstream response contains a cookie' do
55
+ it 'rewrites it to use the upstream domain' do
56
+ downstream_response.set_cookie('downstream.cookie', domain: '.downstream.com', value: 'value')
57
+
58
+ expect(reverse_proxy)
59
+ .to receive(:rewrite_cookies)
60
+ .with(downstream_response.headers, substitute_domain: URI(request.mapping.source_url).host)
61
+
62
+ reverse_proxy.call(env)
63
+ end
64
+ end
65
+
66
+ context 'downstream response does not contain a cookie' do
67
+ it 'does not attempt to rewrite the cookies' do
68
+ downstream_headers = downstream_response.headers
69
+ downstream_headers[HttpHeaderKeys::LOCATION_HEADER] = downstream_location
70
+ expect(reverse_proxy).not_to receive(:rewrite_cookies)
71
+ reverse_proxy.call(env)
72
+ end
73
+ end
74
+ end
75
+
76
+ context 'location header' do
77
+ context 'reverse proxy defined' do
78
+ subject(:reverse_proxy) do
79
+ directive = { downstream_mapping => '/rewritten' }
80
+ described_class.new(app, directive)
81
+ end
82
+ # Location, Content-Location and URI
83
+ it 'rewrites the header' do
84
+ downstream_response.headers[HttpHeaderKeys::LOCATION_HEADER] = downstream_mapping
85
+ reverse_proxy.call(env)
86
+ # TODO: come up with better way for getting source request address and reuse the test suite
87
+ expect(downstream_response.headers[HttpHeaderKeys::LOCATION_HEADER]).to eq('http://example.org/rewritten')
88
+ end
89
+ end
90
+ end
91
+
92
+ context 'response' do
93
+ include_context :http_proxy_rules
94
+
95
+ let(:downstream_response) do
96
+ Rack::Response.new('', 200, prohibited_headers.merge(permitted_header => 'value'))
97
+ end
98
+
99
+ subject(:app) do
100
+ app = proc { downstream_response }
101
+ described_class.new(app, [])
102
+ end
103
+
104
+ it_behaves_like 'prohibited_header_filter' do
105
+ let(:subject) do
106
+ get('/', {}, REQUEST => request).headers
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end