- Added `opencontractserver/constants/safe_http.py` with `PUBLIC_DOMAIN_SOURCE_HOSTS` allowlist (5 gov hosts), `ALLOWED_SCHEMES`, `MAX_REDIRECTS`, `CONNECT_TIMEOUT_SECONDS`, `READ_TIMEOUT_SECONDS`, and `MAX_RESPONSE_BYTES` (500 MB) constants.
- Added `opencontractserver/utils/safe_http.py` with `SSRFValidationError`, `host_on_allowlist()`, `_assert_public_ip()` (rejects any private/loopback/link-local/multicast/reserved/unspecified address from ANY resolved A/AAAA record), `validate_url()`, `safe_fetch_bytes()` (manual redirect loop re-validating every hop, streamed size cap, timeouts via httpx), and `safe_fetch_text()` (UTF-8 wrapper).
- Added `opencontractserver/tests/test_safe_http.py` (24 tests, no DB) covering: scheme rejection, host allowlist rejection, private-IP rejection (loopback/RFC-1918/link-local/IPv6), redirect re-validation (private target rejected), Content-Length cap, streamed-bytes cap, and happy-path round-trips.
