From 3413b178d85de9960892d23795e2ccd5d127f1c4 Mon Sep 17 00:00:00 2001 From: Kacper Sawicki Date: Wed, 4 Feb 2026 14:24:31 +0000 Subject: [PATCH] Validate CODER_URL scheme at startup Add validation to ensure CODER_URL includes http:// or https:// scheme. Go's url.Parse() accepts URLs without schemes, which causes silent runtime failures when the HTTP client attempts requests. This change makes the application fail fast with a clear error message instead of starting successfully and failing silently at runtime. --- main.go | 3 +++ main_test.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 main_test.go diff --git a/main.go b/main.go index ce425f8..4139a98 100644 --- a/main.go +++ b/main.go @@ -42,6 +42,9 @@ func root() *cobra.Command { if err != nil { return fmt.Errorf("parse coder URL: %w", err) } + if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" { + return fmt.Errorf("CODER_URL must include http:// or https:// scheme, got: %q", coderURL) + } if len(kubeConfig) > 0 && kubeConfig[0] == '~' { home, err := os.UserHomeDir() diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000..151cd56 --- /dev/null +++ b/main_test.go @@ -0,0 +1,50 @@ +package main + +import ( + "strings" + "testing" +) + +func TestRootCommand_URLValidation(t *testing.T) { + tests := []struct { + name string + coderURL string + wantError string + }{ + { + name: "missing scheme", + coderURL: "coder.example.com", + wantError: "CODER_URL must include http:// or https:// scheme", + }, + { + name: "empty scheme with path", + coderURL: "//coder.example.com", + wantError: "CODER_URL must include http:// or https:// scheme", + }, + { + name: "ftp scheme", + coderURL: "ftp://coder.example.com", + wantError: "CODER_URL must include http:// or https:// scheme", + }, + { + name: "empty URL", + coderURL: "", + wantError: "--coder-url is required", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd := root() + cmd.SetArgs([]string{"--coder-url", tt.coderURL}) + + err := cmd.Execute() + + if err == nil { + t.Errorf("expected error containing %q, got nil", tt.wantError) + } else if !strings.Contains(err.Error(), tt.wantError) { + t.Errorf("expected error containing %q, got %q", tt.wantError, err.Error()) + } + }) + } +}