РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
1063 of 1593 menu

Интерфейс http.RoundTripper

Интерфейс http.RoundTripper определяет поведение объекта, который может выполнить HTTP-запрос и вернуть ответ. Он содержит один метод RoundTrip, который принимает указатель на http.Request и возвращает указатель на http.Response и ошибку. Этот интерфейс используется в http.Client для выполнения запросов через транспортный слой.

Синтаксис

type RoundTripper interface { RoundTrip(req *Request) (*Response, error) }

Метод RoundTrip выполняет запрос и возвращает ответ. Важно отметить, что он не должен обрабатывать ответ, например, читать его тело или закрывать его. Это задача вызывающего кода. Также метод не должен изменять переданный запрос.

Пример

Самой распространенной реализацией интерфейса является http.Transport. Давайте создадим транспорт с настройками и выполним запрос:

package main import ( "fmt" "io" "net/http" ) func main() { tr := &http.Transport{ MaxIdleConns: 10, IdleConnTimeout: 30, } client := &http.Client{Transport: tr} req, err := http.NewRequest("GET", "https://example.com", nil) if err != nil { fmt.Println(err) return } res, err := client.Do(req) if err != nil { fmt.Println(err) return } defer res.Body.Close() body, err := io.ReadAll(res.Body) if err != nil { fmt.Println(err) return } fmt.Printf("Status: %s\n", res.Status) fmt.Printf("Body length: %d bytes\n", len(body)) }

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

"Status: 200 OK" "Body length: 1256 bytes"

Пример

Давайте реализуем собственный тип, удовлетворяющий интерфейсу http.RoundTripper. Это полезно для логирования запросов или модификации ответов:

package main import ( "fmt" "io" "net/http" ) type LoggingRoundTripper struct { Transport http.RoundTripper } func (lrt *LoggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { fmt.Printf("Request: %s %s\n", req.Method, req.URL) res, err := lrt.Transport.RoundTrip(req) if err != nil { fmt.Printf("Error: %v\n", err) return nil, err } fmt.Printf("Response: %s\n", res.Status) return res, nil } func main() { baseTransport := &http.Transport{} loggingTransport := &LoggingRoundTripper{ Transport: baseTransport, } client := &http.Client{Transport: loggingTransport} req, err := http.NewRequest("GET", "https://example.com", nil) if err != nil { fmt.Println(err) return } res, err := client.Do(req) if err != nil { fmt.Println(err) return } defer res.Body.Close() _, err = io.ReadAll(res.Body) if err != nil { fmt.Println(err) return } }

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

"Request: GET https://example.com" "Response: 200 OK"

Пример

Также можно создать транспорт, который модифицирует запросы, например, добавляет заголовки:

package main import ( "fmt" "io" "net/http" ) type HeaderRoundTripper struct { Transport http.RoundTripper Headers map[string]string } func (hrt *HeaderRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { newReq := req.Clone(req.Context()) for key, val := range hrt.Headers { newReq.Header.Set(key, val) } return hrt.Transport.RoundTrip(newReq) } func main() { baseTransport := &http.Transport{} headerTransport := &HeaderRoundTripper{ Transport: baseTransport, Headers: map[string]string{ "User-Agent": "MyCustomClient/1.0", "X-Custom-Head": "test", }, } client := &http.Client{Transport: headerTransport} req, err := http.NewRequest("GET", "https://httpbin.org/headers", nil) if err != nil { fmt.Println(err) return } res, err := client.Do(req) if err != nil { fmt.Println(err) return } defer res.Body.Close() body, err := io.ReadAll(res.Body) if err != nil { fmt.Println(err) return } fmt.Println(string(body)) }

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

"{\n \"headers\": {\n \"Host\": \"httpbin.org\",\n \"User-Agent\": \"MyCustomClient/1.0\",\n \"X-Custom-Head\": \"test\"\n }\n}"

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

  • тип http.Transport,
    который является стандартной реализацией интерфейса
  • структуру http.Client,
    которая использует интерфейс для выполнения запросов
  • функцию http.NewRequest,
    которая создает новый HTTP-запрос
  • тип http.Request,
    который представляет HTTP-запрос
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить