Метод http.Request.Context

Метод http.Request.Context возвращает контекст, связанный с текущим HTTP-запросом. Контекст содержит информацию о времени выполнения запроса, а также может хранить пользовательские данные. Метод не принимает никаких параметров и возвращает значение типа context.Context.

Синтаксис

goctx := req.Context()

Пример 1

Давайте получим контекст запроса и выведем его значение:

gopackage main

import (
  "fmt"
  "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
  ctx := r.Context()
  fmt.Fprintf(w, "Context: %v", ctx)
}

func main() {
  http.HandleFunc("/", handler)
  http.ListenAndServe(":8080", nil)
}

Пример 2

Давайте проверим, завершен ли контекст запроса:

gopackage main

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

func handler(w http.ResponseWriter, r *http.Request) {
  ctx := r.Context()
  
  select {
  case <-ctx.Done():
    fmt.Fprintf(w, "Request cancelled")
  default:
    fmt.Fprintf(w, "Request is active")
  }
}

func main() {
  http.HandleFunc("/", handler)
  http.ListenAndServe(":8080", nil)
}

Пример 3

Давайте получим значение из контекста запроса:

gopackage main

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

type key string

const userIDKey key = "userID"

func handler(w http.ResponseWriter, r *http.Request) {
  ctx := context.WithValue(r.Context(), userIDKey, "12345")
  r = r.WithContext(ctx)
  
  userID := r.Context().Value(userIDKey)
  fmt.Fprintf(w, "User ID: %s", userID)
}

func main() {
  http.HandleFunc("/", handler)
  http.ListenAndServe(":8080", nil)
}

Пример 4

Давайте обработаем отмену контекста при получении сигнала:

gopackage main

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

func handler(w http.ResponseWriter, r *http.Request) {
  ctx := r.Context()
  
  select {
  case <-time.After(5 * time.Second):
    fmt.Fprintf(w, "Request completed")
  case <-ctx.Done():
    http.Error(w, "Request cancelled", http.StatusRequestTimeout)
  }
}

func main() {
  http.HandleFunc("/", handler)
  http.ListenAndServe(":8080", nil)
}

Результат выполнения кода:

go"Request completed"

Смотрите также

  • метод http.Request.WithContext,
    который создает копию запроса с новым контекстом
  • метод http.Request.Clone,
    который клонирует запрос с новым контекстом
  • метод http.NewRequest,
    который создает новый HTTP-запрос с контекстом по умолчанию
  • метод http.NewRequestWithContext,
    который создает новый HTTP-запрос с указанным контекстом