Skip to content

test(tunnel): cover SSH over HTTPS CONNECT#953

Open
G4614 wants to merge 3 commits into
boxlite-ai:mainfrom
G4614:codex/public-port-preview
Open

test(tunnel): cover SSH over HTTPS CONNECT#953
G4614 wants to merge 3 commits into
boxlite-ai:mainfrom
G4614:codex/public-port-preview

Conversation

@G4614

@G4614 G4614 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Adds real SSH-over-CONNECT dev coverage and documents the complete service-in-box test matrix and runbook.

Test plan:

  • Dev normal service-in-box group: 3 passed in 20.53s
  • Dev SSH-over-CONNECT: 1 passed in 13.43s
  • Dev known lifecycle gaps: 4 xfailed in 28.84s
  • Pre-existing dev Box endpoint and 4 MiB binary integrity: 2 passed in 2.47s
  • yarn --cwd apps prettier --check ../docs/testing/service-in-box-e2e.md

Summary by CodeRabbit

  • New Features
    • Added end-to-end validation for SSH connections routed through HTTPS-based tunnels.
    • Added coverage for Python SDK SSH-over-HTTPS CONNECT tunneling using an OpenSSH proxy command.
  • Documentation
    • Added a new service-in-Box end-to-end testing guide, including prerequisites, example commands, expected “healthy” evidence, troubleshooting, and current coverage gaps.
  • Tests
    • Added an HTTPS CONNECT proxy helper used by tunnel SSH tests.
    • Updated tunnel “stopped-box reachability” expectations to be non-strict XFAIL (XPASS allowed).

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds an SSH-over-HTTPS-CONNECT end-to-end test, an executable CONNECT proxy fixture, lifecycle XFAIL updates, and documentation covering service-in-Box tunnel paths, setup, execution, evidence, troubleshooting, and coverage gaps.

Changes

Tunnel E2E coverage

Layer / File(s) Summary
HTTPS CONNECT proxy fixture
scripts/test/e2e/fixtures/https_connect_proxy.py
Implements TLS connection, HTTP CONNECT negotiation, response validation, and bidirectional stream forwarding.
SSH-over-CONNECT E2E flow
scripts/test/e2e/cases/test_sdk_tunnel.py, scripts/test/e2e/cases/test_node_tunnel.py
Starts sshd in a SimpleBox, creates an HTTPS tunnel, routes SSH through the proxy fixture, verifies command output, and allows stopped-Box XPASS results.
E2E testing documentation
docs/testing/service-in-box-e2e.md
Documents tunnel paths, test inventory, prerequisites, commands, expected evidence, troubleshooting, and current gaps.

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

Possibly related PRs

Suggested reviewers: dorianzheng

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description lacks the required Summary, Changes, How to verify, and Risks / rollout sections from the template. Rewrite it using the template headings and briefly fill each section with the change purpose, key edits, verification command, and any rollout risks.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title accurately highlights the main change: adding SSH-over-HTTPS CONNECT tunnel coverage.
✨ 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.

@G4614
G4614 force-pushed the codex/public-port-preview branch 10 times, most recently from a0ce037 to 0ac7267 Compare July 10, 2026 10:23
@G4614 G4614 changed the title feat(preview): expose public service previews feat(sdk): expose port preview URLs Jul 10, 2026
@G4614
G4614 force-pushed the codex/public-port-preview branch 5 times, most recently from 8033bd6 to 8083362 Compare July 13, 2026 05:11
@G4614 G4614 changed the title feat(sdk): expose port preview URLs feat(preview): expose box HTTP services Jul 13, 2026
@G4614
G4614 force-pushed the codex/public-port-preview branch 3 times, most recently from 6babb23 to b34e7de Compare July 15, 2026 04:33
@G4614 G4614 changed the title feat(preview): expose box HTTP services test(tunnel): cover SSH over HTTPS CONNECT Jul 23, 2026
@G4614
G4614 force-pushed the codex/public-port-preview branch from a6cdaef to 298f374 Compare July 23, 2026 07:45
@G4614
G4614 marked this pull request as ready for review July 23, 2026 08:20
@G4614
G4614 requested a review from a team as a code owner July 23, 2026 08:20
@G4614
G4614 enabled auto-merge July 23, 2026 08:21
@boxlite-agent

