Skip to content

fix: route TLS trust probe through IDE HTTP proxy (CRW-12333) - #361

Merged
adietish merged 1 commit into
redhat-developer:mainfrom
adietish:crw-12333
Aug 12, 2026
Merged

fix: route TLS trust probe through IDE HTTP proxy (CRW-12333)#361
adietish merged 1 commit into
redhat-developer:mainfrom
adietish:crw-12333

Conversation

@adietish

@adietish adietish commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

fixes https://redhat.atlassian.net/browse/CRW-12333

TlsProbe opened a raw SSLSocket and bypassed IdeHttpProxy, so proxy-only clusters timed out even when Check connection worked. Use the IDE ProxySelector (HTTP CONNECT, Basic on 407) and surface connect failures clearly instead of treating them as trust prompts.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@adietish, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 45 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dc43c43e-c8dd-4bdc-9d06-1a63c36aaf6b

📥 Commits

Reviewing files that changed from the base of the PR and between 049b1a1 and 0d0f281.

📒 Files selected for processing (3)
  • src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt
  • src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeProxyTest.kt
  • src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeTestFixtures.kt
📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Improved TLS connection handling through direct connections and HTTP/SOCKS proxies.
    • Added proxy failover and HTTP CONNECT authentication support.
    • Applied connection and read timeouts with secure HTTPS hostname verification.
  • Bug Fixes

    • Clearer errors now distinguish connectivity problems from TLS certificate or handshake failures.
    • Improved handling of proxy connection failures and malformed responses.
  • Tests

    • Added coverage for direct TLS connections, hostname mismatches, proxy authentication, retries, and failure scenarios.

Walkthrough

The change replaces TlsProbe with proxy-aware TlsConnectionProbe. It supports direct, HTTP CONNECT, and SOCKS routes. DefaultTlsTrustManager now separates TLS failures from connectivity failures and reports connection errors with proxy guidance.

Changes

TLS probing and trust evaluation

