lhc 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +37 -0
- data/.rubocop.localch.yml +325 -0
- data/.rubocop.yml +61 -0
- data/.ruby-version +1 -0
- data/Gemfile +13 -0
- data/Gemfile.activesupport4 +4 -0
- data/Gemfile.activesupport5 +4 -0
- data/Gemfile.activesupport6 +4 -0
- data/LICENSE +674 -0
- data/README.md +984 -0
- data/Rakefile +25 -0
- data/cider-ci.yml +6 -0
- data/cider-ci/bin/bundle +51 -0
- data/cider-ci/bin/ruby_install +8 -0
- data/cider-ci/bin/ruby_version +25 -0
- data/cider-ci/jobs/rspec-activesupport-4.yml +28 -0
- data/cider-ci/jobs/rspec-activesupport-5.yml +27 -0
- data/cider-ci/jobs/rspec-activesupport-6.yml +28 -0
- data/cider-ci/jobs/rubocop.yml +18 -0
- data/cider-ci/task_components/bundle.yml +22 -0
- data/cider-ci/task_components/rspec.yml +36 -0
- data/cider-ci/task_components/rubocop.yml +29 -0
- data/cider-ci/task_components/ruby.yml +15 -0
- data/friday.yml +3 -0
- data/lhc.gemspec +39 -0
- data/lib/core_ext/hash/deep_transform_values.rb +48 -0
- data/lib/lhc.rb +136 -0
- data/lib/lhc/concerns/lhc/basic_methods_concern.rb +42 -0
- data/lib/lhc/concerns/lhc/configuration_concern.rb +20 -0
- data/lib/lhc/concerns/lhc/fix_invalid_encoding_concern.rb +42 -0
- data/lib/lhc/concerns/lhc/formats_concern.rb +25 -0
- data/lib/lhc/concerns/lhc/request/user_agent_concern.rb +25 -0
- data/lib/lhc/config.rb +47 -0
- data/lib/lhc/endpoint.rb +119 -0
- data/lib/lhc/error.rb +80 -0
- data/lib/lhc/errors/client_error.rb +73 -0
- data/lib/lhc/errors/parser_error.rb +4 -0
- data/lib/lhc/errors/server_error.rb +28 -0
- data/lib/lhc/errors/timeout.rb +4 -0
- data/lib/lhc/errors/unknown_error.rb +4 -0
- data/lib/lhc/format.rb +18 -0
- data/lib/lhc/formats.rb +8 -0
- data/lib/lhc/formats/form.rb +45 -0
- data/lib/lhc/formats/json.rb +55 -0
- data/lib/lhc/formats/multipart.rb +45 -0
- data/lib/lhc/formats/plain.rb +42 -0
- data/lib/lhc/interceptor.rb +32 -0
- data/lib/lhc/interceptors.rb +26 -0
- data/lib/lhc/interceptors/auth.rb +98 -0
- data/lib/lhc/interceptors/caching.rb +127 -0
- data/lib/lhc/interceptors/default_timeout.rb +16 -0
- data/lib/lhc/interceptors/logging.rb +37 -0
- data/lib/lhc/interceptors/monitoring.rb +63 -0
- data/lib/lhc/interceptors/prometheus.rb +51 -0
- data/lib/lhc/interceptors/retry.rb +41 -0
- data/lib/lhc/interceptors/rollbar.rb +36 -0
- data/lib/lhc/interceptors/throttle.rb +81 -0
- data/lib/lhc/interceptors/zipkin.rb +110 -0
- data/lib/lhc/railtie.rb +10 -0
- data/lib/lhc/request.rb +157 -0
- data/lib/lhc/response.rb +60 -0
- data/lib/lhc/response/data.rb +28 -0
- data/lib/lhc/response/data/base.rb +22 -0
- data/lib/lhc/response/data/collection.rb +16 -0
- data/lib/lhc/response/data/item.rb +29 -0
- data/lib/lhc/rspec.rb +12 -0
- data/lib/lhc/test/cache_helper.rb +3 -0
- data/lib/lhc/version.rb +5 -0
- data/script/ci/build.sh +19 -0
- data/spec/basic_methods/delete_spec.rb +34 -0
- data/spec/basic_methods/get_spec.rb +49 -0
- data/spec/basic_methods/post_spec.rb +42 -0
- data/spec/basic_methods/put_spec.rb +48 -0
- data/spec/basic_methods/request_spec.rb +19 -0
- data/spec/basic_methods/request_without_rails_spec.rb +29 -0
- data/spec/config/endpoints_spec.rb +63 -0
- data/spec/config/placeholders_spec.rb +32 -0
- data/spec/core_ext/hash/deep_transform_values_spec.rb +24 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +8 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +7 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +4 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +5 -0
- data/spec/dummy/bin/rails +6 -0
- data/spec/dummy/bin/rake +6 -0
- data/spec/dummy/config.ru +6 -0
- data/spec/dummy/config/application.rb +16 -0
- data/spec/dummy/config/boot.rb +7 -0
- data/spec/dummy/config/environment.rb +7 -0
- data/spec/dummy/config/environments/development.rb +36 -0
- data/spec/dummy/config/environments/production.rb +77 -0
- data/spec/dummy/config/environments/test.rb +41 -0
- data/spec/dummy/config/initializers/assets.rb +10 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
- data/spec/dummy/config/initializers/inflections.rb +18 -0
- data/spec/dummy/config/initializers/mime_types.rb +6 -0
- data/spec/dummy/config/initializers/session_store.rb +5 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +11 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/endpoint/compile_spec.rb +35 -0
- data/spec/endpoint/match_spec.rb +41 -0
- data/spec/endpoint/placeholders_spec.rb +30 -0
- data/spec/endpoint/remove_interpolated_params_spec.rb +17 -0
- data/spec/endpoint/values_as_params_spec.rb +31 -0
- data/spec/error/dup_spec.rb +12 -0
- data/spec/error/find_spec.rb +57 -0
- data/spec/error/response_spec.rb +17 -0
- data/spec/error/timeout_spec.rb +14 -0
- data/spec/error/to_s_spec.rb +80 -0
- data/spec/formats/form_spec.rb +27 -0
- data/spec/formats/json_spec.rb +66 -0
- data/spec/formats/multipart_spec.rb +26 -0
- data/spec/formats/plain_spec.rb +29 -0
- data/spec/interceptors/after_request_spec.rb +20 -0
- data/spec/interceptors/after_response_spec.rb +39 -0
- data/spec/interceptors/auth/basic_auth_spec.rb +17 -0
- data/spec/interceptors/auth/bearer_spec.rb +19 -0
- data/spec/interceptors/auth/reauthentication_configuration_spec.rb +61 -0
- data/spec/interceptors/auth/reauthentication_spec.rb +44 -0
- data/spec/interceptors/before_request_spec.rb +21 -0
- data/spec/interceptors/before_response_spec.rb +20 -0
- data/spec/interceptors/caching/hydra_spec.rb +26 -0
- data/spec/interceptors/caching/main_spec.rb +73 -0
- data/spec/interceptors/caching/methods_spec.rb +42 -0
- data/spec/interceptors/caching/options_spec.rb +89 -0
- data/spec/interceptors/caching/parameters_spec.rb +24 -0
- data/spec/interceptors/caching/response_status_spec.rb +29 -0
- data/spec/interceptors/caching/to_cache_spec.rb +16 -0
- data/spec/interceptors/default_interceptors_spec.rb +15 -0
- data/spec/interceptors/default_timeout/main_spec.rb +34 -0
- data/spec/interceptors/define_spec.rb +29 -0
- data/spec/interceptors/dup_spec.rb +19 -0
- data/spec/interceptors/logging/main_spec.rb +37 -0
- data/spec/interceptors/monitoring/main_spec.rb +97 -0
- data/spec/interceptors/prometheus_spec.rb +54 -0
- data/spec/interceptors/response_competition_spec.rb +41 -0
- data/spec/interceptors/retry/main_spec.rb +73 -0
- data/spec/interceptors/return_response_spec.rb +38 -0
- data/spec/interceptors/rollbar/invalid_encoding_spec.rb +43 -0
- data/spec/interceptors/rollbar/main_spec.rb +57 -0
- data/spec/interceptors/throttle/main_spec.rb +106 -0
- data/spec/interceptors/throttle/reset_track_spec.rb +53 -0
- data/spec/interceptors/zipkin/distributed_tracing_spec.rb +135 -0
- data/spec/rails_helper.rb +6 -0
- data/spec/request/body_spec.rb +39 -0
- data/spec/request/encoding_spec.rb +37 -0
- data/spec/request/error_handling_spec.rb +88 -0
- data/spec/request/headers_spec.rb +12 -0
- data/spec/request/ignore_errors_spec.rb +73 -0
- data/spec/request/option_dup_spec.rb +13 -0
- data/spec/request/parallel_requests_spec.rb +59 -0
- data/spec/request/params_encoding_spec.rb +26 -0
- data/spec/request/request_without_rails_spec.rb +15 -0
- data/spec/request/url_patterns_spec.rb +54 -0
- data/spec/request/user_agent_spec.rb +26 -0
- data/spec/request/user_agent_without_rails_spec.rb +27 -0
- data/spec/response/body_spec.rb +16 -0
- data/spec/response/code_spec.rb +16 -0
- data/spec/response/data_accessor_spec.rb +29 -0
- data/spec/response/data_spec.rb +61 -0
- data/spec/response/effective_url_spec.rb +16 -0
- data/spec/response/headers_spec.rb +18 -0
- data/spec/response/options_spec.rb +18 -0
- data/spec/response/success_spec.rb +13 -0
- data/spec/response/time_spec.rb +21 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/fixtures/json/feedback.json +11 -0
- data/spec/support/fixtures/json/feedbacks.json +164 -0
- data/spec/support/fixtures/json/localina_content_ad.json +23 -0
- data/spec/support/load_json.rb +5 -0
- data/spec/support/reset_config.rb +7 -0
- data/spec/support/zipkin_mock.rb +113 -0
- data/spec/timeouts/no_signal_spec.rb +13 -0
- data/spec/timeouts/timings_spec.rb +55 -0
- metadata +534 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
module LHC
|
|
6
|
+
module BasicMethodsConcern
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
module ClassMethods
|
|
10
|
+
def request(options)
|
|
11
|
+
if options.is_a? Array
|
|
12
|
+
parallel_requests(options)
|
|
13
|
+
else
|
|
14
|
+
LHC::Request.new(options).response
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
[:get, :post, :put, :delete].each do |http_method|
|
|
19
|
+
define_method(http_method) do |url, options = {}|
|
|
20
|
+
request(options.merge(
|
|
21
|
+
url: url,
|
|
22
|
+
method: http_method
|
|
23
|
+
))
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def parallel_requests(options)
|
|
30
|
+
hydra = Typhoeus::Hydra.new # do not use memoization !
|
|
31
|
+
requests = []
|
|
32
|
+
options.each do |option|
|
|
33
|
+
request = LHC::Request.new(option, false)
|
|
34
|
+
requests << request
|
|
35
|
+
hydra.queue request.raw unless request.response.present?
|
|
36
|
+
end
|
|
37
|
+
hydra.run
|
|
38
|
+
requests.map(&:response)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
module LHC
|
|
6
|
+
module ConfigurationConcern
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
module ClassMethods
|
|
10
|
+
def config
|
|
11
|
+
LHC::Config.instance
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def configure
|
|
15
|
+
LHC::Config.instance.reset
|
|
16
|
+
yield config
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
module LHC
|
|
6
|
+
module FixInvalidEncodingConcern
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
module ClassMethods
|
|
10
|
+
# fix strings that contain non-UTF8 encoding in a forceful way
|
|
11
|
+
# should none of the fix-attempts be successful,
|
|
12
|
+
# an empty string is returned instead
|
|
13
|
+
def fix_invalid_encoding(string)
|
|
14
|
+
return string unless string.is_a?(String)
|
|
15
|
+
result = string.dup
|
|
16
|
+
|
|
17
|
+
# we assume it's ISO-8859-1 first
|
|
18
|
+
if !result.valid_encoding? || !utf8?(result)
|
|
19
|
+
result.encode!('UTF-8', 'ISO-8859-1', invalid: :replace, undef: :replace, replace: '')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# if it's still an issue, try with BINARY
|
|
23
|
+
if !result.valid_encoding? || !utf8?(result)
|
|
24
|
+
result.encode!('UTF-8', 'BINARY', invalid: :replace, undef: :replace, replace: '')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# if its STILL an issue, return an empty string :(
|
|
28
|
+
if !result.valid_encoding? || !utf8?(result)
|
|
29
|
+
result = ""
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
result
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def utf8?(string)
|
|
38
|
+
string.encoding == Encoding::UTF_8
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LHC
|
|
4
|
+
module FormatsConcern
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
module ClassMethods
|
|
8
|
+
def form
|
|
9
|
+
LHC::Formats::Form
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def json
|
|
13
|
+
LHC::Formats::JSON
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def multipart
|
|
17
|
+
LHC::Formats::Multipart
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def plain
|
|
21
|
+
LHC::Formats::Plain
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
require 'lhc/version'
|
|
5
|
+
|
|
6
|
+
module LHC
|
|
7
|
+
class Request
|
|
8
|
+
module UserAgentConcern
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
included do
|
|
12
|
+
Typhoeus::Config.user_agent = begin
|
|
13
|
+
version = LHC::VERSION
|
|
14
|
+
application = nil
|
|
15
|
+
if defined?(Rails)
|
|
16
|
+
app_class = Rails.application.class
|
|
17
|
+
application = (ActiveSupport.gem_version >= Gem::Version.new('6.0.0')) ? app_class.module_parent_name : app_class.parent_name
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
"LHC (#{[version, application].compact.join('; ')}) [https://github.com/local-ch/lhc]"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/lhc/config.rb
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'singleton'
|
|
4
|
+
|
|
5
|
+
class LHC::Config
|
|
6
|
+
include Singleton
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
@endpoints = {}
|
|
10
|
+
@placeholders = {}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def endpoint(name, url, options = {})
|
|
14
|
+
name = name.to_sym
|
|
15
|
+
raise 'Endpoint already exists for that name' if @endpoints[name]
|
|
16
|
+
@endpoints[name] = LHC::Endpoint.new(url, options)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def endpoints
|
|
20
|
+
@endpoints.dup
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def placeholder(name, value)
|
|
24
|
+
name = name.to_sym
|
|
25
|
+
raise 'Placeholder already exists for that name' if @placeholders[name]
|
|
26
|
+
@placeholders[name] = value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def placeholders
|
|
30
|
+
@placeholders.dup
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def interceptors
|
|
34
|
+
(@interceptors || []).dup
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def interceptors=(interceptors)
|
|
38
|
+
raise 'Default interceptors already set and can only be set once' if @interceptors
|
|
39
|
+
@interceptors = interceptors
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def reset
|
|
43
|
+
@endpoints = {}
|
|
44
|
+
@placeholders = {}
|
|
45
|
+
@interceptors = nil
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/lhc/endpoint.rb
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'addressable/template'
|
|
4
|
+
|
|
5
|
+
# An endpoint is an url that leads to a backend resource.
|
|
6
|
+
# The url can also be an url-template (https://tools.ietf.org/html/rfc6570).
|
|
7
|
+
class LHC::Endpoint
|
|
8
|
+
attr_accessor :url
|
|
9
|
+
attr_writer :options
|
|
10
|
+
|
|
11
|
+
def initialize(url, options = nil)
|
|
12
|
+
self.url = url
|
|
13
|
+
self.options = options
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def uri
|
|
17
|
+
@uri ||= Addressable::Template.new(url)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def compile(params)
|
|
21
|
+
context = LHC.config.placeholders.deep_dup
|
|
22
|
+
context.merge!(params) if params.is_a?(Hash)
|
|
23
|
+
expanded = uri.partial_expand(context)
|
|
24
|
+
|
|
25
|
+
if expanded.variables.empty?
|
|
26
|
+
expanded.pattern
|
|
27
|
+
else
|
|
28
|
+
raise("Compilation incomplete. Unable to find value for #{expanded.variables.join(', ')}.")
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Endpoint options are immutable
|
|
33
|
+
def options
|
|
34
|
+
@options.deep_dup
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Removes keys from provided params hash
|
|
38
|
+
# when they are used for interpolation.
|
|
39
|
+
def remove_interpolated_params!(params)
|
|
40
|
+
params ||= {}
|
|
41
|
+
removed = params.slice(*placeholders)
|
|
42
|
+
params.except!(*placeholders)
|
|
43
|
+
|
|
44
|
+
removed
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Returns all placeholders found in the url-template.
|
|
48
|
+
# They are alphabetically sorted.
|
|
49
|
+
def placeholders
|
|
50
|
+
uri.variables.sort.map(&:to_sym)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Compares a concrete url with a template
|
|
54
|
+
# Returns true if concrete url is covered by the template
|
|
55
|
+
# Example: {+datastore}/contracts/{id} == http://local.ch/contracts/1
|
|
56
|
+
def match?(url)
|
|
57
|
+
return true if url == uri.pattern
|
|
58
|
+
match_data = match_data(url)
|
|
59
|
+
return false if match_data.nil?
|
|
60
|
+
|
|
61
|
+
first = match_data.values.first
|
|
62
|
+
last = match_data.values.last
|
|
63
|
+
url_format = File.extname(url)
|
|
64
|
+
|
|
65
|
+
# eliminate false positives in form:
|
|
66
|
+
# http://host/feedbacks matches {+service}/{entry_id}/feedbacks (service: http:/, entry_id: host)
|
|
67
|
+
first&.match(%{https?:/$}).nil? &&
|
|
68
|
+
# eliminates false positives in form:
|
|
69
|
+
# http://host/entries/123.json matches {+service}/entries/{id} (service: http://host, id: 123.json)
|
|
70
|
+
(url_format.blank? || !last&.ends_with?(url_format))
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Extracts the values from url and
|
|
74
|
+
# creates params according to template
|
|
75
|
+
def values_as_params(url)
|
|
76
|
+
match_data = match_data(url)
|
|
77
|
+
return if match_data.nil?
|
|
78
|
+
Hash[match_data.variables.map(&:to_sym).zip(match_data.values)]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Checks if the name has a match in the current context
|
|
82
|
+
def find_value(name, mapping)
|
|
83
|
+
context = LHC.config.placeholders.deep_dup
|
|
84
|
+
context.merge!(mapping)
|
|
85
|
+
|
|
86
|
+
context[name]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Compares a concrete url with a template
|
|
90
|
+
# Returns true if concrete url is covered by the template
|
|
91
|
+
# Example: {+datastore}/contracts/{id} == http://local.ch/contracts/1
|
|
92
|
+
def self.match?(url, template)
|
|
93
|
+
new(template).match?(url)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Returns all placeholders found in the url-template.
|
|
97
|
+
# They are alphabetically sorted.
|
|
98
|
+
def self.placeholders(template)
|
|
99
|
+
new(template).placeholders
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Extracts the values from url and
|
|
103
|
+
# creates params according to template
|
|
104
|
+
def self.values_as_params(template, url)
|
|
105
|
+
raise("#{url} does not match the template: #{template}") if !match?(url, template)
|
|
106
|
+
new(template).values_as_params(url)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
private
|
|
110
|
+
|
|
111
|
+
def match_data(url)
|
|
112
|
+
parsed = URI.parse(url)
|
|
113
|
+
parsed.query = parsed.fragment = nil
|
|
114
|
+
|
|
115
|
+
uri.match(parsed)
|
|
116
|
+
rescue URI::InvalidURIError
|
|
117
|
+
nil
|
|
118
|
+
end
|
|
119
|
+
end
|
data/lib/lhc/error.rb
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class LHC::Error < StandardError
|
|
4
|
+
include LHC::FixInvalidEncodingConcern
|
|
5
|
+
|
|
6
|
+
attr_accessor :response, :_message
|
|
7
|
+
|
|
8
|
+
def self.map
|
|
9
|
+
{
|
|
10
|
+
400 => LHC::BadRequest,
|
|
11
|
+
401 => LHC::Unauthorized,
|
|
12
|
+
402 => LHC::PaymentRequired,
|
|
13
|
+
403 => LHC::Forbidden,
|
|
14
|
+
404 => LHC::NotFound,
|
|
15
|
+
405 => LHC::MethodNotAllowed,
|
|
16
|
+
406 => LHC::NotAcceptable,
|
|
17
|
+
407 => LHC::ProxyAuthenticationRequired,
|
|
18
|
+
408 => LHC::RequestTimeout,
|
|
19
|
+
409 => LHC::Conflict,
|
|
20
|
+
410 => LHC::Gone,
|
|
21
|
+
411 => LHC::LengthRequired,
|
|
22
|
+
412 => LHC::PreconditionFailed,
|
|
23
|
+
413 => LHC::RequestEntityTooLarge,
|
|
24
|
+
414 => LHC::RequestUriToLong,
|
|
25
|
+
415 => LHC::UnsupportedMediaType,
|
|
26
|
+
416 => LHC::RequestedRangeNotSatisfiable,
|
|
27
|
+
417 => LHC::ExpectationFailed,
|
|
28
|
+
422 => LHC::UnprocessableEntity,
|
|
29
|
+
423 => LHC::Locked,
|
|
30
|
+
424 => LHC::FailedDependency,
|
|
31
|
+
426 => LHC::UpgradeRequired,
|
|
32
|
+
|
|
33
|
+
500 => LHC::InternalServerError,
|
|
34
|
+
501 => LHC::NotImplemented,
|
|
35
|
+
502 => LHC::BadGateway,
|
|
36
|
+
503 => LHC::ServiceUnavailable,
|
|
37
|
+
504 => LHC::GatewayTimeout,
|
|
38
|
+
505 => LHC::HttpVersionNotSupported,
|
|
39
|
+
507 => LHC::InsufficientStorage,
|
|
40
|
+
510 => LHC::NotExtended
|
|
41
|
+
}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.find(response)
|
|
45
|
+
return LHC::Timeout if response.timeout?
|
|
46
|
+
status_code = response.code.to_s[0..2].to_i
|
|
47
|
+
error = map[status_code]
|
|
48
|
+
error ||= LHC::UnknownError
|
|
49
|
+
error
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.dup
|
|
53
|
+
self
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def initialize(message, response)
|
|
57
|
+
super(message)
|
|
58
|
+
self._message = message
|
|
59
|
+
self.response = response
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.to_a
|
|
63
|
+
[self]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def to_s
|
|
67
|
+
return response if response.is_a?(String)
|
|
68
|
+
request = response.request
|
|
69
|
+
debug = []
|
|
70
|
+
debug << [request.method, request.url].map { |str| self.class.fix_invalid_encoding(str) }.join(' ')
|
|
71
|
+
debug << "Options: #{request.options}"
|
|
72
|
+
debug << "Headers: #{request.headers}"
|
|
73
|
+
debug << "Response Code: #{response.code} (#{response.options[:return_code]})"
|
|
74
|
+
debug << "Response Options: #{response.options}"
|
|
75
|
+
debug << response.body
|
|
76
|
+
debug << _message
|
|
77
|
+
|
|
78
|
+
debug.map { |str| self.class.fix_invalid_encoding(str) }.join("\n")
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class LHC::ClientError < LHC::Error
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
class LHC::BadRequest < LHC::ClientError
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class LHC::Unauthorized < LHC::ClientError
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class LHC::PaymentRequired < LHC::ClientError
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class LHC::Forbidden < LHC::ClientError
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class LHC::Forbidden < LHC::ClientError
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class LHC::NotFound < LHC::ClientError
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class LHC::MethodNotAllowed < LHC::ClientError
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class LHC::NotAcceptable < LHC::ClientError
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class LHC::ProxyAuthenticationRequired < LHC::ClientError
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class LHC::RequestTimeout < LHC::ClientError
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class LHC::Conflict < LHC::ClientError
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class LHC::Gone < LHC::ClientError
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class LHC::LengthRequired < LHC::ClientError
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class LHC::PreconditionFailed < LHC::ClientError
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
class LHC::RequestEntityTooLarge < LHC::ClientError
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
class LHC::RequestUriToLong < LHC::ClientError
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class LHC::UnsupportedMediaType < LHC::ClientError
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
class LHC::RequestedRangeNotSatisfiable < LHC::ClientError
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class LHC::ExpectationFailed < LHC::ClientError
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class LHC::UnprocessableEntity < LHC::ClientError
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
class LHC::Locked < LHC::ClientError
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
class LHC::FailedDependency < LHC::ClientError
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
class LHC::UpgradeRequired < LHC::ClientError
|
|
73
|
+
end
|