Class: SoraGeocoding::Request

Inherits:
Base
  • Object
show all
Defined in:
lib/sora_geocoding/request.rb

Instance Method Summary collapse

Methods inherited from Base

#configuration, #handle, #raise_error

Instance Method Details

#check_response_for_errors!(response) ⇒ Object

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity



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
# File 'lib/sora_geocoding/request.rb', line 22

def check_response_for_errors!(response)
  if response.code.to_i == 400
    raise_error(SoraGeocoding::InvalidRequest) ||
      SoraGeocoding.log(:warn, 'API error: 400 Bad Request')
  elsif response.code.to_i == 401
    raise_error(SoraGeocoding::RequestDenied) ||
      SoraGeocoding.log(:warn, 'API error: 401 Unauthorized')
  elsif response.code.to_i == 402
    raise_error(SoraGeocoding::PaymentRequiredError) ||
      SoraGeocoding.log(:warn, 'API error: 402 Payment Required')
  elsif response.code.to_i == 403
    raise_error(SoraGeocoding::ForbiddenError) ||
      SoraGeocoding.log(:warn, 'API error: 403 Forbidden')
  elsif response.code.to_i == 404
    raise_error(SoraGeocoding::NotFoundError) ||
      SoraGeocoding.log(:warn, 'API error: 404 Not Found')
  elsif response.code.to_i == 407
    raise_error(SoraGeocoding::ProxyAuthenticationRequiredError) ||
      SoraGeocoding.log(:warn, 'API error: 407 Proxy Authentication Required')
  elsif response.code.to_i == 429
    raise_error(SoraGeocoding::OverQueryLimitError) ||
      SoraGeocoding.log(:warn, 'API error: 429 Too Many Requests')
  elsif response.code.to_i == 503
    raise_error(SoraGeocoding::ServiceUnavailable) ||
      SoraGeocoding.log(:warn, 'API error: 503 Service Unavailable')
  end
end

#configure_ssl!(client) ⇒ Object



105
# File 'lib/sora_geocoding/request.rb', line 105

def configure_ssl!(client); end

#fetch_data(query) ⇒ Object

rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/sora_geocoding/request.rb', line 51

def fetch_data(query)
  parse_raw_data(fetch_raw_data(query))
rescue SocketError => e
  raise_error(e) || SoraGeocoding.log(:warn, 'API connection cannot be established.')
rescue Errno::ECONNREFUSED => e
  raise_error(e) || SoraGeocoding.log(:warn, 'API connection refused.')
rescue SoraGeocoding::NetworkError => e
  raise_error(e) || SoraGeocoding.log(:warn, 'API connection is either unreacheable or reset by the peer')
rescue SoraGeocoding::Timeout => e
  raise_error(e) || SoraGeocoding.log(:warn, 'API not responding fast enough ' \
    '(use SoraGeocoding.configure(:timeout => ...) to set limit).')
end

#http_client ⇒ Object

Make HTTP requests.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/sora_geocoding/request.rb', line 117

def http_client
  proxy = configuration.send("#{protocol}_proxy")
  if proxy
    proxy_url = proxy =~ /^#{protocol}/ ? proxy : protocol + '://' + proxy
    begin
      uri = URI.parse(proxy_url)
    rescue URI::InvalidURIError
      raise ConfigurationError, "Error parsing #{protocol.upcase} proxy URL: '#{proxy_url}'"
    end
    Net::HTTP::Proxy(uri.host, uri.port, uri.user, uri.password)
  else
    Net::HTTP
  end
end

#make_api_request(query_url) ⇒ Object

Make an HTTP(S) request to return the response object.

rubocop:disable Metrics/AbcSize



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/sora_geocoding/request.rb', line 68

def make_api_request(query_url)
  uri = URI.parse(query_url)
  SoraGeocoding.log(:debug, "HTTP request being made for #{uri}")
  http_client.start(
    uri.host,
    uri.port,
    use_ssl: use_ssl?(uri.port),
    open_timeout: configuration.timeout,
    read_timeout: configuration.timeout
  ) do |client|
    configure_ssl!(client) if use_ssl?
    req = Net::HTTP::Get.new(uri.request_uri, configuration.http_headers)
    if configuration.basic_auth[:user] && configuration.basic_auth[:password]
      req.basic_auth(configuration.basic_auth[:user], configuration.basic_auth[:password])
    end
    client.request(req)
  end
rescue Timeout::Error
  raise SoraGeocoding::Timeout
rescue Errno::EHOSTUNREACH, Errno::ETIMEDOUT, Errno::ENETUNREACH, Errno::ECONNRESET
  raise SoraGeocoding::NetworkError
end

#parse_raw_data(raw_data) ⇒ Object



17
18
19
# File 'lib/sora_geocoding/request.rb', line 17

def parse_raw_data(raw_data)
  parse_xml(raw_data)
end

#parse_xml(data) ⇒ Object



8
9
10
11
12
13
14
15
# File 'lib/sora_geocoding/request.rb', line 8

def parse_xml(data)
  REXML::Document.new(data)
rescue StandardError
  unless raise_error(ResponseParseError.new(data))
    SoraGeocoding.log(:warn, "API's response was not valid XML")
    SoraGeocoding.log(:debug, "Raw response: #{data}")
  end
end

#protocol ⇒ Object

Generate a string of http, https or protocol.



110
111
112
# File 'lib/sora_geocoding/request.rb', line 110

def protocol
  'http' + (use_ssl? ? 's' : '')
end

#supported_protocols ⇒ Object

Supported Protocols



135
136
137
# File 'lib/sora_geocoding/request.rb', line 135

def supported_protocols
  %i[http https]
end

#use_ssl?(http_port = nil) ⇒ Boolean

Detect if you are using ssl

Returns:

  • (Boolean)


95
96
97
98
99
100
101
102
103
# File 'lib/sora_geocoding/request.rb', line 95

def use_ssl?(http_port = nil)
  if (http_port == 443) || (supported_protocols == [:https])
    true
  elsif supported_protocols == [:http]
    false
  else
    configuration.use_https
  end
end