diff --git a/.github/workflows/codeChecks.yml b/.github/workflows/codeChecks.yml index 1681afb..f0d7439 100644 --- a/.github/workflows/codeChecks.yml +++ b/.github/workflows/codeChecks.yml @@ -89,10 +89,10 @@ jobs: run: go mod tidy - name: Test with the Go CLI - run: go test ./... -coverprofile=./cover.out -covermode=atomic -coverpkg=./... + run: CGO_ENABLED=1 go test ./... -race - name: Build - run: go build -v ./... + run: CGO_ENABLED=0 go build -v ./... go_test_coverage_check: needs: go_tests diff --git a/CHANGELOG.md b/CHANGELOG.md index 05064a3..8dcc1b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,18 @@ switch to Go 1.27.1 +### Feat + + Requests: pin Go 1.27 ML-KEM hybrid CurvePreferences (including P-521 fallback) and print the negotiated key exchange. + ### Tests Certinfo: GetRemoteCerts tests apply SetTLSInsecure before SetTLSEndpoint so endpoint certificate retrieval uses the intended TLS verification mode. + Requests: httptest TLS servers bind an ephemeral port so parallel cases do not collide on fixed listeners. + + Cmd: re-bind viper flags after Reset so repeated test counts keep CLI flag bindings. + ## 0.15.1 (2026-09-03) ### Feat diff --git a/internal/cmd/root.go b/internal/cmd/root.go index a449360..3e9aa0b 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -105,11 +105,6 @@ func init() { StringVar(&cfgFile, "config", "", "config file (default is $HOME/.https-wrench.yaml)") rootCmd.PersistentFlags().Bool("version", false, "Display the version") - err := viper.BindPFlag("version", rootCmd.PersistentFlags().Lookup("version")) - if err != nil { - fmt.Printf("Error binding version flag: %v\n", err) - } - addCaBundleFlag(requestsCmd) // addCertBundleFlag(requestsCmd) // addKeyFileFlag(requestsCmd) @@ -117,6 +112,30 @@ func init() { addCaBundleFlag(certinfoCmd) addCertBundleFlag(certinfoCmd) addKeyFileFlag(certinfoCmd) + + bindViperFlags() +} + +func bindViperFlags() { + if err := viper.BindPFlag("version", rootCmd.PersistentFlags().Lookup("version")); err != nil { + fmt.Printf("Error binding version flag: %v\n", err) + } + + if err := viper.BindPFlag("ca-bundle", requestsCmd.Flags().Lookup("ca-bundle")); err != nil { + fmt.Printf("Error binding ca-bundle flag: %v\n", err) + } + + if err := viper.BindPFlag("ca-bundle", certinfoCmd.Flags().Lookup("ca-bundle")); err != nil { + fmt.Printf("Error binding ca-bundle flag: %v\n", err) + } + + if err := viper.BindPFlag("cert-bundle", certinfoCmd.Flags().Lookup("cert-bundle")); err != nil { + fmt.Printf("Error binding cert-bundle flag: %v\n", err) + } + + if err := viper.BindPFlag("key-file", certinfoCmd.Flags().Lookup("key-file")); err != nil { + fmt.Printf("Error binding key-file flag: %v\n", err) + } } func initConfig() { @@ -168,27 +187,12 @@ func isMCPCommand() bool { func addCaBundleFlag(cmd *cobra.Command) { cmd.Flags().StringVar(&caBundlePath, "ca-bundle", "", `Path to bundle file with CA certificates to use for validation`) - - err := viper.BindPFlag("ca-bundle", cmd.Flags().Lookup("ca-bundle")) - if err != nil { - fmt.Printf("Error binding ca-bundle flag: %v\n", err) - } } func addCertBundleFlag(cmd *cobra.Command) { cmd.Flags().StringVar(&certBundlePath, "cert-bundle", "", "Path to PEM Certificate bundle file") - - err := viper.BindPFlag("cert-bundle", cmd.Flags().Lookup("cert-bundle")) - if err != nil { - fmt.Printf("Error binding cert-bundle flag: %v\n", err) - } } func addKeyFileFlag(cmd *cobra.Command) { cmd.Flags().StringVar(&keyFilePath, "key-file", "", "Path to PEM Key file") - - err := viper.BindPFlag("key-file", cmd.Flags().Lookup("key-file")) - if err != nil { - fmt.Printf("Error binding key-file flag: %v\n", err) - } } diff --git a/internal/cmd/root_test.go b/internal/cmd/root_test.go index 14664e5..167736b 100644 --- a/internal/cmd/root_test.go +++ b/internal/cmd/root_test.go @@ -13,15 +13,28 @@ import ( "github.com/xenos76/https-wrench/internal/requests" ) +func resetPersistentFlag(name string) { + f := rootCmd.PersistentFlags().Lookup(name) + _ = f.Value.Set(f.DefValue) + f.Changed = false +} + +func resetViper() { + resetPersistentFlag("version") + resetPersistentFlag("config") + viper.Reset() + bindViperFlags() +} + //nolint:revive func TestRootCmd_LoadConfig(t *testing.T) { t.Run("LoadConfig no config file", func(t *testing.T) { oldCfg := cfgFile t.Cleanup(func() { - cfgFile = oldCfg + resetViper() - viper.Reset() + cfgFile = oldCfg }) var mc requests.RequestsMetaConfig @@ -44,9 +57,9 @@ func TestRootCmd_LoadConfig(t *testing.T) { oldCfg := cfgFile t.Cleanup(func() { - cfgFile = oldCfg + resetViper() - viper.Reset() + cfgFile = oldCfg }) var expectedCaCertsPool *x509.CertPool @@ -79,9 +92,9 @@ func TestRootCmd_LoadConfig(t *testing.T) { oldCfg := cfgFile t.Cleanup(func() { - cfgFile = oldCfg + resetViper() - viper.Reset() + cfgFile = oldCfg }) cfgFile = "../../assets/examples/https-wrench-k3s-anchor-and-aliases.yaml" @@ -117,9 +130,9 @@ func TestRootCmd_LoadConfig(t *testing.T) { oldCfg := cfgFile t.Cleanup(func() { - cfgFile = oldCfg + resetViper() - viper.Reset() + cfgFile = oldCfg }) // Make Unmarshal fail by setting a type mismatch @@ -159,10 +172,10 @@ func TestRootCmd_Execute(t *testing.T) { oldCfg := cfgFile t.Cleanup(func() { - cfgFile = oldCfg - rootCmd.SetArgs(nil) - viper.Reset() + resetViper() + + cfgFile = oldCfg }) rootCmd.SetArgs([]string{"--config", "./embedded/config-example.yaml"}) @@ -228,9 +241,9 @@ func TestRootCmd(t *testing.T) { oldCfg := cfgFile t.Cleanup(func() { - cfgFile = oldCfg + resetViper() - viper.Reset() + cfgFile = oldCfg }) buf := new(bytes.Buffer) diff --git a/internal/requests/main_test.go b/internal/requests/main_test.go index d73f56d..5b4d3a3 100644 --- a/internal/requests/main_test.go +++ b/internal/requests/main_test.go @@ -34,11 +34,12 @@ type demoCertTemplate struct { //nolint:revive type demoHttpServerData struct { - serverAddr string - proxyprotoEnabled bool - serverName string - tlsCipherSuites []uint16 - tlsMaxVersion uint16 + listenHost string + proxyprotoEnabled bool + serverName string + tlsCipherSuites []uint16 + tlsCurvePreferences []tls.CurveID + tlsMaxVersion uint16 } var ( @@ -170,6 +171,16 @@ func printResponseBody(res *http.Response) { fmt.Println(string(body)) } +func testServerHostPort(ts *httptest.Server) string { + return ts.Listener.Addr().String() +} + +// NewHTTPSTestServer starts an httptest TLS server configured by data. +// Cipher suites default to the TLS 1.3 AEADs, CurvePreferences to the Go 1.27 +// PQ hybrids plus classical fallbacks, and MaxVersion to TLS 1.3. Non-empty +// data.tlsCipherSuites, data.tlsCurvePreferences, or a non-zero data.tlsMaxVersion +// override those defaults. Optional data.listenHost and data.proxyprotoEnabled +// replace the listener. The caller must Close the returned server. func NewHTTPSTestServer(data demoHttpServerData) (*httptest.Server, error) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "DemoHTTPSServer Handler - client output\n") @@ -181,29 +192,21 @@ func NewHTTPSTestServer(data demoHttpServerData) (*httptest.Server, error) { ts := httptest.NewUnstartedServer(handler) ts.EnableHTTP2 = true - // fmt.Println("Inside NewDemoHTTPSServer()") - - if data.serverAddr != emptyString && !data.proxyprotoEnabled { - listener, err := net.Listen("tcp", data.serverAddr) + if data.listenHost != emptyString { + ln, err := net.Listen("tcp", net.JoinHostPort(data.listenHost, "0")) if err != nil { - fmt.Println("Error creating listener:", err) + return nil, fmt.Errorf("error creating listener: %w", err) } - ts.Listener = listener + _ = ts.Listener.Close() + ts.Listener = ln } - if data.serverAddr != emptyString && data.proxyprotoEnabled { - ln, err := net.Listen("tcp", data.serverAddr) - if err != nil { - panic(err) - } - - proxyListener := &proxyproto.Listener{ - Listener: ln, + if data.proxyprotoEnabled { + ts.Listener = &proxyproto.Listener{ + Listener: ts.Listener, ReadHeaderTimeout: 10 * time.Second, } - - ts.Listener = proxyListener } cert, err := tls.LoadX509KeyPair( @@ -226,6 +229,12 @@ func NewHTTPSTestServer(data demoHttpServerData) (*httptest.Server, error) { tlsCipherSuites = data.tlsCipherSuites } + tlsCurvePreferences := defaultCurvePreferences + + if len(data.tlsCurvePreferences) > 0 { + tlsCurvePreferences = data.tlsCurvePreferences + } + // Set default TLS MaxVersion to 1.3 var tlsMaxVersion uint16 = tls.VersionTLS13 @@ -234,9 +243,10 @@ func NewHTTPSTestServer(data demoHttpServerData) (*httptest.Server, error) { } ts.TLS = &tls.Config{ - Certificates: []tls.Certificate{cert}, - CipherSuites: tlsCipherSuites, - MaxVersion: tlsMaxVersion, + Certificates: []tls.Certificate{cert}, + CipherSuites: tlsCipherSuites, + CurvePreferences: tlsCurvePreferences, + MaxVersion: tlsMaxVersion, } ts.StartTLS() @@ -374,9 +384,9 @@ func TestMain(m *testing.M) { func TestHTTPSTestServer(t *testing.T) { tests := []struct { testname string - serverAddr string + listenHost string }{ - {"localhostIPv4", "127.0.0.1:55667"}, + {"localhostIPv4", "127.0.0.1"}, } for _, tt := range tests { @@ -384,15 +394,14 @@ func TestHTTPSTestServer(t *testing.T) { t.Run(testname, func(t *testing.T) { t.Parallel() - httpSrvData := demoHttpServerData{serverAddr: tt.serverAddr} - // httpSrvData := demoHttpServerData{} + httpSrvData := demoHttpServerData{listenHost: tt.listenHost} ts, err := NewHTTPSTestServer(httpSrvData) if err != nil { t.Fatal(err) } - defer ts.Close() + t.Cleanup(ts.Close) // fmt.Println("TestDemoHTTPSServer") // fmt.Print("Client URL: ") diff --git a/internal/requests/requests.go b/internal/requests/requests.go index 114042c..50713c9 100644 --- a/internal/requests/requests.go +++ b/internal/requests/requests.go @@ -13,6 +13,7 @@ import ( "net/http" "net/http/httputil" "os" + "slices" "strings" "time" @@ -41,6 +42,18 @@ const ( emptyString = "" ) +// defaultCurvePreferences lists Go 1.27 TLS hybrids plus classical fallbacks. +// Explicit CurvePreferences keeps PQ on when GODEBUG=tlsmlkem=0 / tlssecpmlkem=0. +var defaultCurvePreferences = []tls.CurveID{ + tls.X25519MLKEM768, + tls.SecP256r1MLKEM768, + tls.SecP384r1MLKEM1024, + tls.X25519, + tls.CurveP256, + tls.CurveP384, + tls.CurveP521, +} + // ErrMethodNotFound is returned when an unsupported HTTP method is specified. var ErrMethodNotFound = errors.New("HTTP method not found") @@ -312,6 +325,7 @@ func (r *RequestConfig) printTLSInfo(w io.Writer, tlsState *tls.ConnectionState) fmt.Fprintln(w, "TLS:") fmt.Fprintf(w, "Version: %v\n", TLSVersionName(tlsState.Version)) fmt.Fprintf(w, "CipherSuite: %v\n", cipherSuiteName(tlsState.CipherSuite)) + fmt.Fprintf(w, "Key Exchange: %v\n", tlsState.CurveID) for i, cert := range tlsState.PeerCertificates { fmt.Fprintf(w, "Certificate %d:\n", i) @@ -330,7 +344,9 @@ func (r *RequestConfig) printTLSInfo(w io.Writer, tlsState *tls.ConnectionState) // NewRequestHTTPClient creates a new RequestHTTPClient with default transport settings. func NewRequestHTTPClient() *RequestHTTPClient { - tlsConfig := &tls.Config{} + tlsConfig := &tls.Config{ + CurvePreferences: slices.Clone(defaultCurvePreferences), + } httpClient := &http.Client{ Transport: &http.Transport{ ForceAttemptHTTP2: true, diff --git a/internal/requests/requests_handlers.go b/internal/requests/requests_handlers.go index 71ed86d..ec5e960 100644 --- a/internal/requests/requests_handlers.go +++ b/internal/requests/requests_handlers.go @@ -381,6 +381,10 @@ func RenderTLSData(w io.Writer, r *http.Response, filter ...[]map[int][]string) sl("CipherSuite"), sv(cipherSuiteName(respTLS.CipherSuite)), ) + t.Row( + sl("Key Exchange"), + sv(respTLS.CurveID.String()), + ) fmt.Fprintln(w, t.Render()) t.ClearRows() diff --git a/internal/requests/requests_handlers_test.go b/internal/requests/requests_handlers_test.go index 735ab21..5e95e70 100644 --- a/internal/requests/requests_handlers_test.go +++ b/internal/requests/requests_handlers_test.go @@ -318,12 +318,13 @@ func TestTransportAddressFromURLString(t *testing.T) { //nolint:revive func TestRenderTLSData(t *testing.T) { tests := []struct { - srvAddr string - srvTLSCipherSuite uint16 - srvTLSMaxVersion uint16 - reqConf RequestConfig - pool *x509.CertPool - injectTLSError bool + srvTLSCipherSuite uint16 + srvTLSMaxVersion uint16 + tlsCurvePreferences []tls.CurveID + reqConf RequestConfig + pool *x509.CertPool + injectTLSError bool + wantCurveID string }{ // WARN: not all cipher suites listed as 'TLS 1.0 - 1.2 cipher suites' // are supported. @@ -331,17 +332,16 @@ func TestRenderTLSData(t *testing.T) { // https://pkg.go.dev/crypto/tls#pkg-constants // https://github.com/golang/go/issues/53750 { - srvAddr: "localhost:46101", srvTLSCipherSuite: tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, srvTLSMaxVersion: tls.VersionTLS12, reqConf: RequestConfig{ - Name: "example.com", - TransportOverrideURL: "https://localhost:46101", + Name: "example.com", Hosts: []Host{ {Name: "example.com"}, }, }, - pool: caCertPool, + pool: caCertPool, + wantCurveID: "X25519", }, // WARN: I was expecting a cipherSuite list of one element as input to the server conf @@ -349,26 +349,23 @@ func TestRenderTLSData(t *testing.T) { // This test seems to prove the default list is returned instead (..SHA256 vs ...SHA384) // Is this related to the certificate? { - srvAddr: "localhost:46102", // srvTLSCipherSuite: tls.TLS_AES_256_GCM_SHA384, srvTLSCipherSuite: tls.TLS_AES_128_GCM_SHA256, srvTLSMaxVersion: tls.VersionTLS13, reqConf: RequestConfig{ - Name: "example.net", - TransportOverrideURL: "https://localhost:46102", + Name: "example.net", Hosts: []Host{ {Name: "example.net"}, }, }, - pool: caCertPool, + pool: caCertPool, + wantCurveID: "X25519MLKEM768", }, { - srvAddr: "localhost:46103", srvTLSCipherSuite: tls.TLS_AES_128_GCM_SHA256, srvTLSMaxVersion: tls.VersionTLS13, reqConf: RequestConfig{ - Name: "example.de", - TransportOverrideURL: "https://localhost:46103", + Name: "example.de", Hosts: []Host{ {Name: "example.de"}, }, @@ -376,6 +373,58 @@ func TestRenderTLSData(t *testing.T) { pool: caCertPool, injectTLSError: true, }, + { + srvTLSCipherSuite: tls.TLS_AES_128_GCM_SHA256, + srvTLSMaxVersion: tls.VersionTLS13, + tlsCurvePreferences: []tls.CurveID{tls.X25519MLKEM768}, + reqConf: RequestConfig{ + Name: "X25519MLKEM768", + Hosts: []Host{ + {Name: "example.com"}, + }, + }, + pool: caCertPool, + wantCurveID: "X25519MLKEM768", + }, + { + srvTLSCipherSuite: tls.TLS_AES_128_GCM_SHA256, + srvTLSMaxVersion: tls.VersionTLS13, + tlsCurvePreferences: []tls.CurveID{tls.SecP256r1MLKEM768}, + reqConf: RequestConfig{ + Name: "SecP256r1MLKEM768", + Hosts: []Host{ + {Name: "example.net"}, + }, + }, + pool: caCertPool, + wantCurveID: "SecP256r1MLKEM768", + }, + { + srvTLSCipherSuite: tls.TLS_AES_128_GCM_SHA256, + srvTLSMaxVersion: tls.VersionTLS13, + tlsCurvePreferences: []tls.CurveID{tls.SecP384r1MLKEM1024}, + reqConf: RequestConfig{ + Name: "SecP384r1MLKEM1024", + Hosts: []Host{ + {Name: "example.de"}, + }, + }, + pool: caCertPool, + wantCurveID: "SecP384r1MLKEM1024", + }, + { + srvTLSCipherSuite: tls.TLS_AES_128_GCM_SHA256, + srvTLSMaxVersion: tls.VersionTLS13, + tlsCurvePreferences: []tls.CurveID{tls.CurveP521}, + reqConf: RequestConfig{ + Name: "CurveP521", + Hosts: []Host{ + {Name: "example.com"}, + }, + }, + pool: caCertPool, + wantCurveID: "CurveP521", + }, } for _, tc := range tests { @@ -384,17 +433,19 @@ func TestRenderTLSData(t *testing.T) { t.Parallel() httpSrvData := demoHttpServerData{ - serverAddr: tt.srvAddr, - tlsCipherSuites: []uint16{tt.srvTLSCipherSuite}, - tlsMaxVersion: tt.srvTLSMaxVersion, - proxyprotoEnabled: false, - serverName: "localhost", + tlsCipherSuites: []uint16{tt.srvTLSCipherSuite}, + tlsCurvePreferences: tt.tlsCurvePreferences, + tlsMaxVersion: tt.srvTLSMaxVersion, + proxyprotoEnabled: false, + serverName: "localhost", } ts, err := NewHTTPSTestServer(httpSrvData) require.NoError(t, err) - defer ts.Close() + t.Cleanup(ts.Close) + + tt.reqConf.TransportOverrideURL = "https://" + testServerHostPort(ts) respList, err := processHTTPRequestsByHost( context.Background(), @@ -431,6 +482,10 @@ func TestRenderTLSData(t *testing.T) { expectedCipherSuiteName := tls.CipherSuiteName(tt.srvTLSCipherSuite) assert.Contains(t, got, expectedCipherSuiteName) + require.NotEmpty(t, tt.wantCurveID) + assert.Contains(t, got, "Key Exchange") + assert.Contains(t, got, tt.wantCurveID) + assert.Contains(t, got, "Certificate 0") assert.Contains(t, got, "Subject") assert.Contains(t, got, "DNSNames") @@ -448,9 +503,8 @@ func TestHandleRequests(t *testing.T) { RequestVerbose: true, Requests: []RequestConfig{ { - Name: "Meta10", - TransportOverrideURL: "localhost:46201", - UserAgent: "Meta10", + Name: "Meta10", + UserAgent: "Meta10", Hosts: []Host{ {Name: "example.com"}, }, @@ -463,9 +517,8 @@ func TestHandleRequests(t *testing.T) { RequestVerbose: true, Requests: []RequestConfig{ { - Name: "Meta11", - TransportOverrideURL: "localhost:46202", - UserAgent: "Meta11", + Name: "Meta11", + UserAgent: "Meta11", Hosts: []Host{ {Name: emptyString}, }, @@ -475,18 +528,15 @@ func TestHandleRequests(t *testing.T) { tests := []struct { desc string - srvAddr string reqMeta RequestsMetaConfig expectErr bool }{ { desc: "Meta10", - srvAddr: "localhost:46201", reqMeta: reqMeta1, }, { desc: "Meta11", - srvAddr: "localhost:46202", reqMeta: reqMeta2, expectErr: true, }, @@ -502,7 +552,6 @@ func TestHandleRequests(t *testing.T) { type handleRequestsTestCase struct { desc string - srvAddr string reqMeta RequestsMetaConfig expectErr bool } @@ -511,14 +560,15 @@ func runHandleRequestsSubtest(t *testing.T, tt handleRequestsTestCase) { t.Parallel() httpSrvData := demoHttpServerData{ - serverAddr: tt.srvAddr, serverName: "localhost", } ts, err := NewHTTPSTestServer(httpSrvData) require.NoError(t, err) - defer ts.Close() + t.Cleanup(ts.Close) + + tt.reqMeta.Requests[0].TransportOverrideURL = testServerHostPort(ts) buffer := bytes.Buffer{} respMap, err := HandleRequests(context.Background(), &buffer, &tt.reqMeta) diff --git a/internal/requests/requests_test.go b/internal/requests/requests_test.go index 39facff..3d2e1d4 100644 --- a/internal/requests/requests_test.go +++ b/internal/requests/requests_test.go @@ -262,6 +262,10 @@ func TestNewRequestHTTPClient(t *testing.T) { transportExpectContinueTimeout, transport.ExpectContinueTimeout, "unexpected value for ExpectContinueTimeout") + assert.Equal(t, + defaultCurvePreferences, + transport.TLSClientConfig.CurvePreferences, + "unexpected CurvePreferences") }) } @@ -859,21 +863,16 @@ func TestRequestHTTPClient_SetTransportOverride_Error(t *testing.T) { //nolint:revive // test function func TestRequestHTTPClient_SetTransportOverride_transportAddress_server(t *testing.T) { tests := []struct { - trasportURL string - transportAddr string - requestHost string + requestHost string }{ { - "https://127.0.0.1:6455", - "127.0.0.1:6455", "example.com", }, } for _, tc := range tests { tt := tc // safer when using t.Parallel() - testname := fmt.Sprintf("%v", tt.trasportURL) - t.Run(testname, func(t *testing.T) { + t.Run(tt.requestHost, func(t *testing.T) { runSetTransportOverrideSubtest(t, tt) }) } @@ -883,17 +882,17 @@ func TestRequestHTTPClient_SetTransportOverride_transportAddress_server(t *testi func TestRequestHTTPClient_SetProxyProtocolV2_server(t *testing.T) { tests := []struct { testname string - addr string + listenHost string serverName string }{ { "localhost IPv4", - "127.0.0.1:45678", + "", "example.net", }, { "localhost IPv6", - "[::1]:45679", + "::1", "example.de", }, } @@ -990,13 +989,11 @@ func TestPrintCmd(t *testing.T) { func TestPrintResponseDebug(t *testing.T) { tests := []struct { desc string - srvAddr string verbose bool outputs []string }{ { desc: "verboseTrue", - srvAddr: "localhost:46010", verbose: true, outputs: []string{ "Requested url:", @@ -1004,11 +1001,11 @@ func TestPrintResponseDebug(t *testing.T) { "DemoHTTPSServer Handler - client output", "TLS:", "CipherSuite:", + "Key Exchange:", }, }, { desc: "verboseFalse", - srvAddr: "localhost:46011", verbose: false, outputs: []string{emptyString}, }, @@ -1141,7 +1138,6 @@ func TestPrintRequestDebug(t *testing.T) { //nolint:revive func TestProcessHTTPRequestsByHost(t *testing.T) { tests := []struct { - srvAddr string reqConf RequestConfig pool *x509.CertPool verbose bool @@ -1149,11 +1145,9 @@ func TestProcessHTTPRequestsByHost(t *testing.T) { errMsg string }{ { - srvAddr: "localhost:46001", reqConf: RequestConfig{ - Name: "StatusOK", - TransportOverrideURL: "https://localhost:46001", - UserAgent: "test-ua", + Name: "StatusOK", + UserAgent: "test-ua", RequestHeaders: []RequestHeader{ {Key: "testKey", Value: "testValue"}, {Key: "testKey2", Value: "testValue2"}, @@ -1168,10 +1162,8 @@ func TestProcessHTTPRequestsByHost(t *testing.T) { }, { - srvAddr: "localhost:46002", reqConf: RequestConfig{ - Name: "invalidServerName", - TransportOverrideURL: "https://localhost:46002", + Name: "invalidServerName", Hosts: []Host{ {Name: "localhost"}, }, @@ -1184,12 +1176,10 @@ func TestProcessHTTPRequestsByHost(t *testing.T) { }, { - srvAddr: "localhost:46003", reqConf: RequestConfig{ Name: "bodyRex", ResponseBodyMatchRegexp: "DemoHTTPSServer Handler - client output", PrintResponseBody: true, - TransportOverrideURL: "https://localhost:46003", Hosts: []Host{ {Name: "example.com"}, }, @@ -1389,9 +1379,7 @@ func runNewHTTPClientFromRequestConfigSubtest(t *testing.T, tt newHTTPClientFrom } type setTransportOverrideTestCase struct { - trasportURL string - transportAddr string - requestHost string + requestHost string } func runSetTransportOverrideSubtest(t *testing.T, tt setTransportOverrideTestCase) { @@ -1399,19 +1387,20 @@ func runSetTransportOverrideSubtest(t *testing.T, tt setTransportOverrideTestCas c := NewRequestHTTPClient() - _, err := c.SetTransportOverride(tt.trasportURL) + ts, err := NewHTTPSTestServer(demoHttpServerData{}) require.NoError(t, err) - assert.Equal(t, tt.transportAddr, c.transportAddress) - - fmt.Printf("c.transportAddress is %s\n", c.transportAddress) + t.Cleanup(ts.Close) - httpSrvData := demoHttpServerData{serverAddr: tt.transportAddr} + hostPort := testServerHostPort(ts) + transportURL := "https://" + hostPort - ts, err := NewHTTPSTestServer(httpSrvData) + _, err = c.SetTransportOverride(transportURL) require.NoError(t, err) - defer ts.Close() + assert.Equal(t, hostPort, c.transportAddress) + + fmt.Printf("c.transportAddress is %s\n", c.transportAddress) // Extract the transport via type assertion tr, ok := c.client.Transport.(*http.Transport) @@ -1448,7 +1437,7 @@ func runSetTransportOverrideSubtest(t *testing.T, tt setTransportOverrideTestCas type setProxyProtocolV2TestCase struct { testname string - addr string + listenHost string serverName string } @@ -1456,16 +1445,17 @@ func runSetProxyProtocolV2Subtest(t *testing.T, tt setProxyProtocolV2TestCase) { t.Parallel() httpSrvData := demoHttpServerData{ - serverAddr: tt.addr, + listenHost: tt.listenHost, proxyprotoEnabled: true, } ts, err := NewHTTPSTestServer(httpSrvData) require.NoError(t, err) - defer ts.Close() + t.Cleanup(ts.Close) - transportURL := "https://" + tt.addr + hostPort := testServerHostPort(ts) + transportURL := "https://" + hostPort reqURL := "https://" + tt.serverName reqConf := RequestConfig{ @@ -1513,7 +1503,6 @@ func runSetProxyProtocolV2Subtest(t *testing.T, tt setProxyProtocolV2TestCase) { type printResponseDebugTestCase struct { desc string - srvAddr string verbose bool outputs []string } @@ -1522,7 +1511,6 @@ func runPrintResponseDebugSubtest(t *testing.T, tt printResponseDebugTestCase) { t.Parallel() httpSrvData := demoHttpServerData{ - serverAddr: tt.srvAddr, proxyprotoEnabled: false, serverName: "localhost", } @@ -1530,7 +1518,7 @@ func runPrintResponseDebugSubtest(t *testing.T, tt printResponseDebugTestCase) { ts, err := NewHTTPSTestServer(httpSrvData) require.NoError(t, err) - defer ts.Close() + t.Cleanup(ts.Close) tr := &http.Transport{TLSClientConfig: &tls.Config{ RootCAs: caCertPool, @@ -1561,7 +1549,6 @@ func runPrintResponseDebugSubtest(t *testing.T, tt printResponseDebugTestCase) { } type processHTTPRequestsByHostTestCase struct { - srvAddr string reqConf RequestConfig pool *x509.CertPool verbose bool @@ -1570,9 +1557,9 @@ type processHTTPRequestsByHostTestCase struct { } func runProcessHTTPRequestsByHostSubtest(t *testing.T, tt processHTTPRequestsByHostTestCase) { - // t.Parallel() + t.Parallel() + httpSrvData := demoHttpServerData{ - serverAddr: tt.srvAddr, proxyprotoEnabled: false, serverName: "localhost", } @@ -1580,7 +1567,10 @@ func runProcessHTTPRequestsByHostSubtest(t *testing.T, tt processHTTPRequestsByH ts, err := NewHTTPSTestServer(httpSrvData) require.NoError(t, err) - defer ts.Close() + t.Cleanup(ts.Close) + + hostPort := testServerHostPort(ts) + tt.reqConf.TransportOverrideURL = "https://" + hostPort respList, err := processHTTPRequestsByHost( context.Background(), @@ -1593,17 +1583,22 @@ func runProcessHTTPRequestsByHostSubtest(t *testing.T, tt processHTTPRequestsByH t.Error(err) } - verifyProcessHTTPRequestsResults(t, tt, respList) + verifyProcessHTTPRequestsResults(t, tt, respList, hostPort) } -func verifyProcessHTTPRequestsResults(t *testing.T, tt processHTTPRequestsByHostTestCase, respList []ResponseData) { +func verifyProcessHTTPRequestsResults( + t *testing.T, + tt processHTTPRequestsByHostTestCase, + respList []ResponseData, + hostPort string, +) { t.Helper() for _, r := range respList { fmt.Printf("resp type: %T\n", r) assert.Equal(t, - tt.srvAddr, + hostPort, r.TransportAddress, "check TransportAddress", )