diff --git a/clientupdate/distsign/distsign.go b/clientupdate/distsign/distsign.go index b48321f8f..eba4b9267 100644 --- a/clientupdate/distsign/distsign.go +++ b/clientupdate/distsign/distsign.go @@ -57,6 +57,7 @@ import ( "golang.org/x/crypto/blake2s" "tailscale.com/net/tshttpproxy" "tailscale.com/types/logger" + "tailscale.com/util/httpm" "tailscale.com/util/must" ) @@ -335,7 +336,7 @@ func (c *Client) download(ctx context.Context, url, dst string, limit int64) ([] quickCtx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() - headReq := must.Get(http.NewRequestWithContext(quickCtx, http.MethodHead, url, nil)) + headReq := must.Get(http.NewRequestWithContext(quickCtx, httpm.HEAD, url, nil)) res, err := hc.Do(headReq) if err != nil { @@ -349,7 +350,7 @@ func (c *Client) download(ctx context.Context, url, dst string, limit int64) ([] } c.logf("Download size: %v", res.ContentLength) - dlReq := must.Get(http.NewRequestWithContext(ctx, http.MethodGet, url, nil)) + dlReq := must.Get(http.NewRequestWithContext(ctx, httpm.GET, url, nil)) dlRes, err := hc.Do(dlReq) if err != nil { return nil, 0, err diff --git a/ipn/ipnlocal/c2n.go b/ipn/ipnlocal/c2n.go index cae75df96..79fd66ee9 100644 --- a/ipn/ipnlocal/c2n.go +++ b/ipn/ipnlocal/c2n.go @@ -24,6 +24,7 @@ import ( "tailscale.com/tailcfg" "tailscale.com/util/clientmetric" "tailscale.com/util/goroutines" + "tailscale.com/util/httpm" "tailscale.com/version" ) @@ -41,9 +42,9 @@ func (b *LocalBackend) handleC2N(w http.ResponseWriter, r *http.Request) { w.Write(body) case "/update": switch r.Method { - case http.MethodGet: + case httpm.GET: b.handleC2NUpdateGet(w, r) - case http.MethodPost: + case httpm.POST: b.handleC2NUpdatePost(w, r) default: http.Error(w, "bad method", http.StatusMethodNotAllowed) diff --git a/ssh/tailssh/tailssh.go b/ssh/tailssh/tailssh.go index a4a024f8e..8dfb8a671 100644 --- a/ssh/tailssh/tailssh.go +++ b/ssh/tailssh/tailssh.go @@ -43,6 +43,7 @@ import ( "tailscale.com/types/logger" "tailscale.com/types/netmap" "tailscale.com/util/clientmetric" + "tailscale.com/util/httpm" "tailscale.com/util/mak" "tailscale.com/util/multierr" ) @@ -1752,7 +1753,7 @@ func (ss *sshSession) notifyControl(ctx context.Context, nodeKey key.NodePublic, return } - req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body)) + req, err := http.NewRequestWithContext(ctx, httpm.POST, url, bytes.NewReader(body)) if err != nil { ss.logf("notifyControl: unable to create request:", err) return diff --git a/util/httpm/httpm_test.go b/util/httpm/httpm_test.go new file mode 100644 index 000000000..77e6309c8 --- /dev/null +++ b/util/httpm/httpm_test.go @@ -0,0 +1,29 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package httpm + +import ( + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +func TestUsedConsistently(t *testing.T) { + cmd := exec.Command("git", "grep", "-l", "-F", "http.Method") + dir, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + cmd.Dir = filepath.Join(dir, "../..") + matches, _ := cmd.Output() + for _, fn := range strings.Split(strings.TrimSpace(string(matches)), "\n") { + switch fn { + case "util/httpm/httpm.go", "util/httpm/httpm_test.go": + continue + } + t.Errorf("http.MethodFoo constant used in %s; use httpm.FOO instead", fn) + } +}