Class: LlmCostTracker::PriceSync::Fetcher

Inherits:
Object
  • Object
show all
Defined in:
lib/llm_cost_tracker/price_sync/fetcher.rb

Defined Under Namespace

Classes: Response

Constant Summary collapse

USER_AGENT =
"llm_cost_tracker price refresh"
MAX_REDIRECTS =
5
MAX_BODY_BYTES =
2_097_152
OPEN_TIMEOUT =
5
READ_TIMEOUT =
10
WRITE_TIMEOUT =
10

Instance Method Summary collapse

Instance Method Details

#get(url, etag: nil, redirects: 0) ⇒ Object



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
# File 'lib/llm_cost_tracker/price_sync/fetcher.rb', line 25

def get(url, etag: nil, redirects: 0)
  raise Error, "Too many redirects while fetching #{url}" if redirects > MAX_REDIRECTS

  uri = URI.parse(url)
  raise Error, "Pricing snapshot URL must use https" unless uri.scheme == "https"

  request = Net::HTTP::Get.new(uri)
  request["User-Agent"] = USER_AGENT
  request["If-None-Match"] = etag if etag

  response, body = fetch_response(uri, request)

  case response
  when Net::HTTPSuccess
    build_response(response, body: body || limited_body(response), not_modified: false)
  when Net::HTTPNotModified
    build_response(response, body: nil, not_modified: true)
  when Net::HTTPRedirection
    location = response["location"]
    raise Error, "Redirect without location while fetching #{url}" if location.nil? || location.empty?

    get(URI.join(url, location).to_s, etag: etag, redirects: redirects + 1)
  else
    raise Error, "Unable to fetch #{url}: HTTP #{response.code}"
  end
rescue OpenSSL::SSL::SSLError, SocketError, SystemCallError, Timeout::Error => e
  raise Error, "Unable to fetch #{url}: #{e.class}: #{e.message}"
end