Skip to content

fix(backport): preserve HTTPRoute upstream scheme from backend ref#395

Merged
AlinsRan merged 3 commits into
masterfrom
backport-pr-2691-httproute-scheme
May 6, 2026
Merged

fix(backport): preserve HTTPRoute upstream scheme from backend ref#395
AlinsRan merged 3 commits into
masterfrom
backport-pr-2691-httproute-scheme

Conversation

@AlinsRan
Copy link
Copy Markdown
Contributor

@AlinsRan AlinsRan commented Apr 29, 2026

Problem

When translating an HTTPRoute, the translator called AttachBackendTrafficPolicyToUpstream to apply any BackendTrafficPolicy (including an explicit scheme such as https or wss) to the upstream object. Immediately after, it unconditionally overwrote upstream.Scheme with the value derived from the service port's appProtocol:

// before
upstream.Scheme = appProtocolToUpstreamScheme(protocol)

This meant that even when a BackendTrafficPolicy explicitly set scheme: https, the appProtocol-based derivation silently overwrote it — causing backends configured for TLS or WebSocket-Secure to be contacted over the wrong scheme.

Fix

Add a guard so the appProtocol-derived scheme is only applied when the upstream scheme has not already been set:

if upstream.Scheme == "" {
    upstream.Scheme = appProtocolToUpstreamScheme(protocol)
}

This preserves any scheme set by BackendTrafficPolicy while still falling back to the appProtocol-derived value when none is specified.

Tests

Added TestTranslateHTTPRouteUpstreamScheme covering:

  • BackendTrafficPolicy scheme is preserved over appProtocol-derived scheme
  • appProtocol (e.g. kubernetes.io/wss) correctly derives https when no policy scheme is set

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 29, 2026 07:07
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 29, 2026

📝 Walkthrough

Walkthrough

TranslateHTTPRoute now preserves any pre-set upstream.Scheme and only assigns a scheme derived from the service app protocol when upstream.Scheme is empty.

Changes

Scheme assignment and tests

Layer / File(s) Summary
Core Implementation
internal/adc/translator/httproute.go
Guard added: if upstream.Scheme == "" before assigning upstream.Scheme = appProtocolToUpstreamScheme(protocol), so existing Scheme values are not overwritten.
Tests
internal/adc/translator/httproute_test.go
New test TestTranslateHTTPRouteUpstreamScheme added with two cases: (1) preserve policy-provided backend scheme; (2) when policy scheme unset, fallback to HTTPS derived from app protocol (WSS). Test constructs service, endpoints, optional BackendTrafficPolicy, invokes TranslateHTTPRoute, and asserts Upstream.Scheme and Upstream.Nodes[0].Host.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
E2e Test Quality Review ⚠️ Warning Test is unit-only, not E2E. Per blocking criteria, "Unit tests alone are NOT sufficient." Scenario coverage incomplete: missing HTTP fallback, default fallback, empty app protocols, WS protocol tests. Add E2E test verifying scheme preservation end-to-end via gateway. For unit test, add: AppProtocolHTTP→SchemeHTTP, empty appProtocol, final cmp.Or fallback verification, and AppProtocolWS scenario.
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Security Check ✅ Passed No security vulnerabilities found. The conditional scheme assignment preserves BackendTrafficPolicy values without exposing sensitive data, authorization issues, or TLS configuration errors.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: preserving the HTTPRoute upstream scheme from backend reference instead of unconditionally overriding it.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch backport-pr-2691-httproute-scheme

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

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR backports a fix to the HTTPRoute translator so it no longer overwrites an upstream scheme that has already been set earlier in backend processing (e.g., via BackendTrafficPolicy), preserving the expected https/wss behavior when applicable.

Changes:

  • Only set upstream.Scheme from the resolved backend appProtocol when upstream.Scheme is currently empty.
  • Align HTTPRoute scheme precedence behavior with other translators (e.g., ApisixRoute/Ingress) that avoid clobbering an already-populated scheme.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

conformance test report - apisix-standalone mode

apiVersion: gateway.networking.k8s.io/v1
date: "2026-05-06T02:29:58Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
  contact: null
  organization: APISIX
  project: apisix-ingress-controller
  url: https://github.com/apache/apisix-ingress-controller.git
  version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
    result: success
    statistics:
      Failed: 0
      Passed: 12
      Skipped: 0
  name: GATEWAY-GRPC
  summary: Core tests succeeded.
