Skip to content

Capture traffic from sessions that own their configuration - #4

Merged
Rev0212 merged 1 commit into
mainfrom
feature/intercept-custom-sessions
Aug 26, 2026
Merged

Capture traffic from sessions that own their configuration#4
Rev0212 merged 1 commit into
mainfrom
feature/intercept-custom-sessions

Conversation

@Rev0212

@Rev0212 Rev0212 commented Aug 26, 2026

Copy link
Copy Markdown
Owner

URLProtocol.registerClass only reaches URLSession.shared. Any URLSession built with its own configuration resolves its handler chain from that configuration's protocolClasses, snapshotted at init, and never consults the global registry — so Ktor's Darwin engine (PTEShared), and any SDK that builds its own session, was invisible to the inspector.

Swizzle the protocolClasses getter so InspectorURLProtocol lands in the snapshot as each configuration is read during session construction.

Because those sessions hold a direct class reference, unregister() no longer stops them, so gate shouldIntercept on an isCapturing flag to keep disable() effective.

URLProtocol.registerClass only reaches URLSession.shared. Any URLSession
built with its own configuration resolves its handler chain from that
configuration's protocolClasses, snapshotted at init, and never consults
the global registry — so Ktor's Darwin engine (PTEShared), and any SDK
that builds its own session, was invisible to the inspector.

Swizzle the protocolClasses getter so InspectorURLProtocol lands in the
snapshot as each configuration is read during session construction.

Because those sessions hold a direct class reference, unregister() no
longer stops them, so gate shouldIntercept on an isCapturing flag to keep
disable() effective.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 26, 2026 07:04
@Rev0212
Rev0212 merged commit a008d6f into main Aug 26, 2026
1 check passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The swizzle installation is not thread-safe (can be undone by concurrent calls), and the newly added shared capture state further increases the risk of data races from URL loading threads.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR extends NetworkInspector’s traffic capture beyond URLSession.shared by ensuring InspectorURLProtocol is included in URLSessionConfiguration.protocolClasses snapshots taken during URLSession construction, and preserves the ability to “disable” capture by gating interception at runtime.

Changes:

  • Adds a URLSessionConfiguration swizzle to inject InspectorURLProtocol into protocolClasses.
  • Introduces an isCapturing gate so sessions that already hold a protocol class reference stop intercepting after disable()/unregister().
File summaries
File Description
Sources/NetworkInspector/URLSessionConfigurationSwizzle.swift Adds protocolClasses getter swizzle to ensure the inspector protocol is present in per-session snapshots.
Sources/NetworkInspector/NetworkInterceptor.swift Adds isCapturing flag and gates shouldIntercept to keep disable/unregister effective with swizzled sessions.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +24 to +40
static func installInspectorSwizzle() {
guard !isSwizzled else { return }

guard
let original = class_getInstanceMethod(
URLSessionConfiguration.self,
#selector(getter: URLSessionConfiguration.protocolClasses)
),
let replacement = class_getInstanceMethod(
URLSessionConfiguration.self,
#selector(getter: URLSessionConfiguration.inspector_protocolClasses)
)
else { return }

method_exchangeImplementations(original, replacement)
isSwizzled = true
}
Comment on lines 13 to 15
private static var allowedBaseURLs: [String] = []
private static var isCapturing = false

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.

2 participants