Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion sentry_sdk/integrations/aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,14 @@ def aiohttp_processor(

request_info["query_string"] = request.query_string
request_info["method"] = request.method
request_info["env"] = {"REMOTE_ADDR": request.remote}

# REMOTE_ADDR was unconditionally set pre-data collection, so it
# continues to be set when data collection is not enabled.
if (
not has_data_collection_enabled(client_options)
or client_options["data_collection"]["user_info"]
):
request_info["env"] = {"REMOTE_ADDR": request.remote}
request_info["headers"] = _filter_headers(dict(request.headers))

# Just attach raw data here if it is within bounds, if available.
Expand Down
9 changes: 8 additions & 1 deletion sentry_sdk/integrations/sanic.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,14 @@ def sanic_processor(event: "Event", hint: "Optional[Hint]") -> "Optional[Event]"
request_info["query_string"] = urlparts.query

request_info["method"] = request.method
request_info["env"] = {"REMOTE_ADDR": request.remote_addr}

# REMOTE_ADDR was unconditionally set pre-data collection, so it
# continues to be set when data collection is not enabled.
if (
not has_data_collection_enabled(client_options)
or client_options["data_collection"]["user_info"]
):
request_info["env"] = {"REMOTE_ADDR": request.remote_addr}
request_info["headers"] = _filter_headers(dict(request.headers))

return event
Expand Down
9 changes: 8 additions & 1 deletion sentry_sdk/integrations/tornado.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,14 @@ def tornado_processor(event: "Event", hint: "dict[str, Any]") -> "Event":
request_info["query_string"] = request.query

request_info["method"] = request.method
request_info["env"] = {"REMOTE_ADDR": request.remote_ip}

# REMOTE_ADDR was unconditionally set pre-data collection, so it
# continues to be set when data collection is not enabled.
if (
not has_data_collection_enabled(client_options)
or client_options["data_collection"]["user_info"]
):
request_info["env"] = {"REMOTE_ADDR": request.remote_ip}
request_info["headers"] = _filter_headers(dict(request.headers))

if has_data_collection_enabled(client_options):
Expand Down
34 changes: 33 additions & 1 deletion tests/integrations/aiohttp/test_aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@
)
from sentry_sdk.utils import SENSITIVE_DATA_SUBSTITUTE
from tests.conftest import ApproxDict
from tests.integrations.utils import DATA_COLLECTION_USER_INFO_CASES
from tests.integrations.utils import (
DATA_COLLECTION_REMOTE_ADDR_CASES,
DATA_COLLECTION_USER_INFO_CASES,
)


@pytest.mark.asyncio
Expand Down Expand Up @@ -2268,3 +2271,32 @@ async def hello(request):
assert "url.query" not in inner_client_span["attributes"]
else:
assert inner_client_span["attributes"]["url.query"] == expected_query


@pytest.mark.asyncio
@pytest.mark.parametrize(
"init_kwargs, expect_remote_addr", DATA_COLLECTION_REMOTE_ADDR_CASES
)
async def test_remote_addr_data_collection(
sentry_init, aiohttp_client, capture_events, init_kwargs, expect_remote_addr
):
sentry_init(integrations=[AioHttpIntegration()], **init_kwargs)

async def hello(request):
capture_message("hi")
return web.Response(text="hello")

app = web.Application()
app.router.add_get("/", hello)

events = capture_events()

client = await aiohttp_client(app)
resp = await client.get("/")
assert resp.status == 200

(event,) = events
if expect_remote_addr:
assert event["request"]["env"] == {"REMOTE_ADDR": "127.0.0.1"}
else:
assert "env" not in event["request"]
26 changes: 25 additions & 1 deletion tests/integrations/sanic/test_sanic.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
from sentry_sdk.integrations.sanic import SanicIntegration
from sentry_sdk.tracing import TransactionSource
from tests.conftest import get_free_port
from tests.integrations.utils import DATA_COLLECTION_USER_INFO_CASES
from tests.integrations.utils import (
DATA_COLLECTION_REMOTE_ADDR_CASES,
DATA_COLLECTION_USER_INFO_CASES,
)