- core:
    result: partial
    skippedTests:
    - HTTPRouteHTTPSListener
    statistics:
      Failed: 0
      Passed: 32
      Skipped: 1
  extended:
    result: partial
    skippedTests:
    - HTTPRouteRedirectPortAndScheme
    statistics:
      Failed: 0
      Passed: 11
      Skipped: 1
    supportedFeatures:
    - GatewayAddressEmpty
    - GatewayPort8080
    - HTTPRouteBackendProtocolWebSocket
    - HTTPRouteDestinationPortMatching
    - HTTPRouteHostRewrite
    - HTTPRouteMethodMatching
    - HTTPRoutePathRewrite
    - HTTPRoutePortRedirect
    - HTTPRouteQueryParamMatching
    - HTTPRouteRequestMirror
    - HTTPRouteResponseHeaderModification
    - HTTPRouteSchemeRedirect
    unsupportedFeatures:
    - GatewayHTTPListenerIsolation
    - GatewayInfrastructurePropagation
    - GatewayStaticAddresses
    - HTTPRouteBackendProtocolH2C
    - HTTPRouteBackendRequestHeaderModification
    - HTTPRouteBackendTimeout
    - HTTPRouteParentRefPort
    - HTTPRoutePathRedirect
    - HTTPRouteRequestMultipleMirrors
    - HTTPRouteRequestPercentageMirror
    - HTTPRouteRequestTimeout
  name: GATEWAY-HTTP
  summary: Core tests partially succeeded with 1 test skips. Extended tests partially
    succeeded with 1 test skips.
- core:
    result: partial
    skippedTests:
    - TLSRouteSimpleSameNamespace
    statistics:
      Failed: 0
      Passed: 10
      Skipped: 1
  name: GATEWAY-TLS
  summary: Core tests partially succeeded with 1 test skips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

conformance test report - apisix mode

apiVersion: gateway.networking.k8s.io/v1
date: "2026-05-06T02:30:28Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
  contact: null
  organization: APISIX
  project: apisix-ingress-controller
  url: https://github.com/apache/apisix-ingress-controller.git
  version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
    result: success
    statistics:
      Failed: 0
      Passed: 12
      Skipped: 0
  name: GATEWAY-GRPC
  summary: Core tests succeeded.
- core:
    failedTests:
    - HTTPRouteInvalidBackendRefUnknownKind
    result: failure
    skippedTests:
    - HTTPRouteHTTPSListener
    statistics:
      Failed: 1
      Passed: 31
      Skipped: 1
  extended:
    result: partial
    skippedTests:
    - HTTPRouteRedirectPortAndScheme
    statistics:
      Failed: 0
      Passed: 11
      Skipped: 1
    supportedFeatures:
    - GatewayAddressEmpty
    - GatewayPort8080
    - HTTPRouteBackendProtocolWebSocket
    - HTTPRouteDestinationPortMatching
    - HTTPRouteHostRewrite
    - HTTPRouteMethodMatching
    - HTTPRoutePathRewrite
    - HTTPRoutePortRedirect
    - HTTPRouteQueryParamMatching
    - HTTPRouteRequestMirror
    - HTTPRouteResponseHeaderModification
    - HTTPRouteSchemeRedirect
    unsupportedFeatures:
    - GatewayHTTPListenerIsolation
    - GatewayInfrastructurePropagation
    - GatewayStaticAddresses
    - HTTPRouteBackendProtocolH2C
    - HTTPRouteBackendRequestHeaderModification
    - HTTPRouteBackendTimeout
    - HTTPRouteParentRefPort
    - HTTPRoutePathRedirect
    - HTTPRouteRequestMultipleMirrors
    - HTTPRouteRequestPercentageMirror
    - HTTPRouteRequestTimeout
  name: GATEWAY-HTTP
  summary: Core tests failed with 1 test failures. Extended tests partially succeeded
    with 1 test skips.
- core:
    result: partial
    skippedTests:
    - TLSRouteSimpleSameNamespace
    statistics:
      Failed: 0
      Passed: 10
      Skipped: 1
  name: GATEWAY-TLS
  summary: Core tests partially succeeded with 1 test skips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

conformance test report

apiVersion: gateway.networking.k8s.io/v1
date: "2026-05-06T02:51:47Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
  contact: null
  organization: APISIX
  project: apisix-ingress-controller
  url: https://github.com/apache/apisix-ingress-controller.git
  version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
    failedTests:
    - GRPCExactMethodMatching
    - GRPCRouteHeaderMatching
    - GRPCRouteListenerHostnameMatching
    - GatewayModifyListeners
    result: failure
    statistics:
      Failed: 4
      Passed: 8
      Skipped: 0
  name: GATEWAY-GRPC
  summary: Core tests failed with 4 test failures.
- core:
    failedTests:
    - GatewayModifyListeners
    result: failure
    skippedTests:
    - HTTPRouteHTTPSListener
    statistics:
      Failed: 1
      Passed: 31
      Skipped: 1
  extended:
    failedTests:
    - HTTPRouteBackendProtocolWebSocket
    result: failure
    skippedTests:
    - HTTPRouteRedirectPortAndScheme
    statistics:
      Failed: 1
      Passed: 10
      Skipped: 1
    supportedFeatures:
    - GatewayAddressEmpty
    - GatewayPort8080
    - HTTPRouteBackendProtocolWebSocket
    - HTTPRouteDestinationPortMatching
    - HTTPRouteHostRewrite
    - HTTPRouteMethodMatching
    - HTTPRoutePathRewrite
    - HTTPRoutePortRedirect
    - HTTPRouteQueryParamMatching
    - HTTPRouteRequestMirror
    - HTTPRouteResponseHeaderModification
    - HTTPRouteSchemeRedirect
    unsupportedFeatures:
    - GatewayHTTPListenerIsolation
    - GatewayInfrastructurePropagation
    - GatewayStaticAddresses
    - HTTPRouteBackendProtocolH2C
    - HTTPRouteBackendRequestHeaderModification
    - HTTPRouteBackendTimeout
    - HTTPRouteParentRefPort
    - HTTPRoutePathRedirect
    - HTTPRouteRequestMultipleMirrors
    - HTTPRouteRequestPercentageMirror
    - HTTPRouteRequestTimeout
  name: GATEWAY-HTTP
  summary: Core tests failed with 1 test failures. Extended tests failed with 1 test
    failures.
- core:
    failedTests:
    - GatewayModifyListeners
    - TLSRouteSimpleSameNamespace
    result: failure
    statistics:
      Failed: 2
      Passed: 9
      Skipped: 0
  name: GATEWAY-TLS
  summary: Core tests failed with 2 test failures.

AlinsRan and others added 2 commits May 6, 2026 08:40
Copilot AI review requested due to automatic review settings May 6, 2026 02:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
internal/adc/translator/httproute_test.go (1)

146-147: ⚡ Quick win

Guard against empty upstream nodes before indexing.

On Line 147, Nodes[0] can panic if translation returns an empty node list, which makes failures less actionable. Add a require length/non-empty check first.

Suggested patch
 			require.NoError(t, err)
 			require.Len(t, result.Services, 1)
 			require.NotNil(t, result.Services[0].Upstream)
+			require.NotEmpty(t, result.Services[0].Upstream.Nodes)

 			assert.Equal(t, tt.wantScheme, result.Services[0].Upstream.Scheme)
 			assert.Equal(t, "10.0.0.1", result.Services[0].Upstream.Nodes[0].Host)
🤖 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 `@internal/adc/translator/httproute_test.go` around lines 146 - 147, Add a
guard that asserts the upstream nodes slice is non-empty before indexing into
Nodes[0]; specifically, before the line that asserts
result.Services[0].Upstream.Nodes[0].Host, use require.NotEmpty or
require.Greater to check result.Services[0].Upstream.Nodes (or
result.Services[0].Upstream.Nodes.Len()) so the test fails with a clear message
rather than panicking when Nodes is empty.
🤖 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.

Nitpick comments:
In `@internal/adc/translator/httproute_test.go`:
- Around line 146-147: Add a guard that asserts the upstream nodes slice is
non-empty before indexing into Nodes[0]; specifically, before the line that
asserts result.Services[0].Upstream.Nodes[0].Host, use require.NotEmpty or
require.Greater to check result.Services[0].Upstream.Nodes (or
result.Services[0].Upstream.Nodes.Len()) so the test fails with a clear message
rather than panicking when Nodes is empty.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e2ffef3a-ef12-4a9a-a6ab-1a6d917c8dbb

📥 Commits

Reviewing files that changed from the base of the PR and between 1df4062 and 706ea72.

📒 Files selected for processing (1)
  • internal/adc/translator/httproute_test.go

@AlinsRan AlinsRan changed the title backport: preserve HTTPRoute upstream scheme from backend ref fix(backport): preserve HTTPRoute upstream scheme from backend ref May 6, 2026
@AlinsRan AlinsRan merged commit b02e842 into master May 6, 2026
30 of 34 checks passed
@AlinsRan AlinsRan deleted the backport-pr-2691-httproute-scheme branch May 6, 2026 08:49
@AlinsRan AlinsRan self-assigned this May 9, 2026
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.

3 participants