Skip to content

feat(network-details): Implement header and body extraction #7710

@github-actions

Description

@github-actions

Note

The pull request "feat(network-details): Implement header and body extraction" was created by @43jay but did not reference an issue. Therefore this issue was created for better visibility in external tools like Linear.

📜 Description

SentryNetworkBody

Extract request/response bodies that are either JSON, formurlencoded, binary or text.

  • Relies on having a contentType to decide how to interpret the body (NSData).
  • Relies on iOS's UTType to decide whether something is JSON or text.

text:
tries .utf8 , then .isoLatin1 then gives up with BODY_PARSE_ERROR warning.

json:
tries JSONSerialization.jsonObject, gives up with BODY_PARSE_ERROR warning

UTType doesn't know:
extracts a placeholder body E.g. "[Body not captured: contentType=application/octet-stream (10240 bytes)]"

SentryReplayNetworkRequestOrResponse

  • case-insensitive header extraction

💡 Motivation and Context

See first PR in stack.

💚 How did you test it?

Unit tests

make test-ios ONLY_TESTING="SentryReplayNetworkDetailsBodyTests,SentryReplayNetworkDetailsHeaderTests,SentryReplayNetworkDetailsIntegrationTests"

Test Suite 'SentryReplayNetworkDetailsBodyTests' started at 2026-03-19 15:25:09.315.
✔ testInit_withBinaryContentType_shouldCreateArtificialString (0.005 seconds)
✔ testInit_withEmptyData_shouldReturnNil (0.000 seconds)
✔ testInit_withFormURLEncoded_duplicateKeys_shouldPromoteToArray (0.001 seconds)
✔ testInit_withFormURLEncoded_emptyKeys_shouldBeSkipped (0.000 seconds)
✔ testInit_withFormURLEncoded_emptyValue_shouldParseAsEmptyString (0.000 seconds)
Resolving Package Graph
✔ testInit_withFormURLEncoded_equalsInValue_shouldPreserve (0.000 seconds)
✔ testInit_withFormURLEncoded_missingEquals_shouldFallbackToText (0.001 seconds)
✔ testInit_withFormURLEncoded_shouldParseAsForm (0.001 seconds)
✔ testInit_withInvalidJSON_shouldFallbackToString (0.001 seconds)
✔ testInit_withJSONArray_shouldParseCorrectly (0.000 seconds)
✔ testInit_withJSONDictionary_shouldParseCorrectly (0.001 seconds)
✔ testInit_withLargeData_shouldTruncate (0.005 seconds)
✔ testInit_withNilContentType_shouldCreatePlaceholder (0.000 seconds)
✔ testInit_withTextData_shouldStoreAsString (0.000 seconds)
✔ testInit_withUnrecognizedContentType_shouldCreatePlaceholder (0.000 seconds)
✔ testParseMimeAndEncoding_shouldHandleEdgeCases (0.001 seconds)
✔ testSerialize_withJSONArray_shouldReturnArray (0.001 seconds)
✔ testSerialize_withJSONDictionary_shouldReturnDictionary (0.001 seconds)
✔ testSerialize_withNoContentType_shouldCreatePlaceholder (0.001 seconds)
✔ testSerialize_withStringBody_shouldReturnDictionary (0.001 seconds)
Executed 20 tests, with 0 failures (0 unexpected) in 0.021 (0.041) seconds
Test Suite 'SentryTests.xctest' passed at 2026-03-19 15:25:09.356.
Executed 20 tests, with 0 failures (0 unexpected) in 0.021 (0.041) seconds

SentryReplayNetworkDetailsHeaderTests (4 tests):

  • testExtractHeaders_withNilInputs_returnsEmptyDict — nil headers/config returns empty
  • testExtractHeaders_unconfiguredHeadersAreExcluded — only configured headers are extracted
  • testExtractHeaders_caseInsensitiveMatching — header matching is case-insensitive
  • testExtractHeaders_nonStringValues_convertedToStrings — non-string header values are converted

SentryReplayNetworkDetailsIntegrationTests (4 tests):

  • testInit_withMethod_shouldSetMethod — HTTP method is stored
  • testSerialize_withFullData_shouldReturnCompleteDictionary — full detail serializes all fields
  • testSerialize_withPartialData_shouldOnlyIncludeSetFields — partial data omits unset fields
  • testSerialize_withHeaderFiltering_shouldOnlyIncludeConfiguredHeaders — header filtering works end-to-end

📝 Checklist

You have to check all boxes before merging:

  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled. N/A
  • I updated the docs if needed. future PR
  • I updated the wizard if needed. N/A
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog. #skip-changelog future PR
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

Metadata

Metadata

Assignees

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions