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
@@ -1,9 +1,11 @@
1
+ require 'sitehub/equality'
1
2
  class SiteHub
2
3
  class Collection
3
4
  class SplitRouteCollection < Collection
4
5
  class Split
5
- attr_reader :upper, :lower
6
- attr_accessor :value
6
+ attr_reader :upper, :lower, :value
7
+
8
+ include Equality
7
9
 
8
10
  def initialize(lower, upper, value)
9
11
  @upper = upper
@@ -11,8 +13,8 @@ class SiteHub
11
13
  @value = value
12
14
  end
13
15
 
14
- def ==(other)
15
- other.is_a?(Split) && other.lower == lower && other.upper == upper
16
+ def update_value
17
+ @value = yield(@value)
16
18
  end
17
19
  end
18
20
  end
@@ -3,6 +3,7 @@ require 'sitehub/constants/rack_http_header_keys'
3
3
 
4
4
  class SiteHub
5
5
  REQUEST_MAPPING = 'sitehub.request_mapping'.freeze
6
+ REQUEST = 'sitehub.request'.freeze
6
7
  RESPONSE = 'sitehub.response'.freeze
7
8
  ASYNC_CALLBACK = 'async.callback'.freeze
8
9
  RECORDED_ROUTES_COOKIE = 'sitehub.recorded_route'.freeze
@@ -13,7 +14,7 @@ class SiteHub
13
14
  SEMICOLON = ';'.freeze
14
15
  SPACE = ' '.freeze
15
16
  SEMICOLON_WITH_SPACE = "#{SEMICOLON}#{SPACE}".freeze
16
- COMMA_WITH_SPACE = ', '.freeze
17
+ COMMA = ','.freeze
17
18
 
18
19
  HYPHEN = '-'.freeze
19
20
  QUESTION_MARK = '?'.freeze
@@ -16,6 +16,8 @@ class SiteHub
16
16
  CONTENT_ENCODING = 'content-encoding'.freeze
17
17
  SET_COOKIE = 'Set-Cookie'.freeze
18
18
  CONTENT_LENGTH = 'Content-Length'.freeze
19
+ UPGRADE = 'upgrade'.freeze
20
+ TRANSACTION_ID = 'sitehub-transaction-id'.freeze
19
21
  end
20
22
  end
21
23
  end
@@ -12,6 +12,8 @@ class SiteHub
12
12
  REMOTE_ADDRESS_ENV_KEY = 'REMOTE_ADDR'.freeze
13
13
  HTTP_HEADER_FILTER_EXCEPTIONS = %w(CONTENT_TYPE CONTENT_LENGTH).freeze
14
14
  TRANSACTION_ID = 'HTTP_SITEHUB_TRANSACTION_ID'.freeze
15
+ X_FORWARDED_HOST = 'HTTP_X_FORWARDED_HOST'.freeze
16
+ HTTP_HOST = 'HTTP_HOST'.freeze
15
17
  end
16
18
  end
17
19
  end
@@ -1,15 +1,16 @@
1
+ require 'sitehub/equality'
1
2
  require 'sitehub/cookie/attribute'
2
3
  require 'sitehub/cookie/flag'
3
4
  require 'sitehub/constants'
4
5
  class SiteHub
5
6
  class Cookie
6
7
  attr_reader :attributes_and_flags, :name_attribute
7
- include Constants
8
+ include Constants, Equality
8
9
 
9
10
  FIRST = 0
10
11
 
11
12
  def initialize(cookie_string)
12
- pairs = cookie_string.split(SEMICOLON).map do |entry|
13
+ @attributes_and_flags = cookie_string.split(SEMICOLON).map do |entry|
13
14
  if entry.include?(EQUALS_SIGN)
14
15
  Cookie::Attribute.new(*entry.split(EQUALS_SIGN))
15
16
  else
@@ -17,8 +18,7 @@ class SiteHub
17
18
  end
18
19
  end
19
20
 
20
- name_attribute = pairs.delete_at(FIRST)
21
- @attributes_and_flags = pairs
21
+ name_attribute = @attributes_and_flags.delete_at(FIRST)
22
22
  @name_attribute = Cookie::Attribute.new(name_attribute.name.to_s, name_attribute.value)
23
23
  end
24
24
 
@@ -34,15 +34,6 @@ class SiteHub
34
34
  attributes_and_flags.find { |entry| entry.name == name }
35
35
  end
36
36
 
37
- def ==(other)
38
- other.is_a?(self.class) &&
39
- sorted_attributes_and_flags(attributes_and_flags) == sorted_attributes_and_flags(other.attributes_and_flags)
40
- end
41
-
42
- def sorted_attributes_and_flags(attributes_and_flags)
43
- attributes_and_flags.sort { |entry1, entry2| entry1.name <=> entry2.name }
44
- end
45
-
46
37
  def to_s
