Class: RestRequestor
- Inherits:
-
Object
- Object
- RestRequestor
- Defined in:
- lib/rest_requestor.rb,
lib/rest_requestor/config.rb,
lib/rest_requestor/version.rb
Defined Under Namespace
Modules: Config Classes: NotFoundError, RateLimitError, ServiceUnavailableError, StandardError, TooManyRedirectsError
Constant Summary collapse
- OPTION_DEFAULTS =
{ max_retries: 7, open_timeout: 10, read_timeout: 30, proxy_address: "127.0.0.1", proxy_port: 9090, user_agent: nil, skip_proxy: true, logger: nil }
- FILE_CONFIG =
Config.load.freeze
- VERSION =
"0.4.0"
Instance Attribute Summary collapse
-
#elapsed ⇒ Object
readonly
Returns the value of attribute elapsed.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#resp ⇒ Object
readonly
Returns the value of attribute resp.
Class Method Summary collapse
-
.ssl_cert_store ⇒ Object
Shared across instances; cert store is immutable after setup.
Instance Method Summary collapse
-
#initialize(**kw_args) ⇒ RestRequestor
constructor
A new instance of RestRequestor.
- #request(uri, verb, j_params: {}, f_hash: {}, q_params: {}, auth: nil, headers: {}, body: nil, retries: 0) ⇒ Object
- #resolve_redirects(url, limit = 10) ⇒ Object
Constructor Details
#initialize(**kw_args) ⇒ RestRequestor
Returns a new instance of RestRequestor.
58 59 60 61 |
# File 'lib/rest_requestor.rb', line 58 def initialize(**kw_args) @options = OPTION_DEFAULTS.merge(FILE_CONFIG).merge(kw_args) warn_no_user_agent if [:user_agent].to_s.strip.empty? end |
Instance Attribute Details
#elapsed ⇒ Object (readonly)
Returns the value of attribute elapsed.
32 33 34 |
# File 'lib/rest_requestor.rb', line 32 def elapsed @elapsed end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
32 33 34 |
# File 'lib/rest_requestor.rb', line 32 def @options end |
#resp ⇒ Object (readonly)
Returns the value of attribute resp.
32 33 34 |
# File 'lib/rest_requestor.rb', line 32 def resp @resp end |
Class Method Details
.ssl_cert_store ⇒ Object
Shared across instances; cert store is immutable after setup
48 49 50 51 52 53 54 55 56 |
# File 'lib/rest_requestor.rb', line 48 def self.ssl_cert_store @ssl_cert_store ||= begin store = OpenSSL::X509::Store.new store.set_default_paths # Prevent failures when CRL distribution points are unreachable store.flags = OpenSSL::X509::V_FLAG_PARTIAL_CHAIN store end end |
Instance Method Details
#request(uri, verb, j_params: {}, f_hash: {}, q_params: {}, auth: nil, headers: {}, body: nil, retries: 0) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/rest_requestor.rb', line 63 def request(uri, verb, j_params: {}, f_hash: {}, q_params: {}, auth: nil, headers: {}, body: nil, retries: 0) unless [:get, :post, :put, :delete, :patch, :head].include?(verb) raise ArgumentError, "Verb must be one of :get, :post, :put, :delete, :patch, :head — got #{verb.inspect}" end uri = add_query_string(uri, q_params) if q_params && !q_params.empty? exec_req(uri, verb, j_params, f_hash, auth, headers, body) case resp.code.to_i when (200...300) return resp.code.to_i if verb == :head if resp["Content-Type"]&.include?("application/json") JSON.parse(resp.body) elsif resp.code.to_i == 200 && !resp.body.to_s.strip.empty? begin JSON.parse(resp.body.to_s) rescue JSON::ParserError 200 end else resp.code.to_i end when 404 then raise NotFoundError.new(uri, verb, resp, j_params) when 429 # Caller must handle rate limits — retry semantics vary per service raise RateLimitError.new(uri, verb, resp, j_params) when 503 if retries <= [:max_retries] retries += 1 waitfor = retry_delay(retries) [:logger]&.info { "Retrying (#{retries}), pausing #{waitfor} seconds" } sleep waitfor # q_params already incorporated into uri above; omit here to avoid double-encoding request(uri, verb, j_params: j_params, f_hash: f_hash, auth: auth, headers: headers, body: body, retries: retries) else raise ServiceUnavailableError.new(uri, verb, resp, j_params) end else raise StandardError.new(uri, verb, resp, j_params) end end |
#resolve_redirects(url, limit = 10) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/rest_requestor.rb', line 105 def resolve_redirects(url, limit = 10) uri = URI.parse(url) limit.times do http = build_http(uri) req = Net::HTTP::Head.new(uri.request_uri) req["User-Agent"] = [:user_agent] unless [:user_agent].to_s.strip.empty? response = http.request(req) return uri.to_s unless response.is_a?(Net::HTTPRedirection) uri = URI.join(uri, response["location"]) end raise TooManyRedirectsError, "Too many redirects resolving #{url}" end |