Class: Trackdown::Providers::CloudfrontProvider
- Inherits:
-
BaseProvider
- Object
- BaseProvider
- Trackdown::Providers::CloudfrontProvider
- Defined in:
- lib/trackdown/providers/cloudfront_provider.rb
Overview
Provider that uses Amazon CloudFront HTTP headers for IP geolocation. This is the fastest and most lightweight option when your app is behind CloudFront (the AWS CDN) — a direct analog to the Cloudflare provider.
CloudFront resolves the viewer's location at the edge and forwards it to the origin as CloudFront-Viewer-* headers. To receive them, attach an origin request policy that forwards the CloudFront geolocation headers.
Exact AWS viewer-location header contract (names, availability, encoding): https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-cloudfront-headers.html#cloudfront-headers-viewer-location Exact AWS managed-policy contents: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html#managed-origin-request-policy-all-viewer-and-cloudfront
IMPORTANT: Header presence does not authenticate CloudFront. A custom origin must reject direct traffic before an application can trust these values. AWS's exact origin-restriction guidance is: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-overview.html
Note: CloudFront does not emit a continent header. We derive #continent from the country code so it matches the 2-letter code (e.g. "NA") the other providers return. The countries gem exposes a continent name ("North America") but no code, and its names don't map by initials (Africa/Asia/Antarctica/Australia all start with "A", and it labels Oceania "Australia"), so an explicit table is the only reliable mapping.
Constant Summary collapse
- CONTINENT_CODES =
ISO3166 continent name (from the countries gem) => 2-letter code used by the Cloudflare and MaxMind providers. countries gem source: https://github.com/countries/countries
{ 'Africa' => 'AF', 'Antarctica' => 'AN', 'Asia' => 'AS', 'Europe' => 'EU', 'North America' => 'NA', 'South America' => 'SA', 'Australia' => 'OC' # the countries gem labels Oceania "Australia" }.freeze
- COUNTRY_HEADER =
Rack exposes ordinary HTTP request headers as HTTP_* environment entries: https://github.com/rack/rack/blob/main/SPEC.rdoc#http_-headers
'HTTP_CLOUDFRONT_VIEWER_COUNTRY'- CITY_HEADER =
'HTTP_CLOUDFRONT_VIEWER_CITY'- REGION_HEADER =
CloudFront exposes both a region code ("CA") and its full name ("California"). Match the Cloudflare provider's semantics: #region is the name, #region_code the code.
'HTTP_CLOUDFRONT_VIEWER_COUNTRY_REGION_NAME'- REGION_CODE_HEADER =
'HTTP_CLOUDFRONT_VIEWER_COUNTRY_REGION'- LATITUDE_HEADER =
'HTTP_CLOUDFRONT_VIEWER_LATITUDE'- LONGITUDE_HEADER =
'HTTP_CLOUDFRONT_VIEWER_LONGITUDE'- TIMEZONE_HEADER =
'HTTP_CLOUDFRONT_VIEWER_TIME_ZONE'- POSTAL_CODE_HEADER =
'HTTP_CLOUDFRONT_VIEWER_POSTAL_CODE'- METRO_CODE_HEADER =
'HTTP_CLOUDFRONT_VIEWER_METRO_CODE'
Class Method Summary collapse
-
.available?(request: nil) ⇒ Boolean
Check if CloudFront headers are available in the request.
-
.locate(_ip, request: nil) ⇒ LocationResult
Locate IP using CloudFront headers.
- .provider_name ⇒ Object
- .provider_source ⇒ Object
Methods inherited from BaseProvider
get_country_name, get_emoji_flag, parse_coordinate, request_provenance
Class Method Details
.available?(request: nil) ⇒ Boolean
Check if CloudFront headers are available in the request
84 85 86 87 88 |
# File 'lib/trackdown/providers/cloudfront_provider.rb', line 84 def available?(request: nil) return false unless request !extract_country_code(request).nil? end |
.locate(_ip, request: nil) ⇒ LocationResult
Locate IP using CloudFront headers
94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/trackdown/providers/cloudfront_provider.rb', line 94 def locate(_ip, request: nil) raise Trackdown::Error, 'CloudfrontProvider requires a request object with CloudFront headers' unless request provenance = request_provenance(request) country_code = extract_country_code(request) # If no valid country code, return unknown return LocationResult.unavailable(:provider_returned_unknown_country, **provenance) if country_code.nil? build_location_result(country_code, request, **provenance) end |
.provider_name ⇒ Object
75 76 77 |
# File 'lib/trackdown/providers/cloudfront_provider.rb', line 75 def provider_name :cloudfront end |
.provider_source ⇒ Object
79 80 81 |
# File 'lib/trackdown/providers/cloudfront_provider.rb', line 79 def provider_source :cloudfront_request_headers end |