Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release-0.8] IPv6 conformance: Third time's the charm #2381

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 3 additions & 30 deletions conformance/utils/echo/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"bytes"
"context"
"fmt"
"net"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -58,7 +57,7 @@ func (m *MeshPod) MakeRequestAndExpectEventuallyConsistentResponse(t *testing.T,
t.Helper()

http.AwaitConvergence(t, timeoutConfig.RequiredConsecutiveSuccesses, timeoutConfig.MaxTimeToConsistency, func(elapsed time.Duration) bool {
req := makeRequest(exp.Request)
req := makeRequest(t, exp.Request)

resp, err := m.request(req)
if err != nil {
Expand All @@ -76,12 +75,12 @@ func (m *MeshPod) MakeRequestAndExpectEventuallyConsistentResponse(t *testing.T,
t.Logf("Request passed")
}

func makeRequest(r http.Request) []string {
func makeRequest(t *testing.T, r http.Request) []string {
protocol := strings.ToLower(r.Protocol)
if protocol == "" {
protocol = "http"
}
host := calculateHost(r.Host, protocol)
host := http.CalculateHost(t, r.Host, protocol)
args := []string{"client", fmt.Sprintf("%s://%s%s", protocol, host, r.Path)}
if r.Method != "" {
args = append(args, "--method="+r.Method)
Expand Down Expand Up @@ -113,32 +112,6 @@ func compareRequest(exp http.ExpectedResponse, resp Response) error {
return nil
}

// copied from conformance/http to get the ipv6 matching
func calculateHost(reqHost, scheme string) string {
host, port, err := net.SplitHostPort(reqHost)
if err != nil {
return reqHost
}
if strings.ToLower(scheme) == "http" && port == "80" {
return ipv6SafeHost(host)
}
if strings.ToLower(scheme) == "https" && port == "443" {
return ipv6SafeHost(host)
}
return reqHost
}

func ipv6SafeHost(host string) string {
// We assume that host is a literal IPv6 address if host has
// colons.
// Per https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2.
// This is like net.JoinHostPort, but we don't need a port.
if strings.Contains(host, ":") {
return "[" + host + "]"
}
return host
}

func (m *MeshPod) request(args []string) (Response, error) {
container := "echo"

Expand Down
15 changes: 11 additions & 4 deletions conformance/utils/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func MakeRequest(t *testing.T, expected *ExpectedResponse, gwAddr, protocol, sch
}

path, query, _ := strings.Cut(expected.Request.Path, "?")
reqURL := url.URL{Scheme: scheme, Host: calculateHost(gwAddr, scheme), Path: path, RawQuery: query}
reqURL := url.URL{Scheme: scheme, Host: CalculateHost(t, gwAddr, scheme), Path: path, RawQuery: query}

t.Logf("Making %s request to %s", expected.Request.Method, reqURL.String())

Expand Down Expand Up @@ -140,14 +140,21 @@ func MakeRequest(t *testing.T, expected *ExpectedResponse, gwAddr, protocol, sch
return req
}

// calculateHost will calculate the Host header as per [HTTP spec]. To
// CalculateHost will calculate the Host header as per [HTTP spec]. To
// summarize, host will not include any port if it is implied from the scheme. In
// case of any error, the input gwAddr will be returned as the default.
//
// [HTTP spec]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23
func calculateHost(gwAddr, scheme string) string {
host, port, err := net.SplitHostPort(gwAddr)
func CalculateHost(t *testing.T, gwAddr, scheme string) string {
host, port, err := net.SplitHostPort(gwAddr) // note: this will strip brackets of an IPv6 address
if err != nil && strings.Contains(err.Error(), "too many colons in address") {
// This is an IPv6 address; assume it's valid ipv6
// Assume caller won't add a port without brackets
gwAddr = "[" + gwAddr + "]"
host, port, err = net.SplitHostPort(gwAddr)
}
if err != nil {
t.Logf("Failed to parse host %q: %v", gwAddr, err)
return gwAddr
}
if strings.ToLower(scheme) == "http" && port == "80" {
Expand Down