Home  >  Article  >  Backend Development  >  How can I manually shut down an HTTP server after displaying the access token in Go?

How can I manually shut down an HTTP server after displaying the access token in Go?

Susan Sarandon
Susan SarandonOriginal
2024-11-01 03:07:28341browse

How can I manually shut down an HTTP server after displaying the access token in Go?

Manually Shutting Down HTTP Server After Displaying Access Token

To resolve the error encountered in shutting down the HTTP server, you can utilize the context.WithCancel function. This approach involves creating a context that can be canceled manually, allowing you to gracefully close the server.

<code class="go">package main

import (
    "context"
    "fmt"
    "io"
    "log"
    "net/http"
    "time"
)

var client_id = "my_client_id"
var client_secret = "my_client_secret"
var redirect_url = "http://localhost:8000/instagram/callback"

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    srv := startHttpServer(ctx)

    openbrowser(fmt.Sprintf("https://api.instagram.com/oauth/authorize/?client_id=%v&amp;redirect_uri=%v&amp;response_type=code&quot;, client_id, redirect_url))

    // Listen for context cancellation signals
    go func() {
        <-ctx.Done()

        // Gracefully shut down the server
        if err := srv.Shutdown(context.Background()); err != nil {
            panic(err) // failure/timeout shutting down the server gracefully
        }
    }()

    time.Sleep(20 * time.Second)
    cancel()
}

func showTokenToUser(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, fmt.Sprintf("Your access token is: %v", r.URL.Query().Get("code")))
}

func startHttpServer(ctx context.Context) *http.Server {
    srv := &http.Server{Addr: ":8000"}

    http.HandleFunc("/instagram/callback", showTokenToUser)
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Hello world!")
    })

    go func() {
        if err := srv.ListenAndServe(); err != http.ErrServerClosed {
            // cannot panic, because this probably is an intentional close
            log.Fatalf("Httpserver: ListenAndServe() error: %s", err)
        }
    }()

    // Return the server reference for use in shutting down
    return srv
}

func openbrowser(url string) {
    var err error

    switch runtime.GOOS {
    case "linux":
        err = exec.Command("xdg-open", url).Start()
    case "windows":
        err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start()
    case "darwin":
        err = exec.Command("open", url).Start()
    default:
        err = fmt.Errorf("unsupported platform")
    }
    if err != nil {
        log.Fatal(err)
    }
}</code>

This solution utilizes a separate goroutine to handle the context cancellation and graceful server shutdown. When the user accesses the /quit route, the context is canceled, which triggers the server shutdown process.

The above is the detailed content of How can I manually shut down an HTTP server after displaying the access token in Go?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn