Тип http.Request

Тип http.Request из пакета net/http представляет собой HTTP-запрос. Он используется как на стороне сервера для получения данных от клиента, так и на стороне клиента для формирования и отправки запросов. Структура содержит поля для метода запроса, URL, заголовков, тела, параметров формы, cookie и контекста.

При обработке запроса на сервере, структура http.Request передается в функцию-обработчик. На клиенте она создается с помощью функции http.NewRequest.

Создание запроса

Для создания нового запроса используется функция http.NewRequest. Она принимает метод, URL-строку и тело запроса:

gopackage main

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

func main() {
  body := []byte(`{"name":"John"}`)
  req, err := http.NewRequest("POST", "https://example.com/api", bytes.NewBuffer(body))
  if err != nil {
    fmt.Println("Error creating request")
    return
  }

  fmt.Println(req.Method)
  fmt.Println(req.URL.String())
}

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

go"POST"
"https://example.com/api"

В первом параметре передается метод запроса, во втором - URL-адрес, в третьем - тело запроса в виде io.Reader. Если тело не требуется, передается nil.

Поля структуры

Основные поля структуры http.Request:

Рассмотрим пример получения данных из запроса:

gopackage main

import (
  "fmt"
  "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
  fmt.Println("Method:", r.Method)
  fmt.Println("URL:", r.URL.String())
  fmt.Println("Content-Length:", r.ContentLength)
  fmt.Println("User-Agent:", r.Header.Get("User-Agent"))
}

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

При обращении к серверу по адресу localhost:8080, в консоль будет выведена информация о запросе:

go"Method: GET"
"URL: /"
"Content-Length: 0"
"User-Agent: curl/7.68.0"

Метод Header.Get позволяет получить значение конкретного заголовка по его имени.

Работа с параметрами формы

Для доступа к параметрам формы, переданным в запросе, необходимо вызвать метод ParseForm. После этого данные становятся доступны в поле Form (для всех параметров) и PostForm (только для POST-параметров):

gopackage main

import (
  "fmt"
  "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
  err := r.ParseForm()
  if err != nil {
    fmt.Println("Parse error")
    return
  }

  name := r.FormValue("name")
  age := r.FormValue("age")

  fmt.Println("Name:", name)
  fmt.Println("Age:", age)
}

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

При отправке POST-запроса с параметрами name=John&age=30, результат будет:

go"Name: John"
"Age: 30"

Метод FormValue возвращает значение первого параметра с указанным именем. Он автоматически вызывает ParseForm, если это еще не было сделано.

Работа с cookie

Для получения cookie из запроса используется метод Cookie, который возвращает cookie по имени, или метод Cookies, возвращающий все cookie:

gopackage main

import (
  "fmt"
  "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
  cookie, err := r.Cookie("session_id")
  if err != nil {
    fmt.Println("Cookie not found")
    return
  }

  fmt.Println("Session ID:", cookie.Value)

  allCookies := r.Cookies()
  fmt.Println("Total cookies:", len(allCookies))
}

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

Если cookie с именем session_id присутствует, результат будет:

go"Session ID: abc123xyz"
"Total cookies: 3"

В первом параметре метод Cookie принимает имя cookie, которое нужно получить. В случае отсутствия cookie возвращается ошибка.

Контекст запроса

Каждый запрос содержит контекст, который можно получить с помощью метода Context. Контекст используется для управления временем жизни запроса и передачи данных между обработчиками:

gopackage main

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

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

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

При отмене запроса клиентом (например, закрытии вкладки), в консоль будет выведено:

go"Request cancelled: context canceled"

Метод Context не принимает параметров и возвращает контекст запроса, который автоматически отменяется при завершении соединения.

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

  • тип http.Request.ParseForm,
    который разбирает параметры формы из запроса
  • тип http.Request.Cookie,
    который возвращает cookie по имени из запроса
  • тип http.Request.Context,
    который возвращает контекст запроса
  • функцию http.NewRequest,
    которая создает новый HTTP-запрос