Skip to content

fix(okhttp): Capture network details only while Session Replay is recording - #6486

Merged
markushi merged 32 commits into
mainfrom
fix/okhttp-gate-network-details-on-replay
Nov 6, 2026
Merged

markushi merged 32 commits into
mainfrom
fix/okhttp-gate-network-details-on-replay

Conversation

@markushi

@markushi markushi commented Nov 6, 2026

Copy link
Copy Markdown
Member

Follow-up to #6231. This PR targets that branch and must merge after it.

📜 Description

SentryOkHttpInterceptor now captures Session Replay network details (request and response bodies and headers) only while a replay is recording or buffering, so only when options.replayController.isRecording is true. When no replay is active, the interceptor does not buffer the request body and does not wrap the response body. Spans, breadcrumbs, and failed-request events do not change.

The gate covers headers as well as bodies. Like the bodies, the headers are stored in the SENTRY_REPLAY_NETWORK_DETAILS hint, and only DefaultReplayBreadcrumbConverter reads them.

💡 Motivation and Context

Before this change, the SDK captured bodies for allowlisted URLs even when Session Replay was off. This work had no use, because only replay reads those bodies. #6231 fixes the SSE / unknown-length blocking. This PR removes the remaining overhead when replay is not active.

💚 How did you test it?

  • New unit test: no network details are attached when the replay controller is not recording. I made sure that this test fails without the gate.
  • The existing network-detail tests now use a replay controller that is recording.
  • ./gradlew :sentry-okhttp:test

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.

🔮 Next steps

🤖 Generated with Claude Code

carlonzo and others added 30 commits October 6, 2026 13:32
Capturing a response body for session replay peeked it up front with
`Response.peekBody(MAX_NETWORK_BODY_SIZE + 1)`. OkHttp implements a peek as
`request(byteCount)`, which keeps reading until that many bytes are buffered or
the stream ends. A response with no Content-Length never satisfies either
condition, so for server-sent events, long-poll and any chunked endpoint that
stays open the interceptor never returned and the caller never received the
response at all.

Bodies with a known length still end on their own, so they keep the existing
up-front capture. Bodies of unknown length are now wrapped in a body that
copies what the application consumes into a capped buffer and reports it once
no more bytes can arrive: when the stream ends, when the application closes
the body, or when the cap is reached.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Split the capture wrapping into its own function to keep a single return, and
suppress TooManyFunctions on the interceptor as done elsewhere in this module.
A response body has a single consumer, and neither Http1ExchangeCodec.cancel()
nor Http2ExchangeCodec.cancel() closes the body, so nothing reaches this class
from another thread. The AtomicBoolean already guarantees the capture is
reported exactly once.
A streamed body is only known once it has been consumed, which can be after the
NetworkRequestData carrying it was handed to the scope, so the replay thread can
read it while it is still being written. Keeping the three response values
behind one volatile reference means a reader sees either nothing or the
complete set.
…shepherd]

Co-Authored-By: Markus Hintersteiner <markus.hintersteiner@sentry.io>
…shepherd]

# Conflicts:
#	CHANGELOG.md

Co-Authored-By: Markus Hintersteiner <markus.hintersteiner@sentry.io>
…getsentry/sentry-java into fix/okhttp-unknown-length-response-body
@linear-code

linear-code Bot commented Nov 6, 2026

Copy link
Copy Markdown

JAVA-735

@sentry

sentry Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.63.0 (1) release

⚙️ sentry-android Build Distribution Settings

@markushi
markushi marked this pull request as ready for review November 6, 2026 08:34
Base automatically changed from fix/okhttp-unknown-length-response-body to main November 6, 2026 11:45
@markushi
markushi requested a review from a team as a code owner November 6, 2026 11:45
# Conflicts:
#	sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpInterceptorUnknownContentLengthTest.kt
@markushi
markushi enabled auto-merge (squash) November 6, 2026 12:07
@markushi
markushi merged commit b79aabf into main Nov 6, 2026
43 of 44 checks passed
@markushi
markushi deleted the fix/okhttp-gate-network-details-on-replay branch November 6, 2026 12:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gate OkHttp body capture on active Session Replay

3 participants