try:
from sanic_testing import TestManager
Expand Down Expand Up @@ -874,3 +877,24 @@ def oversized_handler(request):

assert "data" not in event["request"]
assert "data" not in event.get("_meta", {}).get("request", {})


@pytest.mark.parametrize(
"init_kwargs, expect_remote_addr", DATA_COLLECTION_REMOTE_ADDR_CASES
)
def test_remote_addr_data_collection(
sentry_init, app, capture_events, init_kwargs, expect_remote_addr
):
sentry_init(integrations=[SanicIntegration()], **init_kwargs)
events = capture_events()

c = get_client(app)
with c as client:
_, response = client.get("/message")
assert response.status == 200

(event,) = events
if expect_remote_addr:
assert event["request"]["env"] == {"REMOTE_ADDR": ""}
else:
assert "env" not in event["request"]
25 changes: 24 additions & 1 deletion tests/integrations/tornado/test_tornado.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
from sentry_sdk import capture_message, start_transaction
from sentry_sdk._types import SENSITIVE_DATA_SUBSTITUTE
from sentry_sdk.integrations.tornado import TornadoIntegration
from tests.integrations.utils import DATA_COLLECTION_USER_INFO_CASES
from tests.integrations.utils import (
DATA_COLLECTION_REMOTE_ADDR_CASES,
DATA_COLLECTION_USER_INFO_CASES,
)


@pytest.fixture
Expand Down Expand Up @@ -1133,3 +1136,23 @@ def test_client_address_span_attribute_data_collection(
assert server_span["attributes"]["client.address"] == "127.0.0.1"
else:
assert "client.address" not in server_span["attributes"]


@pytest.mark.parametrize(
"init_kwargs, expect_remote_addr", DATA_COLLECTION_REMOTE_ADDR_CASES
)
def test_remote_addr_data_collection(
tornado_testcase, sentry_init, capture_events, init_kwargs, expect_remote_addr
):
sentry_init(integrations=[TornadoIntegration()], **init_kwargs)
events = capture_events()
client = tornado_testcase(Application([(r"/hi", CrashingHandler)]))

response = client.fetch("/hi")
assert response.code == 500

(event,) = events
if expect_remote_addr:
assert event["request"]["env"] == {"REMOTE_ADDR": "127.0.0.1"}
else:
assert "env" not in event["request"]
32 changes: 32 additions & 0 deletions tests/integrations/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,38 @@
),
]

# Shared parametrization test matrix for ``REMOTE_ADDR`` on events in
# integrations that set it unconditionally pre-data collection (tornado, sanic,
# aiohttp). Each case is ``(init_kwargs, expect_remote_addr)``: the address is
# only gated once ``data_collection`` is enabled, so the legacy
# ``send_default_pii`` cases still expect it to be collected.
DATA_COLLECTION_REMOTE_ADDR_CASES = [
pytest.param({}, True, id="defaults"),
pytest.param({"send_default_pii": True}, True, id="send_default_pii_true"),
pytest.param({"send_default_pii": False}, True, id="send_default_pii_false"),
pytest.param(
{"_experiments": {"data_collection": {}}}, True, id="data_collection_default"
),
pytest.param(
{"_experiments": {"data_collection": {"user_info": True}}},
True,
id="data_collection_user_info_true",
),
pytest.param(
{"_experiments": {"data_collection": {"user_info": False}}},
False,
id="data_collection_user_info_false",
),
pytest.param(
{
"send_default_pii": True,
"_experiments": {"data_collection": {"user_info": False}},
},
False,
id="data_collection_wins_over_send_default_pii",
),
]

# Shared parametrization test matrix exercising the interaction between the
# ``data_collection.queues`` experiment and the legacy ``send_default_pii`` boolean
# for job/task args and kwargs collected by queue integrations (rq, arq, huey).
Expand Down
Loading