boxlite-agent Bot commented Jul 23, 2026

Copy link
Copy Markdown

📦 BoxLite review — couldn't complete

claude exited 1

stdout:
{"is_error":true,"duration_api_ms":0,"num_turns":1,"stop_reason":"stop_sequence","session_id":"ee9919ad-20fe-43c9-9d32-183afabe6972","total_cost_usd":0,"usage":{"input_tokens":0,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":0,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{},"permission_denials":[],"terminal_reason":"api_error","fast_mode_state":"off","subtype":"success","api_error_status":403,"result":"Your organization has disabled Claude subscription access for Claude Code · Use an Anthropic API key instead, or ask your admin to enable access","type":"result","duration_ms":427,"uuid":"fcfd286d-cf4d-4d61-8cb0-ae6b31784477"}

stderr:
<empty>

powered by BoxLite

@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 `@scripts/test/e2e/cases/test_sdk_tunnel.py`:
- Around line 342-357: The SSH test command in the subprocess created by the
tunnel test targets the default port instead of the guest sshd on port 2222.
Update the command arguments around the endpoint hostname to include the SSH
port option set to 2222, preserving the existing ProxyCommand and connection
checks.

In `@scripts/test/e2e/fixtures/https_connect_proxy.py`:
- Around line 30-34: Update the CONNECT request construction in the proxy
connection flow to send the target authority in the Host header, reusing the
existing authority variable instead of proxy_host. Keep the CONNECT request line
and other headers unchanged.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 231a9f65-db30-4f89-b631-804f9657501a

📥 Commits

Reviewing files that changed from the base of the PR and between 015503d and 1e312c2.

📒 Files selected for processing (3)
  • docs/testing/service-in-box-e2e.md
  • scripts/test/e2e/cases/test_sdk_tunnel.py
  • scripts/test/e2e/fixtures/https_connect_proxy.py

Comment on lines +342 to +357
process = await asyncio.create_subprocess_exec(
"ssh",
"-i",
str(key_path),
"-o",
f"ProxyCommand={proxy_command}",
"-o",
"BatchMode=yes",
"-o",
"StrictHostKeyChecking=no",
"-o",
"UserKnownHostsFile=/dev/null",
"-o",
"ConnectTimeout=15",
f"root@{endpoint.hostname}",
"printf BOXLITE_SSH_CONNECT_OK",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate files =="
git ls-files | rg '(^|/)test_sdk_tunnel\.py$|(^|/)service-in-box-e2e\.md$|sshd|tunnel|ProxyCommand' || true

echo "== test file relevant lines =="
if [ -f scripts/test/e2e/cases/test_sdk_tunnel.py ]; then
  wc -l scripts/test/e2e/cases/test_sdk_tunnel.py
  sed -n '300,390p' scripts/test/e2e/cases/test_sdk_tunnel.py | cat -n -v
fi

echo "== docs relevant lines =="
if [ -f docs/testing/service-in-box-e2e.md ]; then
  wc -l docs/testing/service-in-box-e2e.md
  sed -n '1,120p' docs/testing/service-in-box-e2e.md | cat -n -v
fi

echo "== search proxy_command and 2222 usages =="
rg -n 'ProxyCommand|PROXY_COMMAND|2222|sshd:2222|BOXLITE_SSH_CONNECT_OK|CREATE_SUBPROCESS_EXEC|create_subprocess_exec' .

Repository: boxlite-ai/boxlite

Length of output: 18089


🌐 Web query:

OpenSSH ssh Config ProxyCommand %p remote port default port behavior

💡 Result:

In OpenSSH configuration, the %p token used within a ProxyCommand string is a placeholder that OpenSSH automatically substitutes with the remote port number [1][2][3]. When you specify %p in a ProxyCommand, OpenSSH dynamically inserts the port it intends to connect to [4]. This behavior ensures that the command (such as nc or another proxy tool) uses the correct destination port, regardless of whether that port was explicitly provided by the user in the command line (e.g., via -p), defined in a Port configuration directive, or if it is relying on the system default [4]. Key aspects of this behavior include: - Automatic Resolution: OpenSSH determines the target port based on your connection request. If no specific port is provided, it uses the default SSH port (22) [1][4]. This resolved value is then passed to the ProxyCommand as the replacement for %p [2][5]. - Token Substitution: The %p token is part of a set of tokens (including %h for the host and %r for the remote user) designed to make ProxyCommand flexible [2][6]. When the ssh client executes the ProxyCommand, it performs the expansion of these tokens before the command is run [2][3]. - Consistency: This mechanism allows you to define generic proxy configurations, such as ProxyCommand /usr/bin/nc %h %p, which will correctly adapt to different hosts and ports without needing manual updates for each destination [2][5]. Essentially, %p serves as a bridge that passes the destination port context directly from the OpenSSH client to the utility handling the proxy connection [2][4].

Citations:


🌐 Web query:

OpenSSH ssh command line -p option ProxyCommand %p default port remote host

💡 Result:

In the OpenSSH ProxyCommand directive, the token %p is a placeholder that is automatically substituted with the destination port of the target host [1][2]. When you use %p in a command string, the SSH client replaces it with either the port explicitly specified in your SSH configuration (or via the command line) for that host, or the default SSH port (22) if no specific port is defined [3][2]. Key points regarding %p and ProxyCommand: - Token Substitution: %p (port), along with %h (host) and %r (remote user), are standard tokens supported by the ProxyCommand directive to dynamically pass connection details to the proxy command being executed [4][1]. - Functionality: ProxyCommand instructs the SSH client to use an arbitrary command (such as ssh -W or nc) to establish the connection [1][5]. By using %h and %p, you ensure that the proxy command correctly directs the traffic to the intended target host and port [6][7]. - Example: If you have Host target and Port 830 configured, using ProxyCommand ssh -W %h:%p jumphost will effectively execute as ssh -W target:830 jumphost [3][6]. - Note on Defaulting: If no port is specified for the target host in your configuration, %p defaults to 22 [3]. This behavior is automatic and intrinsic to how the SSH client processes the ProxyCommand string before execution [1].

Citations:


Connect SSH to the tunneled guest port.

The test creates sshd on 2222, and the tunnel is requested for guest port 2222, but the ssh command does not pass -p 2222. OpenSSH then uses the default SSH port internally pass-through for this connection, so the %p placeholder in ProxyCommand points at 22 instead of the running sshd. Add -p 2222 so the SSH client can complete to the intended guest port.

🤖 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 `@scripts/test/e2e/cases/test_sdk_tunnel.py` around lines 342 - 357, The SSH
test command in the subprocess created by the tunnel test targets the default
port instead of the guest sshd on port 2222. Update the command arguments around
the endpoint hostname to include the SSH port option set to 2222, preserving the
existing ProxyCommand and connection checks.

Comment on lines +30 to +34
authority = f"{target_host}:{target_port}"
conn.sendall(
f"CONNECT {authority} HTTP/1.1\r\n"
f"Host: {proxy_host}\r\n"
"Proxy-Connection: Keep-Alive\r\n\r\n".encode()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Send the CONNECT authority in Host.

Line 33 sends the proxy host, while the CONNECT request targets authority. Proxies that validate Host against the CONNECT authority can reject this handshake. Use Host: {authority}.

Proposed fix
         f"CONNECT {authority} HTTP/1.1\r\n"
-        f"Host: {proxy_host}\r\n"
+        f"Host: {authority}\r\n"
         "Proxy-Connection: Keep-Alive\r\n\r\n".encode()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
authority = f"{target_host}:{target_port}"
conn.sendall(
f"CONNECT {authority} HTTP/1.1\r\n"
f"Host: {proxy_host}\r\n"
"Proxy-Connection: Keep-Alive\r\n\r\n".encode()
authority = f"{target_host}:{target_port}"
conn.sendall(
f"CONNECT {authority} HTTP/1.1\r\n"
f"Host: {authority}\r\n"
"Proxy-Connection: Keep-Alive\r\n\r\n".encode()
🤖 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 `@scripts/test/e2e/fixtures/https_connect_proxy.py` around lines 30 - 34,
Update the CONNECT request construction in the proxy connection flow to send the
target authority in the Host header, reusing the existing authority variable
instead of proxy_host. Keep the CONNECT request line and other headers
unchanged.

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