mirror of
https://github.com/alibaba/higress.git
synced 2026-06-08 12:17:28 +08:00
test: allow specifying HTTP protocol (#822)
Signed-off-by: spacewander <spacewanderlzx@gmail.com>
This commit is contained in:
@@ -89,6 +89,70 @@ var WasmPluginsSniMisdirect = suite.ConformanceTest{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Meta: http.AssertionMeta{
|
||||||
|
TestCaseName: "case 3: https/2.0 request with sni and same with host",
|
||||||
|
TargetBackend: "infra-backend-v1",
|
||||||
|
TargetNamespace: "higress-conformance-infra",
|
||||||
|
},
|
||||||
|
Request: http.AssertionRequest{
|
||||||
|
ActualRequest: http.Request{
|
||||||
|
Protocol: "HTTP/2.0",
|
||||||
|
Host: "foo.com",
|
||||||
|
Path: "/foo",
|
||||||
|
Headers: map[string]string{
|
||||||
|
"Content-Type": "text/plain",
|
||||||
|
},
|
||||||
|
TLSConfig: &http.TLSConfig{
|
||||||
|
SNI: "foo.com",
|
||||||
|
Certificates: http.Certificates{
|
||||||
|
CACerts: [][]byte{caCertOut.Bytes()},
|
||||||
|
ClientKeyPairs: []http.ClientKeyPair{{
|
||||||
|
ClientCert: cliCertOut.Bytes(),
|
||||||
|
ClientKey: cliKeyOut.Bytes()},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Response: http.AssertionResponse{
|
||||||
|
ExpectedResponse: http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Meta: http.AssertionMeta{
|
||||||
|
TestCaseName: "case 4: https/2.0 request with sni and not same with host",
|
||||||
|
TargetBackend: "infra-backend-v1",
|
||||||
|
TargetNamespace: "higress-conformance-infra",
|
||||||
|
},
|
||||||
|
Request: http.AssertionRequest{
|
||||||
|
ActualRequest: http.Request{
|
||||||
|
Protocol: "HTTP/2.0",
|
||||||
|
Host: "bar.com",
|
||||||
|
Path: "/foo",
|
||||||
|
Headers: map[string]string{
|
||||||
|
"Content-Type": "text/plain",
|
||||||
|
},
|
||||||
|
TLSConfig: &http.TLSConfig{
|
||||||
|
SNI: "foo.com",
|
||||||
|
Certificates: http.Certificates{
|
||||||
|
CACerts: [][]byte{caCertOut.Bytes()},
|
||||||
|
ClientKeyPairs: []http.ClientKeyPair{{
|
||||||
|
ClientCert: cliCertOut.Bytes(),
|
||||||
|
ClientKey: cliKeyOut.Bytes()},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Response: http.AssertionResponse{
|
||||||
|
ExpectedResponse: http.Response{
|
||||||
|
StatusCode: 421,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("WasmPlugin sni-misdirect", func(t *testing.T) {
|
t.Run("WasmPlugin sni-misdirect", func(t *testing.T) {
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ spec:
|
|||||||
ingressClassName: higress
|
ingressClassName: higress
|
||||||
tls:
|
tls:
|
||||||
- hosts:
|
- hosts:
|
||||||
- "foo.com"
|
- "*.com"
|
||||||
secretName: foo-secret
|
secretName: foo-secret
|
||||||
rules:
|
rules:
|
||||||
- host: "foo.com"
|
- host: "*.com"
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- pathType: Exact
|
- pathType: Exact
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ const (
|
|||||||
// values can be provided, as a comma-separated value.
|
// values can be provided, as a comma-separated value.
|
||||||
type Request struct {
|
type Request struct {
|
||||||
Host string
|
Host string
|
||||||
|
Protocol string
|
||||||
Method string
|
Method string
|
||||||
Path string
|
Path string
|
||||||
Headers map[string]string
|
Headers map[string]string
|
||||||
@@ -162,12 +163,10 @@ func MakeRequestAndExpectEventuallyConsistentResponse(t *testing.T, r roundtripp
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
scheme = "http"
|
scheme = "http"
|
||||||
protocol = "HTTP"
|
|
||||||
tlsConfig *roundtripper.TLSConfig
|
tlsConfig *roundtripper.TLSConfig
|
||||||
)
|
)
|
||||||
if expected.Request.ActualRequest.TLSConfig != nil {
|
if expected.Request.ActualRequest.TLSConfig != nil {
|
||||||
scheme = "https"
|
scheme = "https"
|
||||||
protocol = "HTTPS"
|
|
||||||
clientKeyPairs := make([]roundtripper.ClientKeyPair, 0, len(expected.Request.ActualRequest.TLSConfig.Certificates.ClientKeyPairs))
|
clientKeyPairs := make([]roundtripper.ClientKeyPair, 0, len(expected.Request.ActualRequest.TLSConfig.Certificates.ClientKeyPairs))
|
||||||
for _, keyPair := range expected.Request.ActualRequest.TLSConfig.Certificates.ClientKeyPairs {
|
for _, keyPair := range expected.Request.ActualRequest.TLSConfig.Certificates.ClientKeyPairs {
|
||||||
clientKeyPairs = append(clientKeyPairs, roundtripper.ClientKeyPair{
|
clientKeyPairs = append(clientKeyPairs, roundtripper.ClientKeyPair{
|
||||||
@@ -213,6 +212,11 @@ func MakeRequestAndExpectEventuallyConsistentResponse(t *testing.T, r roundtripp
|
|||||||
|
|
||||||
path, query, _ := strings.Cut(expected.Request.ActualRequest.Path, "?")
|
path, query, _ := strings.Cut(expected.Request.ActualRequest.Path, "?")
|
||||||
|
|
||||||
|
protocol := "HTTP/1.1"
|
||||||
|
if expected.Request.ActualRequest.Protocol != "" {
|
||||||
|
protocol = expected.Request.ActualRequest.Protocol
|
||||||
|
}
|
||||||
|
|
||||||
req := roundtripper.Request{
|
req := roundtripper.Request{
|
||||||
Method: expected.Request.ActualRequest.Method,
|
Method: expected.Request.ActualRequest.Method,
|
||||||
Host: expected.Request.ActualRequest.Host,
|
Host: expected.Request.ActualRequest.Host,
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
|
"golang.org/x/net/http2"
|
||||||
|
|
||||||
"github.com/alibaba/higress/test/e2e/conformance/utils/config"
|
"github.com/alibaba/higress/test/e2e/conformance/utils/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -109,6 +111,53 @@ type DefaultRoundTripper struct {
|
|||||||
TimeoutConfig config.TimeoutConfig
|
TimeoutConfig config.TimeoutConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *DefaultRoundTripper) initTransport(client *http.Client, protocol string, tlsConfig *TLSConfig) error {
|
||||||
|
var tlsClientConfig *tls.Config
|
||||||
|
if tlsConfig != nil {
|
||||||
|
pool := x509.NewCertPool()
|
||||||
|
for _, caCert := range tlsConfig.Certificates.CACert {
|
||||||
|
pool.AppendCertsFromPEM(caCert)
|
||||||
|
}
|
||||||
|
var clientCerts []tls.Certificate
|
||||||
|
for _, keyPair := range tlsConfig.Certificates.ClientKeyPairs {
|
||||||
|
newClientCert, err := tls.X509KeyPair(keyPair.ClientCert, keyPair.ClientKey)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to load client key pair: %w", err)
|
||||||
|
}
|
||||||
|
clientCerts = append(clientCerts, newClientCert)
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsClientConfig = &tls.Config{
|
||||||
|
MinVersion: tlsConfig.MinVersion,
|
||||||
|
MaxVersion: tlsConfig.MaxVersion,
|
||||||
|
ServerName: tlsConfig.SNI,
|
||||||
|
CipherSuites: tlsConfig.CipherSuites,
|
||||||
|
RootCAs: pool,
|
||||||
|
Certificates: clientCerts,
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch protocol {
|
||||||
|
case "HTTP/2.0":
|
||||||
|
tr := &http2.Transport{}
|
||||||
|
if tlsClientConfig != nil {
|
||||||
|
tr.TLSClientConfig = tlsClientConfig
|
||||||
|
}
|
||||||
|
client.Transport = tr
|
||||||
|
default: // HTTP1
|
||||||
|
if tlsClientConfig != nil {
|
||||||
|
client.Transport = &http.Transport{
|
||||||
|
TLSHandshakeTimeout: d.TimeoutConfig.TLSHandshakeTimeout,
|
||||||
|
DisableKeepAlives: true,
|
||||||
|
TLSClientConfig: tlsClientConfig,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// CaptureRoundTrip makes a request with the provided parameters and returns the
|
// CaptureRoundTrip makes a request with the provided parameters and returns the
|
||||||
// captured request and response from echoserver. An error will be returned if
|
// captured request and response from echoserver. An error will be returned if
|
||||||
// there is an error running the function but not if an HTTP error status code
|
// there is an error running the function but not if an HTTP error status code
|
||||||
@@ -152,6 +201,8 @@ func (d *DefaultRoundTripper) CaptureRoundTrip(request Request) (*CapturedReques
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d.initTransport(client, request.Protocol, request.TLSConfig)
|
||||||
|
|
||||||
method := "GET"
|
method := "GET"
|
||||||
if request.Method != "" {
|
if request.Method != "" {
|
||||||
method = request.Method
|
method = request.Method
|
||||||
|
|||||||
77
test/e2e/conformance/utils/roundtripper/roundtripper_test.go
Normal file
77
test/e2e/conformance/utils/roundtripper/roundtripper_test.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package roundtripper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"golang.org/x/net/http2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTransport(t *testing.T) {
|
||||||
|
req := Request{
|
||||||
|
Protocol: "HTTP/2.0",
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
req Request
|
||||||
|
prevTransport http.RoundTripper
|
||||||
|
tlsConfig *TLSConfig
|
||||||
|
transport http.RoundTripper
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "default",
|
||||||
|
req: Request{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "http2",
|
||||||
|
req: req,
|
||||||
|
transport: &http2.Transport{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "http1",
|
||||||
|
req: Request{
|
||||||
|
Protocol: "HTTP/1.1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "https",
|
||||||
|
req: req,
|
||||||
|
tlsConfig: &TLSConfig{
|
||||||
|
SNI: "www.example.com",
|
||||||
|
},
|
||||||
|
transport: &http2.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{
|
||||||
|
RootCAs: x509.NewCertPool(),
|
||||||
|
ServerName: "www.example.com",
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
d := DefaultRoundTripper{}
|
||||||
|
c := http.Client{}
|
||||||
|
d.initTransport(&c, tt.req.Protocol, tt.tlsConfig)
|
||||||
|
assert.Equal(t, tt.transport, c.Transport)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user