Skip to content

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

Draft
43jay wants to merge 3 commits intomobile-935/new-swizzlingfrom
mobile-935/extract-network-details
Draft

feat(network-details): Implement header and body extraction#7585
43jay wants to merge 3 commits intomobile-935/new-swizzlingfrom
mobile-935/extract-network-details

Conversation

@43jay
Copy link
Collaborator

@43jay 43jay commented Mar 4, 2026

📜 Description

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

  • Relies on knowing the contentType to decide how to interpret the body (NSData ).
  • Defaults to interpreting body as text: tries NSUTF8StringEncoding , then NSISOLatin1StringEncoding then gives up with a BODY_PARSE_ERROR warning.

SentryReplayNetworkRequestOrResponse

  • case-insensitive header extraction

💡 Motivation and Context

See first PR in stack.

💚 How did you test it?

Unit tests

xcodebuild test -workspace Sentry.xcworkspace -scheme Sentry -destination 'platform=iOS Simulator,name=iPhone 16 Pro' -only-testing:SentryTests/SentryNetworkBodyTests -only-testing:SentryTests/SentryNetworkRequestDataTests -only-testing:SentryTests/SentryReplayNetworkRequestOrResponseTests | xcbeautify

Test Suite 'SentryNetworkBodyTests' started at 2026-03-04 00:26:36.919.
    ✔ testInit_withBinaryContentType_shouldCreateArtificialString (0.002 seconds)
    ✔ testInit_withEmptyData_shouldReturnNil (0.000 seconds)
    ✔ testInit_withFormURLEncoded_shouldParseAsForm (0.001 seconds)
    ✔ testInit_withInvalidJSON_shouldFallbackToString (0.000 seconds)
    ✔ testInit_withJSONArray_shouldParseCorrectly (0.001 seconds)
    ✔ testInit_withJSONDictionary_shouldParseCorrectly (0.001 seconds)
    ✔ testInit_withLargeData_shouldTruncate (0.010 seconds)
    ✔ testInit_withTextData_shouldStoreAsString (0.000 seconds)
    ✔ testSerialize_withJSONArray_shouldReturnDictionary (0.000 seconds)
    ✔ testSerialize_withJSONDictionary_shouldReturnDictionary (0.001 seconds)
    ✔ testSerialize_withNoContentType_shouldDefaultToText (0.000 seconds)
    ✔ testSerialize_withStringBody_shouldReturnDictionary (0.000 seconds)
Executed 12 tests, with 0 failures (0 unexpected) in 0.018 (0.022) seconds
Test Suite 'SentryNetworkRequestDataTests' started at 2026-03-04 00:26:36.941.
    ✔ testInit_withMethod_shouldSetMethod (0.000 seconds)
    ✔ testSerialize_withFullData_shouldReturnCompleteDictionary (0.001 seconds)
    ✔ testSerialize_withLargeBody_shouldHandleTruncation (0.002 seconds)
    ✔ testSerialize_withPartialData_shouldOnlyIncludeSetFields (0.000 seconds)
Executed 4 tests, with 0 failures (0 unexpected) in 0.004 (0.005) seconds
Test Suite 'SentryReplayNetworkRequestOrResponseTests' started at 2026-03-04 00:26:36.946.
    ✔ testExtractHeaders_caseInsensitiveMatching (0.001 seconds)
    ✔ testExtractHeaders_nonStringValues_convertedToStrings (0.000 seconds)
    ✔ testExtractHeaders_withNilInputs_returnsEmptyDict (0.000 seconds)
    ✔ testInit_withAllParameters_shouldSetAllProperties (0.000 seconds)
    ✔ testSerialize_withAllData_shouldReturnCompleteDict (0.002 seconds)
    ✔ testSerialize_withNilBody_shouldNotIncludeBody (0.001 seconds)
Executed 6 tests, with 0 failures (0 unexpected) in 0.005 (0.005) seconds
Test Suite 'SentryTests.xctest' passed at 2026-03-04 00:26:36.951.
Executed 22 tests, with 0 failures (0 unexpected) in 0.027 (0.033) seconds
Executed 22 tests, with 0 failures (0 unexpected) in 0.027 (0.034) seconds

