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



129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/chargebee/nativeRequest.rb', line 129

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



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/chargebee/nativeRequest.rb', line 108

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



98
99
100
101
102
103
104
105
106
# File 'lib/chargebee/nativeRequest.rb', line 98

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
91
92
93
94
95
96
# 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 rheaders[:content_encoding] == 'gzip' && rbody && !rbody.empty?
    rbody = StringIO.new(rbody)
    gz = Zlib::GzipReader.new(rbody)
    begin
      rbody = gz.read
    ensure
      gz.close
    end
  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