mirror of
https://github.com/stripe/stripe-ruby.git
synced 2025-05-15 00:01:39 -04:00
109 lines
3.7 KiB
Ruby
109 lines
3.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Stripe
|
|
# 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 = {}
|
|
|
|
# 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]
|
|
warn("Duplicate header values for `#{name}`; returning only first") if values && values.count > 1
|
|
values ? values.first : nil
|
|
end
|
|
end
|
|
|
|
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
|
|
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
|