diff --git a/cmd/run.go b/cmd/run.go index 1447376..08ff28c 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -107,6 +107,7 @@ Latency Percentiles: u := config.ParsedTarget httpCfg := config.ToHTTPConfig() + httpCfg.Version = cmd.Root().Version if outputFormat != "json" { httpCfg.Stderr = cmd.ErrOrStderr() } diff --git a/internal/httpclient/client.go b/internal/httpclient/client.go index 53f853d..c3e363a 100644 --- a/internal/httpclient/client.go +++ b/internal/httpclient/client.go @@ -35,6 +35,7 @@ type Config struct { Body string Headers []string Verbose bool + Version string Stderr io.Writer } @@ -74,6 +75,10 @@ func MakeRequest(ctx context.Context, client HTTPDoer, cfg Config) (statusCode i } } + if req.Header.Get("User-Agent") == "" { + req.Header.Set("User-Agent", fmt.Sprintf("goperf/%s", cfg.Version)) + } + if cfg.Body != "" && req.Header.Get("Content-Type") == "" { req.Header.Set("Content-Type", "application/json") } diff --git a/internal/httpclient/client_test.go b/internal/httpclient/client_test.go index 104b84d..caf95ab 100644 --- a/internal/httpclient/client_test.go +++ b/internal/httpclient/client_test.go @@ -57,6 +57,54 @@ func TestMakeRequestSuccess(t *testing.T) { } } +func TestMakeRequest_DefaultUserAgent(t *testing.T) { + var gotUA string + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + gotUA = r.Header.Get("User-Agent") + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + + _, _, err := MakeRequest(context.Background(), &http.Client{}, Config{ + Target: server.URL, + Timeout: testTimeout, + Method: "GET", + Version: "1.2.3", + }) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + if gotUA != "goperf/1.2.3" { + t.Errorf("expected User-Agent 'goperf/1.2.3', got %q", gotUA) + } +} + +func TestMakeRequest_UserAgentOverride(t *testing.T) { + var gotUAValues []string + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + gotUAValues = r.Header.Values("User-Agent") + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + + _, _, err := MakeRequest(context.Background(), &http.Client{}, Config{ + Target: server.URL, + Timeout: testTimeout, + Method: "GET", + Version: "1.2.3", + Headers: []string{"User-Agent: custom-agent/9.9"}, + }) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + if len(gotUAValues) != 1 { + t.Errorf("expected exactly 1 User-Agent value (no duplicates), got %v", gotUAValues) + } + if gotUAValues[0] != "custom-agent/9.9" { + t.Errorf("expected User-Agent 'custom-agent/9.9', got %q", gotUAValues[0]) + } +} + func TestMakeRequest_Errors(t *testing.T) { tests := []struct { name string