lib/stripe/stripe_response.rb in stripe-5.34.0 vs lib/stripe/stripe_response.rb in stripe-5.35.0
- old
+ new
@@ -1,82 +1,110 @@
# frozen_string_literal: true
module Stripe
- # StripeResponse encapsulates some vitals of a response that came back from
- # the Stripe API.
- class StripeResponse
- # Headers provides an access wrapper to an API response's header data. It
- # mainly exists so that we don't need to expose the entire
- # `Net::HTTPResponse` object while still getting some of its benefits like
- # case-insensitive access to header names and flattening of header values.
- class Headers
- # Initializes a Headers object from a Net::HTTP::HTTPResponse object.
- def self.from_net_http(resp)
- new(resp.to_hash)
+ # Headers provides an access wrapper to an API response's header data. It
+ # mainly exists so that we don't need to expose the entire
+ # `Net::HTTPResponse` object while still getting some of its benefits like
+ # case-insensitive access to header names and flattening of header values.
+ class StripeResponseHeaders
+ # Initializes a Headers object from a Net::HTTP::HTTPResponse object.
+ def self.from_net_http(resp)
+ new(resp.to_hash)
+ end
+
+ # `hash` is expected to be a hash mapping header names to arrays of
+ # header values. This is the default format generated by calling
+ # `#to_hash` on a `Net::HTTPResponse` object because headers can be
+ # repeated multiple times. Using `#[]` will collapse values down to just
+ # the first.
+ def initialize(hash)
+ if !hash.is_a?(Hash) ||
+ !hash.keys.all? { |n| n.is_a?(String) } ||
+ !hash.values.all? { |a| a.is_a?(Array) } ||
+ !hash.values.all? { |a| a.all? { |v| v.is_a?(String) } }
+ raise ArgumentError,
+ "expect hash to be a map of string header names to arrays of " \
+ "header values"
end
- # `hash` is expected to be a hash mapping header names to arrays of
- # header values. This is the default format generated by calling
- # `#to_hash` on a `Net::HTTPResponse` object because headers can be
- # repeated multiple times. Using `#[]` will collapse values down to just
- # the first.
- def initialize(hash)
- if !hash.is_a?(Hash) ||
- !hash.keys.all? { |n| n.is_a?(String) } ||
- !hash.values.all? { |a| a.is_a?(Array) } ||
- !hash.values.all? { |a| a.all? { |v| v.is_a?(String) } }
- raise ArgumentError,
- "expect hash to be a map of string header names to arrays of " \
- "header values"
- end
+ @hash = {}
- @hash = {}
-
- # This shouldn't be strictly necessary because `Net::HTTPResponse` will
- # produce a hash with all headers downcased, but do it anyway just in
- # case an object of this class was constructed manually.
- #
- # Also has the effect of duplicating the hash, which is desirable for a
- # little extra object safety.
- hash.each do |k, v|
- @hash[k.downcase] = v
- end
+ # This shouldn't be strictly necessary because `Net::HTTPResponse` will
+ # produce a hash with all headers downcased, but do it anyway just in
+ # case an object of this class was constructed manually.
+ #
+ # Also has the effect of duplicating the hash, which is desirable for a
+ # little extra object safety.
+ hash.each do |k, v|
+ @hash[k.downcase] = v
end
+ end
- def [](name)
- values = @hash[name.downcase]
- if values && values.count > 1
- warn("Duplicate header values for `#{name}`; returning only first")
- end
- values ? values.first : nil
+ def [](name)
+ values = @hash[name.downcase]
+ if values && values.count > 1
+ warn("Duplicate header values for `#{name}`; returning only first")
end
+ values ? values.first : nil
end
+ end
- # The data contained by the HTTP body of the response deserialized from
- # JSON.
- attr_accessor :data
-
- # The raw HTTP body of the response.
- attr_accessor :http_body
-
+ module StripeResponseBase
# A Hash of the HTTP headers of the response.
attr_accessor :http_headers
# The integer HTTP status code of the response.
attr_accessor :http_status
# The Stripe request ID of the response.
attr_accessor :request_id
+ def self.populate_for_net_http(resp, http_resp)
+ resp.http_headers = StripeResponseHeaders.from_net_http(http_resp)
+ resp.http_status = http_resp.code.to_i
+ resp.request_id = http_resp["request-id"]
+ end
+ end
+
+ # StripeResponse encapsulates some vitals of a response that came back from
+ # the Stripe API.
+ class StripeResponse
+ include StripeResponseBase
+ # The data contained by the HTTP body of the response deserialized from
+ # JSON.
+ attr_accessor :data
+
+ # The raw HTTP body of the response.
+ attr_accessor :http_body
+
# Initializes a StripeResponse object from a Net::HTTP::HTTPResponse
# object.
def self.from_net_http(http_resp)
resp = StripeResponse.new
resp.data = JSON.parse(http_resp.body, symbolize_names: true)
resp.http_body = http_resp.body
- resp.http_headers = Headers.from_net_http(http_resp)
- resp.http_status = http_resp.code.to_i
- resp.request_id = http_resp["request-id"]
+ StripeResponseBase.populate_for_net_http(resp, http_resp)
+ resp
+ end
+ end
+
+ # We have to alias StripeResponseHeaders to StripeResponse::Headers, as this
+ # class used to be embedded within StripeResponse and we want to be backwards
+ # compatible.
+ StripeResponse::Headers = StripeResponseHeaders
+
+ # StripeHeadersOnlyResponse includes only header-related vitals of the
+ # response. This is used for streaming requests where the response was read
+ # directly in a block and we explicitly don't want to store the body of the
+ # response in memory.
+ class StripeHeadersOnlyResponse
+ include StripeResponseBase
+
+ # Initializes a StripeHeadersOnlyResponse object from a
+ # Net::HTTP::HTTPResponse object.
+ def self.from_net_http(http_resp)
+ resp = StripeHeadersOnlyResponse.new
+ StripeResponseBase.populate_for_net_http(resp, http_resp)
resp
end
end
end