Skip to content

Commit

Permalink
feat: /quitquitquit api now responds to HTTP GET and POST requests. (#…
Browse files Browse the repository at this point in the history
…1947)

The /quitquitquit endpoint used to return a 400 error when it received a request other than an HTTP POST. Now, it
will shut down the proxy if it receives either a GET or a POST request. This will make it possible for kubernetes
pod lifecycle handlers to gracefully signal the proxy to shut down.

Fixes #1946
  • Loading branch information
hessjcg committed Sep 14, 2023
1 parent 8e7b40f commit e5ebb48
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ func runSignalWrapper(cmd *Command) (err error) {

func quitquitquit(quitOnce *sync.Once, shutdownCh chan<- error) http.HandlerFunc {
return func(rw http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
if req.Method != http.MethodPost && req.Method != http.MethodGet {
rw.WriteHeader(400)
return
}
Expand Down
39 changes: 37 additions & 2 deletions cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1307,7 +1307,7 @@ func TestPProfServer(t *testing.T) {
}
}

func TestQuitQuitQuit(t *testing.T) {
func TestQuitQuitQuitHTTPPost(t *testing.T) {
c := NewCommand(WithDialer(&spyDialer{}))
c.SilenceUsage = true
c.SilenceErrors = true
Expand All @@ -1320,7 +1320,7 @@ func TestQuitQuitQuit(t *testing.T) {
err := c.ExecuteContext(ctx)
errCh <- err
}()
resp, err := tryDial("GET", "http://localhost:9192/quitquitquit")
resp, err := tryDial("HEAD", "http://localhost:9192/quitquitquit")
if err != nil {
t.Fatalf("failed to dial endpoint: %v", err)
}
Expand Down Expand Up @@ -1348,6 +1348,41 @@ func TestQuitQuitQuit(t *testing.T) {
}
}

func TestQuitQuitQuitHTTPGet(t *testing.T) {
c := NewCommand(WithDialer(&spyDialer{}))
c.SilenceUsage = true
c.SilenceErrors = true
c.SetArgs([]string{"--quitquitquit", "--admin-port", "9194", "my-project:my-region:my-instance"})
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

errCh := make(chan error)
go func() {
err := c.ExecuteContext(ctx)
errCh <- err
}()

resp, err := tryDial("GET", "http://localhost:9194/quitquitquit")
if err != nil {
t.Fatalf("failed to dial endpoint: %v", err)
}
if resp.StatusCode != http.StatusOK {
t.Fatalf("expected a 200 status, got = %v", resp.StatusCode)
}

var gotErr error
select {
case err := <-errCh:
gotErr = err
case <-time.After(30 * time.Second):
t.Fatal("timeout waiting for error")
}

if !errors.Is(gotErr, errQuitQuitQuit) {
t.Fatalf("want = %v, got = %v", errQuitQuitQuit, gotErr)
}
}

type errorDialer struct {
spyDialer
}
Expand Down

0 comments on commit e5ebb48

Please sign in to comment.