import pytest
class TestRequestsAdapter:
@pytest.fixture
def safe_session(self):
requests = pytest.importorskip("requests")
from url_jail.adapters import safe_session
return safe_session()
def test_fetch_public_url(self, safe_session):
response = safe_session.get("https://httpbin.org/get")
assert response.status_code == 200
def test_blocks_loopback(self, safe_session):
from url_jail import SsrfBlocked
with pytest.raises(SsrfBlocked):
safe_session.get("http://127.0.0.1/")
def test_blocks_metadata(self, safe_session):
from url_jail import SsrfBlocked, HostnameBlocked
with pytest.raises((SsrfBlocked, HostnameBlocked)):
safe_session.get("http://169.254.169.254/")
def test_blocks_private_ip(self, safe_session):
from url_jail import SsrfBlocked
with pytest.raises(SsrfBlocked):
safe_session.get("http://192.168.1.1/")
def test_allows_private_with_policy(self):
pytest.importorskip("requests")
from url_jail.adapters import safe_session
from url_jail import Policy
session = safe_session(policy=Policy.ALLOW_PRIVATE)
class TestHttpxAdapter:
@pytest.fixture
def safe_client(self):
httpx = pytest.importorskip("httpx")
from url_jail.adapters import safe_httpx_client
return safe_httpx_client()
def test_fetch_public_url(self, safe_client):
response = safe_client.get("https://httpbin.org/get")
assert response.status_code == 200
safe_client.close()
def test_blocks_loopback(self, safe_client):
from url_jail import SsrfBlocked
with pytest.raises(SsrfBlocked):
safe_client.get("http://127.0.0.1/")
safe_client.close()
def test_blocks_metadata(self, safe_client):
from url_jail import SsrfBlocked, HostnameBlocked
with pytest.raises((SsrfBlocked, HostnameBlocked)):
safe_client.get("http://169.254.169.254/")
safe_client.close()
class TestHttpxAsyncAdapter:
@pytest.fixture
def safe_async_client(self):
httpx = pytest.importorskip("httpx")
from url_jail.adapters import safe_httpx_async_client
return safe_httpx_async_client()
@pytest.mark.asyncio
async def test_fetch_public_url(self, safe_async_client):
async with safe_async_client as client:
response = await client.get("https://httpbin.org/get")
assert response.status_code == 200
@pytest.mark.asyncio
async def test_blocks_loopback(self, safe_async_client):
from url_jail import SsrfBlocked
async with safe_async_client as client:
with pytest.raises(SsrfBlocked):
await client.get("http://127.0.0.1/")
class TestAiohttpAdapter:
@pytest.mark.asyncio
async def test_fetch_public_url(self):
aiohttp = pytest.importorskip("aiohttp")
from url_jail.adapters import safe_aiohttp_session
async with safe_aiohttp_session() as session:
async with session.get("https://httpbin.org/get") as response:
assert response.status == 200
@pytest.mark.asyncio
async def test_blocks_loopback(self):
aiohttp = pytest.importorskip("aiohttp")
from url_jail.adapters import safe_aiohttp_session
from url_jail import SsrfBlocked
async with safe_aiohttp_session() as session:
with pytest.raises(SsrfBlocked):
async with session.get("http://127.0.0.1/"):
pass
class TestUrllib3Adapter:
@pytest.fixture
def safe_pool(self):
urllib3 = pytest.importorskip("urllib3")
from url_jail.adapters import safe_urllib3_pool
return safe_urllib3_pool()
def test_fetch_public_url(self, safe_pool):
response = safe_pool.request("GET", "https://httpbin.org/get")
assert response.status == 200
def test_blocks_loopback(self, safe_pool):
from url_jail import SsrfBlocked
with pytest.raises(SsrfBlocked):
safe_pool.request("GET", "http://127.0.0.1/")
def test_blocks_metadata(self, safe_pool):
from url_jail import SsrfBlocked, HostnameBlocked
with pytest.raises((SsrfBlocked, HostnameBlocked)):
safe_pool.request("GET", "http://169.254.169.254/")
def test_blocks_private_ip(self, safe_pool):
from url_jail import SsrfBlocked
with pytest.raises(SsrfBlocked):
safe_pool.request("GET", "http://192.168.1.1/")
class TestAdapterPolicies:
def test_requests_custom_policy(self):
pytest.importorskip("requests")
from url_jail.adapters import safe_session
from url_jail import Policy
session = safe_session(policy=Policy.ALLOW_PRIVATE)
assert session is not None
def test_httpx_custom_policy(self):
pytest.importorskip("httpx")
from url_jail.adapters import safe_httpx_client
from url_jail import Policy
client = safe_httpx_client(policy=Policy.ALLOW_PRIVATE)
assert client is not None
client.close()
@pytest.mark.asyncio
async def test_aiohttp_custom_policy(self):
pytest.importorskip("aiohttp")
from url_jail.adapters import safe_aiohttp_session
from url_jail import Policy
session = safe_aiohttp_session(policy=Policy.ALLOW_PRIVATE)
assert session is not None
await session.close()
def test_urllib3_custom_policy(self):
pytest.importorskip("urllib3")
from url_jail.adapters import safe_urllib3_pool
from url_jail import Policy
pool = safe_urllib3_pool(policy=Policy.ALLOW_PRIVATE)
assert pool is not None