Class: EasyPost::HttpClient

Inherits:
Object
  • Object
show all
Defined in:
lib/easypost/http_client.rb

Instance Method Summary collapse

Constructor Details

#initialize(base_url, config, custom_client_exec = nil) ⇒ HttpClient

Returns a new instance of HttpClient.



6
7
8
9
10
# File 'lib/easypost/http_client.rb', line 6

def initialize(base_url, config, custom_client_exec = nil)
  @base_url = base_url
  @config = config
  @custom_client_exec = custom_client_exec
end

Instance Method Details

#default_request_execute(method, uri, headers, open_timeout, read_timeout, body = nil) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/easypost/http_client.rb', line 88

def default_request_execute(method, uri, headers, open_timeout, read_timeout, body = nil)
  # Create the request, set the headers and body if necessary.
  request = Net::HTTP.const_get(method.capitalize).new(uri)
  headers.each { |k, v| request[k] = v }
  request.body = body if body

  begin
    # Attempt to make the request and return the response.
    Net::HTTP.start(
      uri.host,
      uri.port,
      use_ssl: true,
      read_timeout: read_timeout,
      open_timeout: open_timeout,
    ) do |http|
      http.request(request)
    end
  rescue Net::ReadTimeout, Net::OpenTimeout, Errno::EHOSTUNREACH => e
    # Raise a timeout error if the request times out.
    raise EasyPost::Errors::TimeoutError.new(e.message)
  rescue OpenSSL::SSL::SSLError => e
    # Raise an SSL error if the request fails due to an SSL error.
    raise EasyPost::Errors::SslError.new(e.message)
  rescue StandardError => e
    # Raise an unknown HTTP error if anything else causes the request to fail to complete
    # (this is different from processing 4xx/5xx errors from the API)
    raise EasyPost::Errors::UnknownApiError.new(e.message)
  end
end

#request(method, path, headers = nil, body = nil, api_version = EasyPost::InternalUtilities::Constants::API_VERSION) ⇒ Object

Execute an HTTP request to the API.



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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/easypost/http_client.rb', line 13

def request(
  method,
  path,
  headers = nil,
  body = nil,
  api_version = EasyPost::InternalUtilities::Constants::API_VERSION
)
  # Remove leading slash from path.
  path = path[1..] if path[0] == '/'

  uri = URI.parse("#{@base_url}/#{api_version}/#{path}")
  headers = @config[:headers].merge(headers || {})
  serialized_body = JSON.dump(EasyPost::InternalUtilities.objects_to_ids(body)) if body
  open_timeout = @config[:open_timeout]
  read_timeout = @config[:read_timeout]
  request_timestamp = Time.now
  request_uuid = SecureRandom.uuid

  if EasyPost::Hooks.any_subscribers?(:request)
    request_context = EasyPost::Hooks::RequestContext.new(
      method: method,
      path: uri.to_s,
      headers: headers,
      request_body: body,
      request_timestamp: request_timestamp,
      request_uuid: request_uuid,
    )
    EasyPost::Hooks.notify(:request, request_context)
  end

  # Execute the request, return the response.

  response = if @custom_client_exec
               @custom_client_exec.call(method, uri, headers, open_timeout, read_timeout, serialized_body)
             else
               default_request_execute(method, uri, headers, open_timeout, read_timeout, serialized_body)
             end
  response_timestamp = Time.now

  if EasyPost::Hooks.any_subscribers?(:response)
    response_context = {
      http_status: nil,
      method: method,
      path: uri.to_s,
      headers: nil,
      response_body: nil,
      request_timestamp: request_timestamp,
      response_timestamp: response_timestamp,
      client_response_object: response,
      request_uuid: request_uuid,
    }

    # If using a custom HTTP client, the user will have to infer these from the raw
    # client_response_object attribute
    if response.is_a?(Net::HTTPResponse)
      response_body = begin
        JSON.parse(response.body)
      rescue JSON::ParseError
        response.body
      end
      response_context.merge!(
        {
          http_status: response.code.to_i,
          headers: response.each_header.to_h,
          response_body: response_body,
        },
      )
    end

    EasyPost::Hooks.notify(:response, EasyPost::Hooks::ResponseContext.new(**response_context))
  end

  response
end