diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b74a003..c6edc52 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -226,7 +226,14 @@ jobs: sleep 1 # Verify target is up - curl -sf "http://127.0.0.1:$TARGET_PORT/" > /dev/null || true + set +e + curl -sf "http://127.0.0.1:$TARGET_PORT/" > /dev/null + TARGET_CHECK=$? + set -e + if [ "$TARGET_CHECK" -ne 0 ]; then + echo "ERROR: HTTP target on port $TARGET_PORT is not responding" + exit 1 + fi # 3. Start listener (background) $RUN listen \ @@ -249,8 +256,38 @@ jobs: CONNECTOR_PID=$! sleep 3 - # 5. Test SOCKS5 forwarding - RESULT=$(curl -sf --proxy "socks5h://127.0.0.1:$SOCKS_PORT" "http://127.0.0.1:$TARGET_PORT/" 2>&1 | head -5 || true) - echo "E2E response: $RESULT" + # 5. Test SOCKS5 forwarding through the tunnel + # Do NOT mask failures with || true - CI must fail if tunnel does not forward traffic + set +e + RESPONSE=$(curl -s -w "\n%{http_code}" --proxy "socks5h://127.0.0.1:$SOCKS_PORT" "http://127.0.0.1:$TARGET_PORT/") + CURL_EXIT=$? + set -e + + if [ "$CURL_EXIT" -ne 0 ]; then + echo "ERROR: curl through SOCKS5 proxy failed with exit code $CURL_EXIT" + echo "Response: $RESPONSE" + exit 1 + fi + + # Extract HTTP status code (last line) and response body + # Note: head -n -1 is not portable (fails on macOS BSD), use sed instead + HTTP_STATUS=$(echo "$RESPONSE" | tail -n 1) + RESPONSE_BODY=$(echo "$RESPONSE" | sed '$ d') + + echo "E2E HTTP status: $HTTP_STATUS" + echo "E2E response preview: ${RESPONSE_BODY:0:200}" + + # Assert HTTP 200 + if [ "$HTTP_STATUS" != "200" ]; then + echo "ERROR: Expected HTTP 200, got $HTTP_STATUS" + exit 1 + fi + + # Assert response contains expected content from Python http.server + if ! echo "$RESPONSE_BODY" | grep -qi "directory listing\|