lhc 0.2.1
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 +36 -0
- data/Gemfile +11 -0
- data/README.md +116 -0
- data/Rakefile +25 -0
- data/docs/configuration.md +57 -0
- data/docs/exceptions.md +68 -0
- data/docs/interceptors.md +90 -0
- data/docs/request.md +24 -0
- data/docs/response.md +19 -0
- data/lhc.gemspec +30 -0
- data/lib/lhc.rb +16 -0
- data/lib/lhc/concerns/lhc/basic_methods.rb +42 -0
- data/lib/lhc/config.rb +45 -0
- data/lib/lhc/endpoint.rb +53 -0
- data/lib/lhc/error.rb +63 -0
- data/lib/lhc/errors/client_error.rb +73 -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/interceptor.rb +9 -0
- data/lib/lhc/interceptor_processor.rb +24 -0
- data/lib/lhc/request.rb +91 -0
- data/lib/lhc/response.rb +52 -0
- data/lib/lhc/version.rb +3 -0
- data/script/ci/build.sh +19 -0
- data/spec/basic_methods/delete_spec.rb +34 -0
- data/spec/basic_methods/get_spec.rb +37 -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/config/endpoints_spec.rb +49 -0
- data/spec/config/placeholders_spec.rb +32 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -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 +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -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 +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +14 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +34 -0
- data/spec/dummy/config/environments/production.rb +75 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/assets.rb +8 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +9 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +56 -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 +25 -0
- data/spec/endpoint/placeholders_spec.rb +14 -0
- data/spec/endpoint/remove_interpolated_params_spec.rb +16 -0
- data/spec/error/find_spec.rb +56 -0
- data/spec/error/response_spec.rb +17 -0
- data/spec/error/timeout_spec.rb +14 -0
- data/spec/interceptors/after_request_spec.rb +21 -0
- data/spec/interceptors/after_response_spec.rb +42 -0
- data/spec/interceptors/before_request_spec.rb +21 -0
- data/spec/interceptors/before_response_spec.rb +21 -0
- data/spec/interceptors/default_interceptors_spec.rb +15 -0
- data/spec/interceptors/define_spec.rb +29 -0
- data/spec/interceptors/response_competition_spec.rb +40 -0
- data/spec/interceptors/return_response_spec.rb +39 -0
- data/spec/rails_helper.rb +4 -0
- data/spec/request/error_handling_spec.rb +52 -0
- data/spec/request/headers_spec.rb +11 -0
- data/spec/request/option_dup_spec.rb +12 -0
- data/spec/request/parallel_requests_spec.rb +15 -0
- data/spec/request/url_patterns_spec.rb +19 -0
- data/spec/response/body_spec.rb +16 -0
- data/spec/response/code_spec.rb +16 -0
- data/spec/response/data_spec.rb +18 -0
- data/spec/response/headers_spec.rb +18 -0
- data/spec/response/success_spec.rb +12 -0
- data/spec/response/time_spec.rb +16 -0
- data/spec/spec_helper.rb +4 -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 +3 -0
- data/spec/support/reset_config.rb +7 -0
- data/spec/timeouts/no_signal_spec.rb +13 -0
- data/spec/timeouts/timings_spec.rb +59 -0
- metadata +313 -0
data/docs/response.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Response
|
2
|
+
===
|
3
|
+
|
4
|
+
```ruby
|
5
|
+
response.request #<LHC::Request> the associated request.
|
6
|
+
|
7
|
+
response.data #<OpenStruct> in case response body contains parsable JSON.
|
8
|
+
response.data.something.nested
|
9
|
+
|
10
|
+
response.body #<String>
|
11
|
+
|
12
|
+
response.code #<Fixnum>
|
13
|
+
|
14
|
+
response.headers #<Hash>
|
15
|
+
|
16
|
+
response.time #<Fixnum> Provides response time in ms.
|
17
|
+
|
18
|
+
response.timeout? #true|false
|
19
|
+
```
|
data/lhc.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
# Maintain your gem's version:
|
4
|
+
require "lhc/version"
|
5
|
+
|
6
|
+
# Describe your gem and declare its dependencies:
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "lhc"
|
9
|
+
s.version = LHC::VERSION
|
10
|
+
s.authors = ['local.ch']
|
11
|
+
s.email = ['ws-operations@local.ch']
|
12
|
+
s.homepage = 'https://github.com/local-ch/lhc'
|
13
|
+
s.summary = 'LocalHttpServices'
|
14
|
+
s.description = 'Rails gem wrapping typhoeus and providing additional features (like interceptors)'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
18
|
+
s.require_paths = ['lib']
|
19
|
+
|
20
|
+
s.requirements << 'Ruby >= 1.9.2'
|
21
|
+
s.required_ruby_version = '>= 1.9.2'
|
22
|
+
|
23
|
+
s.add_dependency 'typhoeus'
|
24
|
+
|
25
|
+
s.add_development_dependency 'rspec-rails', '>= 3.0.0'
|
26
|
+
s.add_development_dependency 'rails', '~> 4.1.1'
|
27
|
+
s.add_development_dependency 'webmock'
|
28
|
+
s.add_development_dependency 'geminabox'
|
29
|
+
s.add_development_dependency 'pry'
|
30
|
+
end
|
data/lib/lhc.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
Dir[File.dirname(__FILE__) + '/lhc/concerns/lhc/*.rb'].sort.each {|file| require file }
|
2
|
+
|
3
|
+
module LHC
|
4
|
+
include BasicMethods
|
5
|
+
|
6
|
+
def self.config
|
7
|
+
LHC::Config.instance
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.configure
|
11
|
+
LHC::Config.instance.reset
|
12
|
+
yield config
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Gem.find_files('lhc/**/*.rb').sort.each { |path| require path }
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
module LHC
|
4
|
+
|
5
|
+
module BasicMethods
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
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.hydra
|
31
|
+
requests = []
|
32
|
+
options.each do |options|
|
33
|
+
request = LHC::Request.new(options, false)
|
34
|
+
requests << request
|
35
|
+
hydra.queue request.raw
|
36
|
+
end
|
37
|
+
hydra.run
|
38
|
+
requests.map(&:response)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/lhc/config.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
class LHC::Config
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@endpoints = {}
|
8
|
+
@placeholders = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def endpoint(name, url, options = {})
|
12
|
+
name = name.to_sym
|
13
|
+
fail 'Endpoint already exists for that name' if @endpoints[name]
|
14
|
+
@endpoints[name] = LHC::Endpoint.new(url, options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def endpoints
|
18
|
+
@endpoints.dup
|
19
|
+
end
|
20
|
+
|
21
|
+
def placeholder(name, value)
|
22
|
+
name = name.to_sym
|
23
|
+
fail 'Placeholder already exists for that name' if @placeholders[name]
|
24
|
+
@placeholders[name] = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def placeholders
|
28
|
+
@placeholders.dup
|
29
|
+
end
|
30
|
+
|
31
|
+
def interceptors
|
32
|
+
(@interceptors || []).dup
|
33
|
+
end
|
34
|
+
|
35
|
+
def interceptors=(interceptors)
|
36
|
+
fail 'Default interceptors already set and can only be set once' if @interceptors
|
37
|
+
@interceptors = interceptors
|
38
|
+
end
|
39
|
+
|
40
|
+
def reset
|
41
|
+
@endpoints = {}
|
42
|
+
@placeholders = {}
|
43
|
+
@interceptors = nil
|
44
|
+
end
|
45
|
+
end
|
data/lib/lhc/endpoint.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# An endpoint is an url that leads to a backend resource.
|
2
|
+
# The url can also be an url-template.
|
3
|
+
class LHC::Endpoint
|
4
|
+
|
5
|
+
PLACEHOLDER = /\:[A-Z,a-z,_,-]+/
|
6
|
+
|
7
|
+
attr_accessor :url, :options
|
8
|
+
|
9
|
+
def initialize(url, options = nil)
|
10
|
+
self.url = url
|
11
|
+
self.options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def compile(params)
|
15
|
+
url.gsub(PLACEHOLDER) do |match|
|
16
|
+
replacement = if params.is_a? Proc
|
17
|
+
params.call(match)
|
18
|
+
else
|
19
|
+
find_value(match, params)
|
20
|
+
end
|
21
|
+
replacement || fail("Compilation incomplete. Unable to find value for #{match.gsub(':', '')}.")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Removes keys from provided params hash
|
26
|
+
# when they are used for interpolation.
|
27
|
+
def remove_interpolated_params!(params)
|
28
|
+
params ||= {}
|
29
|
+
removed = {}
|
30
|
+
url.scan(PLACEHOLDER) do |match|
|
31
|
+
match = match.gsub(/^\:/, '')
|
32
|
+
if value = find_value(match, params)
|
33
|
+
removed[match.to_sym] = value
|
34
|
+
params.delete(match.to_sym)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
removed
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns all placeholders found in the url-template.
|
41
|
+
# They are alphabetically sorted.
|
42
|
+
def placeholders
|
43
|
+
url.scan(PLACEHOLDER).sort
|
44
|
+
end
|
45
|
+
|
46
|
+
# Find a value for a placeholder either in the configuration
|
47
|
+
# or in the provided params.
|
48
|
+
def find_value(match, params)
|
49
|
+
params ||= {}
|
50
|
+
match = match.gsub(/^\:/, '').to_sym
|
51
|
+
params[match] || LHC.config.placeholders[match]
|
52
|
+
end
|
53
|
+
end
|
data/lib/lhc/error.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
class LHC::Error < StandardError
|
2
|
+
|
3
|
+
attr_accessor :response
|
4
|
+
|
5
|
+
def self.map
|
6
|
+
{
|
7
|
+
400 => LHC::BadRequest,
|
8
|
+
401 => LHC::Unauthorized,
|
9
|
+
402 => LHC::PaymentRequired,
|
10
|
+
403 => LHC::Forbidden,
|
11
|
+
404 => LHC::NotFound,
|
12
|
+
405 => LHC::MethodNotAllowed,
|
13
|
+
406 => LHC::NotAcceptable,
|
14
|
+
407 => LHC::ProxyAuthenticationRequired,
|
15
|
+
408 => LHC::RequestTimeout,
|
16
|
+
409 => LHC::Conflict,
|
17
|
+
410 => LHC::Gone,
|
18
|
+
411 => LHC::LengthRequired,
|
19
|
+
412 => LHC::PreconditionFailed,
|
20
|
+
413 => LHC::RequestEntityTooLarge,
|
21
|
+
414 => LHC::RequestUriToLong,
|
22
|
+
415 => LHC::UnsupportedMediaType,
|
23
|
+
416 => LHC::RequestedRangeNotSatisfiable,
|
24
|
+
417 => LHC::ExpectationFailed,
|
25
|
+
422 => LHC::UnprocessableEntity,
|
26
|
+
423 => LHC::Locked,
|
27
|
+
424 => LHC::FailedDependency,
|
28
|
+
426 => LHC::UpgradeRequired,
|
29
|
+
|
30
|
+
500 => LHC::InternalServerError,
|
31
|
+
501 => LHC::NotImplemented,
|
32
|
+
502 => LHC::BadGateway,
|
33
|
+
503 => LHC::ServiceUnavailable,
|
34
|
+
504 => LHC::GatewayTimeout,
|
35
|
+
505 => LHC::HttpVersionNotSupported,
|
36
|
+
507 => LHC::InsufficientStorage,
|
37
|
+
510 => LHC::NotExtended
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.find(response)
|
42
|
+
return LHC::Timeout if response.timeout?
|
43
|
+
status_code = response.code.to_s[0..2].to_i
|
44
|
+
error = map[status_code]
|
45
|
+
error ||= LHC::UnknownError
|
46
|
+
error
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize(message, response)
|
50
|
+
super(message)
|
51
|
+
self.response = response
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_s
|
55
|
+
request = response.request
|
56
|
+
debug = []
|
57
|
+
debug << "#{request.method} #{request.url}"
|
58
|
+
debug << "Params: #{request.options}"
|
59
|
+
debug << "Response Code: #{response.code}"
|
60
|
+
debug << response.body
|
61
|
+
debug.join("\n")
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../error'
|
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
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../error'
|
2
|
+
|
3
|
+
class LHC::ServerError < LHC::Error
|
4
|
+
end
|
5
|
+
|
6
|
+
class LHC::InternalServerError < LHC::ServerError
|
7
|
+
end
|
8
|
+
|
9
|
+
class LHC::NotImplemented < LHC::ServerError
|
10
|
+
end
|
11
|
+
|
12
|
+
class LHC::BadGateway < LHC::ServerError
|
13
|
+
end
|
14
|
+
|
15
|
+
class LHC::ServiceUnavailable < LHC::ServerError
|
16
|
+
end
|
17
|
+
|
18
|
+
class LHC::GatewayTimeout < LHC::ServerError
|
19
|
+
end
|
20
|
+
|
21
|
+
class LHC::HttpVersionNotSupported < LHC::ServerError
|
22
|
+
end
|
23
|
+
|
24
|
+
class LHC::InsufficientStorage < LHC::ServerError
|
25
|
+
end
|
26
|
+
|
27
|
+
class LHC::NotExtended < LHC::ServerError
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Handles interceptions during the lifecycle of a request
|
2
|
+
class LHC::InterceptorProcessor
|
3
|
+
|
4
|
+
attr_accessor :interceptors
|
5
|
+
|
6
|
+
# Intitalizes the processor and determines if global or local interceptors are used
|
7
|
+
def initialize(target)
|
8
|
+
options = target.options if target.is_a? LHC::Request
|
9
|
+
options ||= target.request.options if target.is_a? LHC::Response
|
10
|
+
self.interceptors = (options[:interceptors] || LHC.config.interceptors).map{ |i| i.new }
|
11
|
+
end
|
12
|
+
|
13
|
+
# Forwards messages to interceptors and handles provided responses.
|
14
|
+
def intercept(name, target)
|
15
|
+
interceptors.each do |interceptor|
|
16
|
+
result = interceptor.send(name, target)
|
17
|
+
if result.is_a? LHC::Response
|
18
|
+
fail 'Response already set from another interceptor' if @response
|
19
|
+
request = target.is_a?(LHC::Request) ? target : target.request
|
20
|
+
@response = request.response = result
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/lhc/request.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'typhoeus'
|
2
|
+
|
3
|
+
# The request is doing an http-request using typhoeus.
|
4
|
+
# It provides functionalities to access and alter request data
|
5
|
+
# and it communicates with interceptors.
|
6
|
+
class LHC::Request
|
7
|
+
|
8
|
+
TYPHOEUS_OPTIONS = [:params, :method, :body, :headers]
|
9
|
+
|
10
|
+
attr_accessor :response, :options, :raw
|
11
|
+
|
12
|
+
def initialize(options, self_executing = true)
|
13
|
+
self.options = options.deep_dup
|
14
|
+
use_configured_endpoint!
|
15
|
+
generate_url_from_template!
|
16
|
+
self.iprocessor = LHC::InterceptorProcessor.new(self)
|
17
|
+
self.raw = create_request
|
18
|
+
return unless self_executing
|
19
|
+
iprocessor.intercept(:before_request, self)
|
20
|
+
raw.run if !response
|
21
|
+
end
|
22
|
+
|
23
|
+
def url
|
24
|
+
raw.base_url || options[:url]
|
25
|
+
end
|
26
|
+
|
27
|
+
def method
|
28
|
+
(raw.options[:method] || options[:method] || :get).to_sym
|
29
|
+
end
|
30
|
+
|
31
|
+
def headers
|
32
|
+
raw.options.fetch(:headers, nil) || raw.options[:headers] = {}
|
33
|
+
end
|
34
|
+
|
35
|
+
def params
|
36
|
+
raw.options.fetch(:params, nil) || raw.options[:params] = {}
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
attr_accessor :iprocessor
|
42
|
+
|
43
|
+
def create_request
|
44
|
+
request = Typhoeus::Request.new(options[:url], typhoeusize(options))
|
45
|
+
request.on_headers do
|
46
|
+
iprocessor.intercept(:after_request, self)
|
47
|
+
iprocessor.intercept(:before_response, self)
|
48
|
+
end
|
49
|
+
request.on_complete { |response| on_complete(response) }
|
50
|
+
request
|
51
|
+
end
|
52
|
+
|
53
|
+
def typhoeusize(options)
|
54
|
+
options = options.deep_dup
|
55
|
+
easy = Ethon::Easy.new
|
56
|
+
options.delete(:url)
|
57
|
+
options.each do |key, v|
|
58
|
+
next if TYPHOEUS_OPTIONS.include? key
|
59
|
+
method = "#{key}="
|
60
|
+
options.delete key unless easy.respond_to?(method)
|
61
|
+
end
|
62
|
+
options
|
63
|
+
end
|
64
|
+
|
65
|
+
# Get configured endpoint and use it for doing the request.
|
66
|
+
# Explicit request options are overriding configured options.
|
67
|
+
def use_configured_endpoint!
|
68
|
+
return unless (endpoint = LHC.config.endpoints[options[:url]])
|
69
|
+
endpoint.options.deep_merge!(options)
|
70
|
+
options.deep_merge!(endpoint.options)
|
71
|
+
options[:url] = endpoint.url
|
72
|
+
end
|
73
|
+
|
74
|
+
# Generates URL from a URL template
|
75
|
+
def generate_url_from_template!
|
76
|
+
endpoint = LHC::Endpoint.new(options[:url])
|
77
|
+
options[:url] = endpoint.compile(options[:params])
|
78
|
+
endpoint.remove_interpolated_params!(options[:params])
|
79
|
+
end
|
80
|
+
|
81
|
+
def on_complete(response)
|
82
|
+
self.response ||= LHC::Response.new(response, self)
|
83
|
+
iprocessor.intercept(:after_response, self.response)
|
84
|
+
throw_error unless self.response.success?
|
85
|
+
end
|
86
|
+
|
87
|
+
def throw_error
|
88
|
+
error = LHC::Error.find(response)
|
89
|
+
fail error.new(error, response)
|
90
|
+
end
|
91
|
+
end
|