Home  >  Article  >  Backend Development  >  How to Gracefully Shut Down an HTTP Server After a Response?

How to Gracefully Shut Down an HTTP Server After a Response?

Linda Hamilton
Linda HamiltonOriginal
2024-10-31 04:19:30498browse

How to Gracefully Shut Down an HTTP Server After a Response?

Gracefully Shutting Down HTTP Server After Response

Problem

When using a local HTTP server to capture OAuth access tokens for an Instagram API integration, the server needs to be shut down after the token is displayed to the user. However, attempting to manually terminate the server using srv.Shutdown() results in an error:

Httpserver: ListenAndServe() error: http: Server closed
http: panic serving [::1]:61793: runtime error: invalid memory address or nil pointer dereference

Analysis

The error occurs because the HTTP server is still handling other requests while the showTokenToUser handler is attempting to shut it down.

Solution

To gracefully shut down the HTTP server after completing the callback request:

1. Use Context.WithCancel()

Use context.WithCancel() to create a context that can be canceled manually. Pass this context to the HTTP server when starting it.

2. Gracefully Shut Down the Server

In the callback handler showTokenToUser, call srv.Shutdown(ctx) to gracefully shut down the server. ctx is the canceled context passed to the server.

Code

<code class="go">package main

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

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    http.HandleFunc("/instagram/callback", func(w http.ResponseWriter, r *http.Request) {
        showTokenToUser(w, r, ctx)
    })

    srv := &http.Server{Addr: ":8000"}
    go func() {
        if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
            log.Printf("httpserver: ListenAndServe() error: %s", err)
        }
    }()

    <-ctx.Done()

    // Gracefully shut down the server
    if err := srv.Shutdown(context.Background()); err != nil && err != context.Canceled {
        log.Println(err)
    }
}

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

This solution ensures that the HTTP server is gracefully shut down after the callback request is completed, without causing any errors or interrupting ongoing connections.

The above is the detailed content of How to Gracefully Shut Down an HTTP Server After a Response?. 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