feat(service): add GEOBLOCK negative geofence

Regions in GEOBLOCK refuse the service and everything else is allowed. A hit stops the run with a region error instead of auto-proxying; the check also covers proxy exits and the remote-dl client region.
This commit is contained in:
imSp4rky
2026-09-16 15:06:43 -06:00
parent 1a993f4cb9
commit aec45e30cc
17 changed files with 154 additions and 20 deletions
+7
View File
@@ -109,6 +109,13 @@ def test_build_error_response_debug_mode_includes_traceback() -> None:
(Exception("Connection refused"), APIErrorCode.NETWORK_ERROR),
(TimeoutError("read timeout"), APIErrorCode.NETWORK_ERROR),
(Exception("Not available in your region"), APIErrorCode.GEOFENCE),
(Exception("Service is geoblocked in GB"), APIErrorCode.GEOFENCE),
(
Exception(
"Service is not available in your region (GB). Pass --proxy with a proxy outside the blocked regions."
),
APIErrorCode.GEOFENCE,
),
(Exception("Title not found"), APIErrorCode.NOT_FOUND),
(Exception("HTTP 429 too many requests"), APIErrorCode.RATE_LIMITED),
(Exception("DRM license fetch failed"), APIErrorCode.DRM_ERROR),
@@ -48,6 +48,16 @@ def test_region_mismatch_raises(monkeypatch):
assert exc_info.value.details == {"service": "EXAMPLE"}
def test_geoblocked_client_region_raises(monkeypatch):
patch_server_region(monkeypatch, "CA")
service_class = handlers.Services.load("EXAMPLE")
monkeypatch.setattr(service_class, "GEOBLOCK", ("GB",), raising=False)
with pytest.raises(APIError) as exc_info:
handlers.resolve_handler_proxy({"client_region": "gb"}, "EXAMPLE", request("plainkey"))
assert exc_info.value.error_code == APIErrorCode.GEOFENCE
assert exc_info.value.details == {"service": "EXAMPLE"}
def test_region_match_no_proxy(monkeypatch):
patch_server_region(monkeypatch, "CA")
assert handlers.resolve_handler_proxy({"client_region": "ca"}, "EXAMPLE", request("plainkey")) == (None, [])