Skip to content

fix: bypass HTTP logging for websocket tunnels - #667

Open
eugene-harold-krabs wants to merge 3 commits into
hcavarsan:mainfrom
eugene-harold-krabs:fix/666-websocket-forwarding
Open

fix: bypass HTTP logging for websocket tunnels#667
eugene-harold-krabs wants to merge 3 commits into
hcavarsan:mainfrom
eugene-harold-krabs:fix/666-websocket-forwarding

Conversation

@eugene-harold-krabs

Copy link
Copy Markdown

Summary

  • detect WebSocket upgrade requests while HTTP logging is enabled
  • switch the connection into raw tunnel mode after a WebSocket upgrade so frames are forwarded without being parsed/logged as HTTP requests or responses
  • add coverage for WebSocket upgrade request detection

Fixes #666

Testing

  • Not run locally: this agent environment does not have cargo/rustfmt installed.
  • Pushed to a fork so GitHub Actions can build and produce Windows artifacts.

@hcavarsan

hcavarsan commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds shared WebSocket tunnel mode to TcpForwarder's bidirectional forwarding path. The forwarder now tracks upgrade state with an AtomicBool, switches both directions to direct byte forwarding once a WebSocket upgrade is detected, and updates early-cancel tests to pass the shared state.

Changes

WebSocket Tunnel Mode

Layer / File(s) Summary
Shared tunnel state setup
crates/kftray-portforward/src/kube/tcp_forwarder.rs
Adds AtomicBool/Ordering imports and creates a shared websocket_tunnel_mode flag in forward_connection, passed to both forwarding directions.
Client-to-upstream tunnel handling
crates/kftray-portforward/src/kube/tcp_forwarder.rs
forward_client_to_upstream accepts the shared flag and forwards bytes directly once tunnel mode is set; the early-cancel test now passes the shared state.
Upstream-to-client tunnel handling
crates/kftray-portforward/src/kube/tcp_forwarder.rs
forward_upstream_to_client accepts the shared flag; bypasses response buffering/logging once tunnel mode is enabled, detects WebSocket upgrade responses to enable tunnel mode, and updates the early-cancel test.
Response logging upgrade detection
crates/kftray-portforward/src/kube/tcp_forwarder.rs
handle_response_logging_static now returns a boolean and checks the accumulated response buffer for WebSocket upgrade responses before continuing normal response logging decisions.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The change addresses #666 by detecting WebSocket upgrades and forwarding traffic as a raw tunnel.
Out of Scope Changes check ✅ Passed The diff stays focused on WebSocket upgrade handling and the related tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly matches the main change: bypassing HTTP logging for WebSocket tunnel traffic.
Description check ✅ Passed The description is directly related to the WebSocket tunnel-mode and logging changes in the PR.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@google-cla

google-cla Bot commented Jul 7, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
crates/kftray-portforward/src/kube/tcp_forwarder.rs (1)

623-625: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Connection header token matching is too strict.

Some clients send Connection: keep-alive, Upgrade, which lowercases to connection: keep-alive, upgrade and fails the exact "connection: upgrade" substring check. The handshake still works via the response-side detection, but the request-side fast path won’t trigger. Consider matching an upgrade token within the Connection header value rather than the full connection: upgrade literal.

🤖 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 `@crates/kftray-portforward/src/kube/tcp_forwarder.rs` around lines 623 - 625,
The request-side WebSocket handshake check in tcp_forwarder should not require
the exact "connection: upgrade" literal, since headers like "Connection:
keep-alive, Upgrade" will miss the fast path. Update the header matching logic
near the websocket upgrade condition to look for an Upgrade token within the
Connection header value instead of a full-string match, while keeping the
existing checks in the same handshake branch.
🤖 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 `@crates/kftray-portforward/src/kube/tcp_forwarder.rs`:
- Line 265: The two early-cancel test call sites in tcp_forwarder.rs still use
the पुराने forward_client_to_upstream and forward_upstream_to_client signatures;
update both calls to pass the websocket_tunnel_mode Arc<AtomicBool> argument so
they match the new function signature. Use the existing websocket_tunnel_mode
variable in the same test block and ensure both helper invocations receive it
consistently.
- Around line 293-300: The websocket tunnel flag is being enabled too early in
the request path inside the `TcpForwarder` flow, which can bypass the
response-side handshake confirmation. Move the
`websocket_tunnel_mode.store(true, ...)` transition out of the
`is_websocket_upgrade_request` branch and instead set it when
`HttpResponseAnalyzer::is_websocket_upgrade` confirms the upstream returned a
`101` response. Keep the upgrade request buffered and forwarded normally until
that response check succeeds so HTTP logging and non-upgrade failures still
follow the standard path.

---

Nitpick comments:
In `@crates/kftray-portforward/src/kube/tcp_forwarder.rs`:
- Around line 623-625: The request-side WebSocket handshake check in
tcp_forwarder should not require the exact "connection: upgrade" literal, since
headers like "Connection: keep-alive, Upgrade" will miss the fast path. Update
the header matching logic near the websocket upgrade condition to look for an
Upgrade token within the Connection header value instead of a full-string match,
while keeping the existing checks in the same handshake branch.
🪄 Autofix (Beta)

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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 399f4a0c-5014-47ba-9a7a-307e3514dcda

📥 Commits

Reviewing files that changed from the base of the PR and between 5a27f10 and a994d02.

📒 Files selected for processing (1)
  • crates/kftray-portforward/src/kube/tcp_forwarder.rs

Comment thread crates/kftray-portforward/src/kube/tcp_forwarder.rs
Comment thread crates/kftray-portforward/src/kube/tcp_forwarder.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/kftray-portforward/src/kube/tcp_forwarder.rs (1)

434-443: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Accumulate bytes before checking for a websocket upgrade is_websocket_upgrade(&buffer[..n]) only sees the current read, so a 101 Switching Protocols split across TCP packets won’t flip websocket_tunnel_mode. That leaves the response buffer growing on a long-lived websocket connection. Use the accumulated response bytes here, or defer the switch until the full header block is available.

🤖 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 `@crates/kftray-portforward/src/kube/tcp_forwarder.rs` around lines 434 - 443,
The websocket upgrade check in tcp_forwarder::handle_response logic only
inspects the current read buffer, so split HTTP 101 headers can be missed;
update the response handling around is_websocket_upgrade_response and
websocket_tunnel_mode to evaluate accumulated response bytes (or wait until the
full header block is available) before switching modes, while keeping
response_state and should_log in sync.
🤖 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.

Outside diff comments:
In `@crates/kftray-portforward/src/kube/tcp_forwarder.rs`:
- Around line 434-443: The websocket upgrade check in
tcp_forwarder::handle_response logic only inspects the current read buffer, so
split HTTP 101 headers can be missed; update the response handling around
is_websocket_upgrade_response and websocket_tunnel_mode to evaluate accumulated
response bytes (or wait until the full header block is available) before
switching modes, while keeping response_state and should_log in sync.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c062765d-46b9-4236-bfeb-2ab2a6516d74

📥 Commits

Reviewing files that changed from the base of the PR and between a994d02 and f2c78d0.

📒 Files selected for processing (1)
  • crates/kftray-portforward/src/kube/tcp_forwarder.rs

@xrow

xrow commented Jul 9, 2026

Copy link
Copy Markdown

@hcavarsan I am not that familiar with GitLab. I an the owner of @eugene-harold-krabs. How can I get the remaining pending checks rolling? I would like to complete the task.

@xrow

xrow commented Aug 7, 2026

Copy link
Copy Markdown

@hcavarsan Poke... Plz review... Thank you.

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.

Support web sockets

3 participants