📝 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.

Closes #7587

@linear
Copy link

linear bot commented Mar 4, 2026

@github-actions
Copy link
Contributor

github-actions bot commented Mar 4, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


This PR will not appear in the changelog.


🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 4, 2026

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 6e5c5bb

@43jay 43jay marked this pull request as ready for review March 4, 2026 04:31
@codecov
Copy link

codecov bot commented Mar 4, 2026

Codecov Report

❌ Patch coverage is 94.82759% with 3 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (mobile-935/new-swizzling@9a8d48d). Learn more about missing BASE report.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...ons/SessionReplay/SentryReplayNetworkDetails.swift 94.827% 3 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@                     Coverage Diff                      @@
##             mobile-935/new-swizzling     #7585   +/-   ##
============================================================
  Coverage                            ?   85.009%           
============================================================
  Files                               ?       486           
  Lines                               ?     28965           
  Branches                            ?     12610           
============================================================
  Hits                                ?     24623           
  Misses                              ?      4293           
  Partials                            ?        49           
Files with missing lines Coverage Δ
...ons/SessionReplay/SentryReplayNetworkDetails.swift 95.327% <94.827%> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9a8d48d...6e5c5bb. Read the comment docs.

@43jay 43jay force-pushed the mobile-935/new-swizzling branch from 9473efb to 5bc5830 Compare March 4, 2026 21:03
@43jay 43jay force-pushed the mobile-935/extract-network-details branch 2 times, most recently from 3547546 to e7c5abb Compare March 4, 2026 22:00
@43jay 43jay force-pushed the mobile-935/new-swizzling branch 2 times, most recently from 7faf4ef to 6e19c0a Compare March 6, 2026 16:33
@43jay 43jay force-pushed the mobile-935/extract-network-details branch from e7c5abb to 2e9607e Compare March 6, 2026 16:33
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.


var warnings = [NetworkBodyWarning]()
let lower = contentType?.lowercased() ?? ""
let utType = contentType.flatMap { UTType(mimeType: $0.lowercased()) }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Content-type parameters cause UTType MIME lookup failure

High Severity

UTType(mimeType:) expects a bare MIME type (e.g. "application/json") but real-world Content-Type headers typically include parameters like "application/json; charset=utf-8". Passing the full value with parameters causes UTType initialization to return nil, so the JSON and text branches are skipped entirely. The body then falls through to the else branch and produces a "[Body not captured: …]" placeholder instead of parsing the content. The form-urlencoded branch is unaffected because it uses contains. Stripping parameters (splitting on ";" and taking the first component) before calling UTType(mimeType:) would fix this.

Fix in Cursor Fix in Web

43jay added 3 commits March 6, 2026 14:39
1) Extracts bodies that are JSON, formurlencoded, or text.

Uses UTType to accurately classify content types as JSON
or text without maintaining a manual list. Falls back
to a string match for application/x-www-form-urlencoded
which has no UTType representation.

!Relies on having a valid `contentType`

2) Populates NetworkBodyWarning's for
 "MAYBE_JSON_TRUNCATED"
 "TEXT_TRUNCATED"
 "BODY_PARSE_ERROR"
 ^when encountered, these show custom dashboard UI.
Uses UTType to classify content types: only content positively identified
as text is decoded. Everything else gets a descriptive placeholder:
 Example - "[Body not captured: contentType=image/png (8 bytes)]"

Known text types (where UTType conforms to .text) are reliably classified
by UTType's type hierarchy. If a content type header is incorrect (e.g.
claims text but contains binary), the resulting decode failure is caught
by the existing bodyParseError warning.
Casts to lower-case before comparing headers.
ObjC setters now accept raw allHeaders and configuredHeaders instead
of pre-filtered headers, keeping the filtering logic in Swift.
@43jay 43jay marked this pull request as draft March 6, 2026 18:43
@43jay 43jay force-pushed the mobile-935/new-swizzling branch from 6e19c0a to 9a8d48d Compare March 6, 2026 19:25
@43jay 43jay force-pushed the mobile-935/extract-network-details branch from 2e9607e to 6e5c5bb Compare March 6, 2026 19:25
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.

1 participant