47
38
  [name_attribute].concat(attributes_and_flags).join(SEMICOLON_WITH_SPACE)
48
39
  end
@@ -1,21 +1,22 @@
1
- require 'sitehub/string_sanitiser'
1
+ require 'sitehub/string_utils'
2
+ require 'sitehub/equality'
2
3
  class SiteHub
3
4
  class Cookie
4
5
  class Attribute
5
- include StringSanitiser
6
- attr_accessor :name, :value
6
+ include Equality
7
+ attr_reader :name, :value
7
8
 
8
9
  def initialize(name, value)
9
- @name = sanitise(name).to_s.to_sym
10
- @value = sanitise(value || EMPTY_STRING)
10
+ @name = StringUtils.sanitise(name).to_sym
11
+ @value = StringUtils.sanitise(value)
11
12
  end
12
13
 
13
- def to_s
14
- "#{name}=#{value}"
14
+ def update(value)
15
+ @value = value
15
16
  end
16
17
 
17
- def ==(other)
18
- other.is_a?(Attribute) && name == other.name && value == other.value
18
+ def to_s
19
+ "#{name}=#{value}"
19
20
  end
20
21
  end
21
22
  end
@@ -1,21 +1,18 @@
1
- require 'sitehub/string_sanitiser'
1
+ require 'sitehub/string_utils'
2
+ require 'sitehub/equality'
2
3
  class SiteHub
3
4
  class Cookie
4
5
  class Flag
5
- include StringSanitiser
6
- attr_accessor :name
6
+ include Equality
7
+ attr_reader :name
7
8
 
8
9
  def initialize(flag)
9
- @name = sanitise(flag).to_sym
10
+ @name = StringUtils.sanitise(flag).to_sym
10
11
  end
11
12
 
12
13
  def to_s
13
14
  name.to_s
14
15
  end
15
-
16
- def ==(other)
17
- other.is_a?(Flag) && name == other.name
18
- end
19
16
  end
20
17
  end
21
18
  end
@@ -1,6 +1,7 @@
1
1
  require 'sitehub/cookie'
2
2
  require 'sitehub/constants'
3
3
  class SiteHub
4
+ # TODO: - change in to object and remove .reek exclusions for UtilityFunction
4
5
  module CookieRewriting
5
6
  ENDING_WITH_NEWLINE = /#{NEW_LINE}$/
6
7
 
@@ -9,11 +10,18 @@ class SiteHub
9
10
 
10
11
  cookies_hash.values.each do |cookie|
11
12
  domain_attribute = cookie.find(:domain) || next
12
- value = domain_attribute.value
13
- domain_attribute.value = substitute_domain.dup
14
- domain_attribute.value.prepend(FULL_STOP) if value.start_with?(FULL_STOP)
13
+ update_domain(domain_attribute, substitute_domain)
14
+ end
15
+ headers[Constants::HttpHeaderKeys::SET_COOKIE] = cookies_hash_to_string(cookies_hash)
16
+ end
17
+
18
+ def update_domain(domain_attribute, substitute_domain)
19
+ substitute = substitute_domain.dup
20
+ if domain_attribute.value.start_with?(FULL_STOP)
21
+ domain_attribute.update(substitute.prepend(FULL_STOP))
22
+ else
23
+ domain_attribute.update(substitute)
15
24
  end
16
- headers[HttpHeaders::SET_COOKIE] = cookies_hash_to_string(cookies_hash)
17
25
  end
18
26
 
19
27
  def cookies_hash_to_string(cookies_hash)
@@ -26,7 +34,6 @@ class SiteHub
26
34
  cookie_string.lines.each_with_object({}) do |cookie_line, cookies|
27
35
  cookie = SiteHub::Cookie.new(cookie_line)
28
36
  cookies[cookie.name] = cookie
29
- cookies
30
37
  end
31
38
  end
32
39
  end
