diff --git a/cli.go b/cli.go index 29ae0ad..9203ae6 100644 --- a/cli.go +++ b/cli.go @@ -488,10 +488,15 @@ func RunCLI(args []string, stdout io.Writer, stderr io.Writer, options CLIOption } // Custom HTTP client. Used to disable TLS certificate verification. - transport := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - TLSClientConfig: tlsConfig, - } + // Clone keeps the defaults (proxy, timeouts, HTTP/2) without mutating the + // shared global. HTTP/2 matters: some servers, including TWNIC, reject + // HTTP/1.1 with 426 Upgrade Required. + transport := &http.Transport{Proxy: http.ProxyFromEnvironment, ForceAttemptHTTP2: true} + // Embedders may have replaced the global with a non-*http.Transport. + if t, ok := http.DefaultTransport.(*http.Transport); ok { + transport = t.Clone() + } + transport.TLSClientConfig = tlsConfig // Setup http.RoundTripper for http clients bs.HTTP = &http.Client{ diff --git a/cli_test.go b/cli_test.go index 05fd9e8..4444c7e 100644 --- a/cli_test.go +++ b/cli_test.go @@ -39,6 +39,47 @@ func fixtureServer(t *testing.T) *httptest.Server { return srv } +func http2FixtureServer(t *testing.T) *httptest.Server { + t.Helper() + + mux := http.NewServeMux() + mux.HandleFunc("/domain/example.cz", func(w http.ResponseWriter, r *http.Request) { + if r.ProtoMajor != 2 { + w.WriteHeader(http.StatusUpgradeRequired) + return + } + + w.Header().Set("Content-Type", "application/rdap+json") + _, _ = w.Write(test.LoadFile("rdap/rdap.nic.cz/domain-example.cz.json")) + }) + + srv := httptest.NewUnstartedServer(mux) + srv.EnableHTTP2 = true + srv.StartTLS() + t.Cleanup(srv.Close) + + return srv +} + +func TestRunCLIUsesHTTP2WhenTLSConfigIsCustomised(t *testing.T) { + srv := http2FixtureServer(t) + + var stdout, stderr bytes.Buffer + code := RunCLI([]string{ + "--insecure", + "--cache-dir", "", + "--server", srv.URL, + "example.cz", + }, &stdout, &stderr, CLIOptions{}) + + if code != 0 { + t.Fatalf("RunCLI() exit code = %d, want 0; stderr = %s", code, stderr.String()) + } + if !strings.Contains(stdout.String(), "Domain Name: example.cz") { + t.Errorf("RunCLI() output does not contain the decoded domain: %s", stdout.String()) + } +} + // TestRunCLIGolden drives RunCLI end-to-end for a range of commands and output // modes, comparing exit code, stdout, and stderr against committed golden files. // Network-backed cases point --server at an in-process fixture server and use an