Ari
Ari

Reputation: 6169

Shutdown web server after the request is handled - Go

I have a function that when run will give a user a URL to use to start an OAuth flow for a token exchange with my client.

I need to run a local HTTP server to accept the callback for the user. But I'm not sure how to then shutdown the HTTP server and close the function and move on once the flow is done.


func OAuth(request *OAuthRequest) {

    http.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte(`{"response": "unable to handle request"}`))

       // Do something

      // Finish up and shutdown HTTP server
    })

    err := http.ListenAndServe(net.JoinHostPort("","8080"), nil)
    if err != nil {
        log.Fatalln(err)
    }

    fmt.Println("Login at: www.example.com/123abc")

    // Wait for user to finish flow
   
}

  1. User calls .OAuth()
  2. Local server is started and exposes /callback
  3. User is given URL to use in browser
  4. Remote server sends callback to localhost/callback
  5. Local HTTP server handles response
  6. Job done, shutdown local HTTP server
  7. .OAuth() is complete

Upvotes: 2

Views: 711

Answers (1)

rustyx
rustyx

Reputation: 85371

You need to create the HTTP server via http.Server if you want to be able to shut it down:

package main

import (
    "context"
    "fmt"
    "net/http"
)

func main() {
    mux := http.NewServeMux()
    srv := http.Server{
        Addr:    "localhost:8080",
        Handler: mux,
    }
    mux.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte(`{"response": "unable to handle request"}`))
        go srv.Shutdown(context.Background())
    })

    fmt.Println("Login at: www.example.com/123abc")

    if err := srv.ListenAndServe(); err != http.ErrServerClosed {
        panic(err)
    }
}

Upvotes: 3

Related Questions