@@ -0,0 +1,37 @@
1
+ require 'sitehub/request'
2
+ require 'sitehub/request_mapping'
3
+ require 'sitehub/rules'
4
+ require 'sitehub/resolver'
5
+ require 'faraday'
6
+ require 'sitehub/constants'
7
+
8
+ # Requirements: https://www.mnot.net/blog/2011/07/11/what_proxies_must_do
9
+ # 1. remove hop by hop headers
10
+ # 2. detect bad framing: where content length and content-encoding clash or are incorrect
11
+ # 3. fix conflicts between header and URL header
12
+ # 4. insert via (optional)
13
+ # 5. Expect header (optional)
14
+
15
+ class SiteHub
16
+ class DownstreamClient
17
+ include Constants
18
+
19
+ attr_reader :http_client
20
+
21
+ def initialize
22
+ @http_client = Faraday.new(ssl: { verify: false }) do |con|
23
+ con.adapter :em_synchrony
24
+ end
25
+ end
26
+
27
+ def call(sitehub_request)
28
+ response = http_client.send(sitehub_request.request_method, sitehub_request.uri) do |request|
29
+ request.headers = sitehub_request.headers
30
+ request.body = sitehub_request.body
31
+ request.params = sitehub_request.params
32
+ end
33
+
34
+ Rack::Response.new(response.body, response.status, response.headers)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,28 @@
1
+ class SiteHub
2
+ module Equality
3
+ module ClassMethods
4
+ def transient_fields
5
+ @transient_fields ||= []
6
+ end
7
+
8
+ def transient(*fields)
9
+ transient_fields.concat(fields.collect { |field| "@#{field}".to_sym })
10
+ end
11
+ end
12
+ def self.included(clazz)
13
+ clazz.extend(ClassMethods)
14
+ end
15
+
16
+ def ==(other)
17
+ return false unless other.is_a?(_clazz)
18
+ fields = instance_variables.find_all { |field| !_clazz.transient_fields.include?(field) }
19
+ fields.all? do |variable|
20
+ instance_variable_get(variable) == other.instance_variable_get(variable)
21
+ end
22
+ end
23
+
24
+ def _clazz
25
+ self.class
26
+ end
27
+ end
28
+ end
@@ -1,81 +1,38 @@
1
1
  # rubocop:disable Metrics/ParameterLists
2
- require 'sitehub/http_headers'
3
- require 'sitehub/request_mapping'
4
- require 'sitehub/rules'
5
- require 'sitehub/resolver'
6
- require 'faraday'
7
- require 'sitehub/constants'
8
2
  class SiteHub
9
3
  class ForwardProxy
10
- ERROR_RESPONSE = Rack::Response.new(['error'], 500, {})
4
+ include Rules, Resolver
11
5
 
12
- include HttpHeaders, Rules, Resolver, Constants
6
+ attr_reader :downstream_client, :sitehub_cookie_name, :sitehub_cookie_path, :id, :mapped_path, :mapped_url
13
7
 
14
- attr_reader :url, :id, :mapped_path, :http_client, :sitehub_cookie_path, :sitehub_cookie_name
15
-
16
- def initialize(url:, id:, mapped_path: nil, rule: nil, sitehub_cookie_path: nil, sitehub_cookie_name:)
8
+ def initialize(sitehub_cookie_path: nil, sitehub_cookie_name:, id:, rule: nil, mapped_path:, mapped_url:)
9
+ @downstream_client = DownstreamClient.new
10
+ @sitehub_cookie_path = sitehub_cookie_path
11
+ @sitehub_cookie_name = sitehub_cookie_name
17
12
  @id = id
18
- @url = url
19
13
  @rule = rule
20
14
  @mapped_path = mapped_path
21
- @sitehub_cookie_path = sitehub_cookie_path
22
- @sitehub_cookie_name = sitehub_cookie_name
23
- @http_client = Faraday.new(ssl: { verify: false }) do |con|
24
- con.adapter :em_synchrony
25
- end
15
+ @mapped_url = mapped_url
26
16
  end
27
17
 
28
18
  def call(env)
29
- source_request = Rack::Request.new(env)
30
- request_mapping = env[REQUEST_MAPPING] = request_mapping(source_request)
31
- mapped_uri = URI(request_mapping.computed_uri)
32
-
33
- downstream_response = proxy_call(request_headers(mapped_uri, source_request), mapped_uri, source_request)
34
-
35
- response(downstream_response, source_request)
36
- rescue StandardError => e
37
- env[ERRORS] << e.message
38
- ERROR_RESPONSE.dup
39
- end
40
-
41
- def response(response, source_request)
42
- Rack::Response.new(response.body, response.status, sanitise_headers(response.headers)).tap do |r|
43
- r.set_cookie(sitehub_cookie_name, path: (sitehub_cookie_path || source_request.path), value: id)
44
- end
45
- end
19
+ request = env[REQUEST]
20
+ request.map(mapped_path, mapped_url)
46
21
 
