Class: Trackdown::Providers::AutoProvider
- Inherits:
-
BaseProvider
- Object
- BaseProvider
- Trackdown::Providers::AutoProvider
- Defined in:
- lib/trackdown/providers/auto_provider.rb
Overview
Intelligent provider that automatically selects the best available provider Selection order:
- Use the single edge provider whose client-IP header matches the target IP.
- Try MaxMind, then return Unknown, when no edge provider can be verified.
- Fail closed when both edge providers appear valid; header names alone cannot distinguish an authentic stacked-CDN request from forwarded viewer input.
This is the recommended default for most applications
IMPORTANT: When there's an upstream proxy before the CDN (e.g., a legacy API gateway), the CDN's geo headers will reflect the proxy's location, not the real client. AutoProvider detects this by comparing the CDN's own view of the client IP (CF-Connecting-IP for Cloudflare, CloudFront-Viewer-Address for CloudFront) with the passed IP and falls back to MaxMind (or Unknown when MaxMind is unavailable) on a mismatch.
Cloudflare documents that CF-Connecting-IP is added only on edge-to-origin traffic: https://developers.cloudflare.com/fundamentals/reference/http-headers/#cf-connecting-ip AWS documents that the managed CloudFront policy forwards every viewer header, so CF-* names can still be viewer-controlled when they arrive through CloudFront: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html#managed-origin-request-policy-all-viewer-and-cloudfront
Constant Summary collapse
- CF_CONNECTING_IP_HEADER =
'HTTP_CF_CONNECTING_IP'- CLOUDFRONT_VIEWER_ADDRESS_HEADER =
'HTTP_CLOUDFRONT_VIEWER_ADDRESS'
Class Method Summary collapse
-
.available?(request: nil) ⇒ Boolean
Auto provider is available if at least one provider is available.
-
.locate(ip, request: nil) ⇒ LocationResult
Intelligently locate IP using the best available provider.
-
.provider_name ⇒ Object
:auto has no identity of its own.
- .provider_source ⇒ Object
Methods inherited from BaseProvider
get_country_name, get_emoji_flag, parse_coordinate, request_provenance
Class Method Details
.available?(request: nil) ⇒ Boolean
Auto provider is available if at least one provider is available
54 55 56 57 58 |
# File 'lib/trackdown/providers/auto_provider.rb', line 54 def available?(request: nil) cloudflare_auto_available?(request) || cloudfront_auto_available?(request) || MaxmindProvider.available?(request: request) end |
.locate(ip, request: nil) ⇒ LocationResult
Intelligently locate IP using the best available provider
64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/trackdown/providers/auto_provider.rb', line 64 def locate(ip, request: nil) edge_provider = select_edge_provider(ip, request) return edge_provider.locate(ip, request: request) if edge_provider # Fall back to MaxMind if available return MaxmindProvider.locate(ip, request: request) if MaxmindProvider.available?(request: request) # No providers available - fail gracefully with a warning warn_no_providers LocationResult.unavailable(:no_provider_available) end |
.provider_name ⇒ Object
:auto has no identity of its own. Every result names whichever provider actually won, and a result with no provider at all names none.
45 46 47 |
# File 'lib/trackdown/providers/auto_provider.rb', line 45 def provider_name nil end |
.provider_source ⇒ Object
49 50 51 |
# File 'lib/trackdown/providers/auto_provider.rb', line 49 def provider_source nil end |