Module: ChargeBee::NativeRequest

Defined in:
lib/chargebee/nativeRequest.rb

Class Method Summary collapse

Class Method Details

.beautify_headers(headers) ⇒ Object

directly copying headers formatting from rest-client to support backward compatability for rest-client



123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/chargebee/nativeRequest.rb', line 123

def self.beautify_headers(headers)
  headers.inject({}) do |out, (key, value)|
    key_sym = key.tr('-', '_').downcase.to_sym

    # Handle Set-Cookie specially since it cannot be joined by comma.
    if key.downcase == 'set-cookie'
      out[key_sym] = value
    else
      out[key_sym] = value.join(', ')
    end

    out
  end
end

.handle_for_error(rcode, rbody) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/chargebee/nativeRequest.rb', line 102

def self.handle_for_error(rcode, rbody)
  return Error.new("No response returned by ChargeBee API. HTTP status code: #{rcode}") if rcode == 204
  begin
    error_obj = JSON.parse(rbody)
    error_obj = Util.symbolize_keys(error_obj)
  rescue Exception => e
    raise Error.new("Error response not in JSON format. The http status code is #{rcode} \n #{rbody.inspect}",e)
  end
  type = error_obj[:type]
  case type
  when "payment"
    raise PaymentError.new(rcode, error_obj)
  when "operation_failed"
    raise OperationFailedError.new(rcode, error_obj)
  when "invalid_request"
    raise InvalidRequestError.new(rcode, error_obj)
  else
    raise APIError.new(rcode, error_obj)
  end
end

.handle_json_error(rbody, e) ⇒ Object



92
93
94
95
96
97
98
99
100
# File 'lib/chargebee/nativeRequest.rb', line 92

def self.handle_json_error(rbody, e)
  if rbody.include?("503")
    raise Error.new("Sorry, the server is currently unable to handle the request due to a temporary overload or scheduled maintenance. Please retry after sometime. \n type: internal_temporary_error, \n http_status_code: 503, \n error_code: internal_temporary_error,\n content: #{rbody.inspect}",e)
  elsif rbody.include?("504")
    raise Error.new("The server did not receive a timely response from an upstream server, request aborted. If this problem persists, contact us at support@chargebee.com. \n type: gateway_timeout, \n http_status_code: 504, \n error_code: gateway_timeout,\n content:  #{rbody.inspect}",e)
  else
    raise Error.new("Sorry, something went wrong when trying to process the request. If this problem persists, contact us at support@chargebee.com. \n type: internal_error, \n http_status_code: 500, \n error_code: internal_error,\n content:  #{rbody.inspect}",e)
  end
end

.handle_response(response, headers) ⇒ Object



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
# File 'lib/chargebee/nativeRequest.rb', line 64

def self.handle_response(response, headers)
  rcode = response.code.to_i
  rbody = response.body

  # converting headers to rest-client format previously we were using rest-client,
  # and mapping headers to that format to support backward compatability
  rheaders = beautify_headers(response.to_hash)

  # When a custom 'Accept-Encoding' header is set to gzip, Net::HTTP will not automatically
  # decompress the response. Therefore, we need to manually handle decompression
  # based on the 'Content-Encoding' header in the response.
  # https://github.com/ruby/ruby/blob/19c1f0233eb5202403c52b196f1d573893eacab7/lib/net/http/generic_request.rb#L82
  if headers.keys.any? { |k| k.downcase == 'accept-encoding' } && rheaders[:content_encoding] == 'gzip' && rbody && !rbody.empty?
    rbody = Zlib::GzipReader.new(StringIO.new(rbody)).read
  end

  if rcode >= 200 && rcode < 300
    begin
      resp = JSON.parse(rbody)
    rescue JSON::ParserError => e
      raise handle_json_error(rbody, e)
    end
    return Util.symbolize_keys(resp), rheaders, rcode
  else
    raise handle_for_error(rcode, rbody)
  end
end

.request(method, url, env, params = nil, headers = {}, subdomain = nil, isJsonRequest = false) ⇒ Object

Raises:



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/chargebee/nativeRequest.rb', line 9

def self.request(method, url, env, params = nil, headers = {}, subdomain = nil, isJsonRequest = false)
  raise Error.new('No environment configured.') unless env
  api_key = env.api_key

  uri = URI(env.api_url(url, subdomain))

  case method.to_s.downcase.to_sym
  when :get, :head, :delete
    uri.query = URI.encode_www_form(params) if params
    payload = nil
  else
    payload = isJsonRequest ? params : URI.encode_www_form(params || {})
  end
  user_agent = ChargeBee.user_agent
  content_type_header = isJsonRequest ? "application/json;charset=UTF-8" : "application/x-www-form-urlencoded"
  headers = {
    "User-Agent" => user_agent,
    "Accept" => "application/json",
    "Lang-Version" => RUBY_VERSION,
    "OS-Version" => RUBY_PLATFORM,
    "Content-Type" => content_type_header
  }.merge(headers)

  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  http.open_timeout=env.connect_timeout
  http.read_timeout=env.read_timeout
  if ChargeBee.verify_ca_certs?
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
    http.ca_file = ChargeBee.ca_cert_path
  else
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  end

  request_class = case method.to_s.downcase.to_sym
                  when :get then Net::HTTP::Get
                  when :post then Net::HTTP::Post
                  when :put then Net::HTTP::Put
                  when :delete then Net::HTTP::Delete
                  else raise Error.new("Unsupported HTTP method: #{method}")
                  end

  request = request_class.new(uri, headers)
  request.body = payload if payload

  request.basic_auth(api_key, nil)

  begin
    response = http.request(request)
  rescue => e
    raise IOError.new("IO Exception when trying to connect to ChargeBee with URL #{uri} . Reason: #{e}", e)
  end
  handle_response(response, headers)
end