47
- def request_headers(mapped_uri, source_request)
48
- headers = sanitise_headers(extract_http_headers(source_request.env))
49
- headers[HOST_HEADER] = "#{mapped_uri.host}:#{mapped_uri.port}"
50
- headers[X_FORWARDED_HOST_HEADER] = append_host(headers[X_FORWARDED_HOST_HEADER].to_s, source_request.url)
51
- headers
52
- end
53
-
54
- def proxy_call(headers, mapped_uri, source_request)
55
- http_client.send(source_request.request_method.downcase, mapped_uri) do |request|
56
- request.headers = headers
57
- request.body = source_request.body.read
58
- request.params = source_request.params
22
+ downstream_client.call(request).tap do |response|
23
+ response.set_cookie(sitehub_cookie_name, path: (sitehub_cookie_path || request.path), value: id)
59
24
  end
60
25
  end
61
26
 
62
- def request_mapping(source_request)
63
- RequestMapping.new(source_url: source_request.url, mapped_url: url, mapped_path: mapped_path)
64
- end
65
-
66
27
  def ==(other)
67
- other.is_a?(ForwardProxy) && url == other.url
68
- end
69
-
70
- private
71
-
72
- def append_host(forwarded_host, destination_uri)
73
- destination_uri = URI(destination_uri)
74
- if forwarded_host == EMPTY_STRING
75
- "#{destination_uri.host}:#{destination_uri.port}"
76
- else
77
- "#{forwarded_host},#{destination_uri.host}"
78
- end
28
+ expected = [other.mapped_path,
29
+ other.mapped_url,
30
+ other.rule,
31
+ other.id,
32
+ other.sitehub_cookie_name,
33
+ other.sitehub_cookie_path]
34
+
35
+ expected == [mapped_path, mapped_url, rule, id, sitehub_cookie_name, sitehub_cookie_path]
79
36
  end
80
37
  end
81
38
  end
@@ -1,41 +1,49 @@
1
1
  require 'uuid'
2
+ require 'sitehub/equality'
3
+ require 'sitehub/getter_setter_methods'
2
4
  require_relative 'collection/split_route_collection'
3
5
  require_relative 'rules'
4
6
  require_relative 'resolver'
5
7
  require_relative 'collection/route_collection'
6
8
  require_relative 'middleware'
9
+ require_relative 'forward_proxy'
10
+ require_relative 'downstream_client'
7
11
 
8
12
  class SiteHub
9
13
  class ForwardProxyBuilder
10
- include Middleware
11
- include Rules, Resolver
12
-
13
14
  class InvalidDefinitionException < Exception
14
15
  end
15
16
 
16
- INVALID_SPLIT_MSG = 'label and url must be defined if not supplying a block'.freeze
17
+ INVALID_SPLIT_MSG = 'url must be defined if not supplying a block'.freeze
17
18
  ROUTES_WITH_SPLITS_MSG = 'you cant register routes and splits at the same level'.freeze
18
19
  INVALID_ROUTE_DEF_MSG = 'rule must be specified when supplying a block'.freeze
20
+ IGNORING_URL_LABEL_MSG = 'Block supplied, ignoring URL and Label parameters'.freeze
21
+
22
+ extend GetterSetterMethods
23
+ include Rules, Resolver, Equality, Middleware
24
+
25
+ transient :id
19
26
 
20
- attr_reader :mapped_path, :default_proxy, :routes, :middlewares, :splits, :sitehub_cookie_name
27
+ getter_setters :default_proxy, :sitehub_cookie_path
28
+ attr_reader :mapped_path, :sitehub_cookie_name, :id
21
29
 
22
30
  def initialize(url: nil, mapped_path:, rule: nil, sitehub_cookie_name: nil, &block)
31
+ @id = UUID.generate(:compact)
23
32
  @mapped_path = mapped_path
24
- @middlewares = []
25
33
  @splits = Collection::SplitRouteCollection.new
26
34
  @routes = Collection::RouteCollection.new
27
35
  @sitehub_cookie_name = sitehub_cookie_name
28
36
  rule(rule) if rule
29
37
  default(url: url) if url
30
38
 
31
- return unless block
39
+ return unless block_given?
32
40
 
33
41
  instance_eval(&block)
34
42
  raise InvalidDefinitionException unless valid?
35
43
  end
36
44
 
37
45
  def valid?
38
- return true if @default_proxy
46
+ return true if default_proxy
39
47
  endpoints.valid?
40
48
  end
41
49
 
@@ -47,70 +55,83 @@ class SiteHub
47
55
  end
48
56
 
49
57
  def split(percentage:, url: nil, label: nil, &block)
50
- endpoints(splits)
58
+ raise InvalidDefinitionException, INVALID_SPLIT_MSG unless block || url
51
59
 