Layer / File(s) Summary
Proxy-aware TLS connection probe
src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt, src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsProbe.kt, src/main/kotlin/com/redhat/devtools/gateway/util/IdeHttpProxy.kt
TlsConnectionProbe adds direct, SOCKS, and HTTP CONNECT probing with retries, authentication, timeouts, bounded response parsing, TLS endpoint identification, and handshake handling. TlsProbe is removed. IdeHttpProxy exposes proxySelector().
Trust evaluation error handling
src/main/kotlin/com/redhat/devtools/gateway/auth/tls/DefaultTlsTrustManager.kt
Trust probes use TlsConnectionProbe. TLS exceptions are rethrown. Other I/O failures become descriptive connection errors across all probe paths.
Probe and trust failure validation
src/test/kotlin/com/redhat/devtools/gateway/auth/tls/*
Tests cover direct TLS, hostname validation, HTTP CONNECT, proxy authentication, retry behavior, malformed responses, cleanup, and trust-manager connectivity errors.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers: azatsarynnyy, vrubezhny

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains proxy-aware TLS probing and connection error handling.
Title check ✅ Passed The title clearly identifies the main change: routing TLS trust probes through the IDE HTTP proxy.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@adietish
adietish force-pushed the crw-12333 branch 4 times, most recently from 50b5a29 to f3f7133 Compare August 10, 2026 15:48
@codecov-commenter

codecov-commenter commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 73.72881% with 31 lines in your changes missing coverage. Please review.
✅ Project coverage is 35.04%. Comparing base (71098f6) to head (0d0f281).
⚠️ Report is 415 commits behind head on main.

Files with missing lines Patch % Lines
...at/devtools/gateway/auth/tls/TlsConnectionProbe.kt 72.81% 13 Missing and 15 partials ⚠️
...evtools/gateway/auth/tls/DefaultTlsTrustManager.kt 76.92% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            main     #361       +/-   ##
==========================================
+ Coverage   0.00%   35.04%   +35.04%     
==========================================
  Files          4      113      +109     
  Lines         26     4916     +4890     
  Branches       0      945      +945     
==========================================
+ Hits           0     1723     +1723     
- Misses        26     2941     +2915     
- Partials       0      252      +252     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 5

🧹 Nitpick comments (2)
src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt (2)

174-197: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

The Authenticator request hardcodes Basic and ignores the advertised realm.

basicProxyAuthorization passes an empty prompt and the scheme Basic without reading the Proxy-Authenticate header from the 407 response. A proxy that advertises a realm, or a credential store keyed by realm, then returns no credentials. Capture the Proxy-Authenticate value in readConnectStatus and pass the parsed realm and scheme here.

Also note that PasswordAuthentication.getPassword() returns a copy, so password.fill clears the copy only.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt`
around lines 174 - 197, Update readConnectStatus to capture the 407 response’s
Proxy-Authenticate header, parse its advertised scheme and realm, and pass both
into basicProxyAuthorization instead of using an empty prompt and hardcoded
Basic. Preserve the existing credential encoding, but remove the misleading
password.fill cleanup or otherwise avoid implying it clears the authenticator’s
stored password because getPassword() returns a copy.

78-101: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider reporting failures to the proxy selector.

connect never calls proxySelector.connectFailed when a proxy route fails. IDE and JVM selectors use that callback to deprioritize a broken proxy for later requests. Adding the call in the IOException branch of connect keeps proxy failover state consistent with the other HTTP paths in IdeHttpProxy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt`
around lines 78 - 101, The connect flow should report failed proxy routes
through ProxySelector.connectFailed. Update the IOException handling in connect
to invoke the callback with the failed proxy’s address and the thrown exception,
while preserving the existing exception propagation and direct-connection
behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/main/kotlin/com/redhat/devtools/gateway/auth/tls/DefaultTlsTrustManager.kt`:
- Around line 164-178: In the SSLHandshakeException handler, update the captured
chain validation before trustAnchor is assigned so both null and empty
serverCertificateChain results rethrow the original exception. Keep the existing
CapturedCertInfo construction unchanged for non-empty chains, using the chain
value associated with CapturingTrustManager.

In `@src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt`:
- Around line 146-172: Bound both CONNECT response dimensions: update
readAsciiLine to enforce a maximum line length and fail when the limit is
exceeded, including lines that reach EOF without a newline; update
readConnectStatus to read at most a fixed maximum number of header lines while
preserving termination on an empty line or EOF. Define or reuse clear constants
for the line and header limits, and use an indexed while loop rather than break
inside repeat.
- Around line 199-203: Update TlsConnectionProbe.handshakeOver to set the
created SSLSocket's SSLParameters.endpointIdentificationAlgorithm to "HTTPS"
before startHandshake(). Preserve CapturingTrustManager certificate capture and
add regression tests covering both hostname-matching success and
hostname-mismatch failure cases.

In
`@src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeTest.kt`:
- Line 92: Suppress detekt’s EmptyFunctionBlock rule for the anonymous
ProxySelector objects containing the empty connectFailed overrides, or add an
intentionality comment inside each body. Apply the fix to all four connectFailed
implementations referenced in TlsConnectionProbeTest.
- Around line 42-58: Replace the non-thread-safe tasks mutableListOf used by the
proxy accept thread and tearDown with a concurrent collection that supports safe
concurrent appends and iteration. Update the tasks declaration and retain the
existing cancellation behavior in tearDown, ensuring worker-added futures cannot
be skipped or trigger ConcurrentModificationException.

---

Nitpick comments:
In `@src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt`:
- Around line 174-197: Update readConnectStatus to capture the 407 response’s
Proxy-Authenticate header, parse its advertised scheme and realm, and pass both
into basicProxyAuthorization instead of using an empty prompt and hardcoded
Basic. Preserve the existing credential encoding, but remove the misleading
password.fill cleanup or otherwise avoid implying it clears the authenticator’s
stored password because getPassword() returns a copy.
- Around line 78-101: The connect flow should report failed proxy routes through
ProxySelector.connectFailed. Update the IOException handling in connect to
invoke the callback with the failed proxy’s address and the thrown exception,
while preserving the existing exception propagation and direct-connection
behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 58b7d331-9f0b-45ad-8c36-7b7d9bb6ba4b

📥 Commits

Reviewing files that changed from the base of the PR and between 14bce0f and ce62cef.

⛔ Files ignored due to path filters (2)
  • src/test/resources/tls/server-cert.pem is excluded by !**/*.pem
  • src/test/resources/tls/server-key.pem is excluded by !**/*.pem
📒 Files selected for processing (7)
  • src/main/kotlin/com/redhat/devtools/gateway/auth/tls/DefaultTlsTrustManager.kt
  • src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt
  • src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsProbe.kt
  • src/main/kotlin/com/redhat/devtools/gateway/util/IdeHttpProxy.kt
  • src/test/kotlin/com/redhat/devtools/gateway/auth/tls/DefaultTlsTrustManagerTrustTest.kt
  • src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeTest.kt
  • src/test/resources/tls/README.md
💤 Files with no reviewable changes (1)
  • src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsProbe.kt

Comment thread src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeTest.kt Outdated
Comment thread src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeTest.kt Outdated
@adietish

Copy link
Copy Markdown
Collaborator Author

@azatsarynnyy, @vrubezhny: we should have this PR merged before we release the new version 0.0.19
Customer in support case 04383919 reported that it fixed his issues.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeTest.kt`:
- Around line 284-286: Update the authorization check in the request validation
around the authorized predicate to require the Basic header value to equal the
Base64-encoded token for proxy-user:proxy-pass, rather than accepting any header
with the Basic scheme. Preserve case-insensitive matching for the header name
and ensure invalid credentials cause the test to reject the request.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0344d870-50c4-4fb2-bc67-8cefef6e0f54

📥 Commits

Reviewing files that changed from the base of the PR and between ce62cef and 3b25d25.

⛔ Files ignored due to path filters (4)
  • src/test/resources/tls/mismatch-cert.pem is excluded by !**/*.pem
  • src/test/resources/tls/mismatch-key.pem is excluded by !**/*.pem
  • src/test/resources/tls/server-cert.pem is excluded by !**/*.pem
  • src/test/resources/tls/server-key.pem is excluded by !**/*.pem
📒 Files selected for processing (3)
  • src/main/kotlin/com/redhat/devtools/gateway/auth/tls/DefaultTlsTrustManager.kt
  • src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt
  • src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeTest.kt
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/kotlin/com/redhat/devtools/gateway/auth/tls/DefaultTlsTrustManager.kt
  • src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt

Comment thread src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeTest.kt Outdated

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeRetryTest.kt`:
- Line 45: Replace the released-port setup in TlsConnectionProbeRetryTest with a
deterministic local proxy fixture that remains bound while
TlsConnectionProbe.connect executes and accepts then immediately closes the
connection. Update the test lifecycle to start and clean up this fixture,
preserving the intended proxy-failure and retry assertions without relying on
deadProxyPort.

In
`@src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeTestFixtures.kt`:
- Around line 35-37: Make the tasks collection in TlsConnectionProbeTestFixtures
safe for concurrent registration and iteration by using CopyOnWriteArrayList or
equivalent synchronization. Ensure proxy accept task additions and close()
teardown cannot race, while preserving existing task cancellation and executor
shutdown behavior.
- Around line 151-153: Update the authorized check in the proxy fixture’s
request validation to compare the complete Proxy-Authorization Basic value for
proxy-user:proxy-pass, rather than accepting any header with the Basic prefix.
Preserve case-insensitive header-name matching while requiring the credential
value to match exactly.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 739a8d4d-f630-41cd-abc3-315c6bc671a0

📥 Commits

Reviewing files that changed from the base of the PR and between 3b25d25 and 15155db.

📒 Files selected for processing (5)
  • src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt
  • src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeDirectTest.kt
  • src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeProxyTest.kt
  • src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeRetryTest.kt
  • src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeTestFixtures.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt

@adietish
adietish force-pushed the crw-12333 branch 3 times, most recently from 43102e2 to 33a148b Compare August 11, 2026 23:21

@vrubezhny vrubezhny left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good to me. Thanks!

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt`:
- Around line 152-160: Update writeConnectRequest to build a bracketed authority
when host contains “:” (IPv6), while leaving non-IPv6 hosts unchanged; reuse
that authority in both the CONNECT request line and Host header. Add a
regression test using a proxy that verifies the received CONNECT authority for
an IPv6 target.

In
`@src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeRetryTest.kt`:
- Around line 42-63: Strengthen both retry tests around
TlsConnectionProbe.connect by recording proxy activity in the fixture and
asserting that the configured proxy routes were actually used. Update the
failing-proxy and successful-proxy test setups to capture a proxy connection or
CONNECT request, then verify those records after the connection attempt,
including the intended retry/no-direct-fallback behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 77cdab68-f9cd-40da-b4a1-8895c5a3cd28

📥 Commits

Reviewing files that changed from the base of the PR and between 15155db and 049b1a1.

📒 Files selected for processing (5)
  • src/main/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbe.kt
  • src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeDirectTest.kt
  • src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeProxyTest.kt
  • src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeRetryTest.kt
  • src/test/kotlin/com/redhat/devtools/gateway/auth/tls/TlsConnectionProbeTestFixtures.kt

TlsConnectionProbe opened a raw SSLSocket and bypassed IdeHttpProxy, so
proxy-only clusters timed out even when Check connection worked.
Use the IDE ProxySelector (HTTP CONNECT, Basic on 407) and surface
connect failures clearly instead of treating them as trust prompts.

Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@adietish
adietish merged commit c2d489a into redhat-developer:main Aug 12, 2026
7 checks passed
@adietish
adietish deleted the crw-12333 branch August 12, 2026 03:34
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.

4 participants