52
- raise InvalidDefinitionException, INVALID_SPLIT_MSG unless block || [url, label].all?
60
+ proxy = if block
61
+ warn(IGNORING_URL_LABEL_MSG) if url || label
62
+ new(&block).build
63
+ else
64
+ forward_proxy(label: label, url: url)
65
+ end
53
66
 
54
- label = label ? label.to_sym : UUID.generate(:compact)
55
-
56
- proxy = block ? new(&block).build : forward_proxy(label: label, url: url)
67
+ splits.add proxy.id, proxy, percentage
68
+ end
57
69
 
58
- endpoints.add label, proxy, percentage
70
+ def route(url: nil, label: nil, rule: nil, &block)
71
+ endpoint = if block
72
+ raise InvalidDefinitionException, INVALID_ROUTE_DEF_MSG unless rule
73
+ warn(IGNORING_URL_LABEL_MSG) if url || label
74
+ new(rule: rule, &block).build
75
+ else
76
+ forward_proxy(url: url, label: label, rule: rule)
77
+ end
78
+
79
+ routes.add(endpoint.id, endpoint)
59
80
  end
60
81
 
61
- def new(&block)
62
- self.class.new(mapped_path: mapped_path, &block)
82
+ def default(url:)
83
+ default_proxy(forward_proxy(label: :default, url: url))
63
84
  end
64
85
 
65
- def route(url: nil, label: nil, rule: nil, &block)
66
- endpoints(routes)
67
-
68
- if block
69
- raise InvalidDefinitionException, INVALID_ROUTE_DEF_MSG unless rule
70
- builder = self.class.new(mapped_path: mapped_path, rule: rule, &block).build
71
- endpoints.add UUID.generate(:compact), builder
72
- else
73
- endpoints.add label.to_sym, forward_proxy(url: url, label: label, rule: rule)
86
+ def build
87
+ if middleware?
88
+ build_with_middleware
89
+ build_default_with_middleware if default_proxy
74
90
  end
91
+
92
+ self
75
93
  end
76
94
 
77
- def default(url:)
78
- @default_proxy = forward_proxy(label: :default, url: url)
95
+ def resolve(id: nil, env:)
96
+ id = id.to_s.to_sym
97
+ endpoints[id] || endpoints.resolve(env: env) || default_proxy
79
98
  end
80
99
 
81
- def sitehub_cookie_path(path = nil)
82
- return @sitehub_cookie_path unless path
83
- @sitehub_cookie_path = path
100
+ def forward_proxy(label:, url:, rule: nil)
101
+ label ||= UUID.generate(:compact)
102
+ ForwardProxy.new(sitehub_cookie_path: sitehub_cookie_path,
103
+ sitehub_cookie_name: sitehub_cookie_name,
104
+ id: label.to_sym,
105
+ rule: rule,
106
+ mapped_url: url,
107
+ mapped_path: mapped_path)
84
108
  end
85
109
 
86
- def build
110
+ private
111
+
112
+ def routes
113
+ endpoints(@routes)
114
+ end
115
+
116
+ def splits
117
+ endpoints(@splits)
118
+ end
119
+
120
+ def build_with_middleware
87
121
  endpoints.transform do |proxy|
88
122
  apply_middleware(proxy).tap do |wrapped_proxy|
89
- wrapped_proxy.extend(Rules)
90
- wrapped_proxy.extend(Resolver) unless wrapped_proxy.is_a?(Resolver)
123
+ wrapped_proxy.extend(Rules, Resolver)
91
124
  wrapped_proxy.rule(proxy.rule)
92
125
  end
93
126
  end
94
- @default_proxy = apply_middleware(default_proxy) if default_proxy
95
- self
96
127
  end
97
128
 
98
- def resolve(id: nil, env:)
99
- id = id.to_s.to_sym
100
- endpoints[id] || endpoints.resolve(env: env) || default_proxy
101
- end
102
-
103
- def ==(other)
104
- other.is_a?(ForwardProxyBuilder) && default_proxy == other.default_proxy && endpoints == other.endpoints
129
+ def build_default_with_middleware
130
+ default_proxy(apply_middleware(default_proxy))
105
131
  end
106
132
 
107
- def forward_proxy(label:, url:, rule: nil)
108
- ForwardProxy.new(url: url,
109
- id: label.to_sym,
110
- mapped_path: mapped_path,
111
- sitehub_cookie_path: sitehub_cookie_path,
112
- sitehub_cookie_name: sitehub_cookie_name,
113
- rule: rule)
133
+ def new(rule: nil, &block)
134
+ self.class.new(mapped_path: mapped_path, rule: rule, &block)
114
135
  end
115
136
  end
116
137
  end