Это многостраничный печатный вид этого раздела. Нажмите что бы печатать.

Вернуться к обычному просмотру страницы.

Пакет net/http встроенных функций и типов языка Go

Пакет http предоставляет реализации HTTP-клиента и сервера. Get, Head, Post и PostForm выполняют HTTP- (или HTTPS)-запросы.
resp, err := http.Get("http://example.com/")
...
resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
...
resp, err := http.PostForm("http://example.com/form",
	url.Values{"key": {"Value"}, "id": {"123"}})

Вызывающий абонент должен закрыть тело Resp, когда закончит с ним работать:

resp, err := http.Get("http://example.com/")
if err != nil {
	// handle error
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
// ...

Клиенты и транспорты (Clients and Transports)

Для управления HTTP-заголовками, политикой перенаправлений (redirects) и другими настройками клиента, создайте http.Client:

client := &http.Client{
    CheckRedirect: redirectPolicyFunc, // политика перенаправлений
}

resp, err := client.Get("http://example.com")
// ...

req, err := http.NewRequest("GET", "http://example.com", nil)
req.Header.Add("If-None-Match", `W/"wyzzy"`) // добавление кастомного заголовка
resp, err := client.Do(req)
// ...

Для более низкоуровневого контроля (прокси, TLS, keep-alive, сжатие и др.) настройте http.Transport:

tr := &http.Transport{
    MaxIdleConns:       10,               // макс. число бездействующих соединений
    IdleConnTimeout:    30 * time.Second, // таймаут для idle-соединений
    DisableCompression: true,             // отключение сжатия (gzip)
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://example.com")

Важно:

  • Client и Transport потокобезопасны (можно использовать в нескольких горутинах).
  • Их следует создавать один раз и переиспользовать для эффективности.

Серверы (Servers)

ListenAndServe запускает HTTP-сервер с указанным адресом и обработчиком (handler). Если handler = nil, используется DefaultServeMux:

http.Handle("/foo", fooHandler)  // регистрация обработчика для пути "/foo"

http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})

log.Fatal(http.ListenAndServe(":8080", nil)) // запуск сервера на :8080

Для тонкой настройки сервера создайте http.Server:

s := &http.Server{
    Addr:           ":8080",         // адрес сервера
    Handler:        myHandler,       // кастомный обработчик
    ReadTimeout:    10 * time.Second, // таймаут на чтение запроса
    WriteTimeout:   10 * time.Second, // таймаут на запись ответа
    MaxHeaderBytes: 1 << 20,         // макс. размер заголовков (1 MB)
}
log.Fatal(s.ListenAndServe())

Поддержка HTTP/2

С Go 1.6+ HTTP/2 поддерживается автоматически при использовании HTTPS.

Как отключить HTTP/2?

  • Для клиента: задать Transport.TLSNextProto = make(map[string]func(...)) (пустой map).
  • Для сервера: задать Server.TLSNextProto = make(map[string]func(...)).

Через переменную GODEBUG:

GODEBUG=http2client=0  # отключить HTTP/2 для клиентов  
GODEBUG=http2server=0  # отключить HTTP/2 для серверов  
GODEBUG=http2debug=1   # логировать отладочную информацию  
GODEBUG=http2debug=2   # расширенные логи (дампы фреймов)  

Перед отключением HTTP/2 сообщите о проблеме: golang.org/s/http2bug.

Расширенная настройка HTTP/2
Для сложных сценариев (например, ручная конфигурация HTTP/2) используйте пакет golang.org/x/net/http2:

import "golang.org/x/net/http2"

// Для клиента:
http2.ConfigureTransport(tr) // tr — ваш *http.Transport

// Для сервера:
http2.ConfigureServer(s, nil) // s — ваш *http.Server

Ручная настройка через golang.org/x/net/http2 имеет приоритет над встроенной поддержкой HTTP/2 в net/http.


Ключевые термины

  • DefaultServeMux – стандартный муксер (роутер) HTTP-запросов.
  • Transport – управление низкоуровневыми параметрами HTTP-соединений.
  • TLSNextProto – настройка протоколов, работающих поверх TLS (например, HTTP/2).
  • GODEBUG – переменная окружения для отладки поведения Go-программ.

Константы

const (
	MethodGet     = "GET"
	MethodHead    = "HEAD"
	MethodPost    = "POST"
	MethodPut     = "PUT"
	MethodPatch   = "PATCH" // RFC 5789
	MethodDelete  = "DELETE"
	MethodConnect = "CONNECT"
	MethodOptions = "OPTIONS"
	MethodTrace   = "TRACE"
)

Общие методы HTTP. Если не указано иное, они определены в разделе 4.3 RFC 7231.

const (
	StatusContinue           = 100 // RFC 9110, 15.2.1
	StatusSwitchingProtocols = 101 // RFC 9110, 15.2.2
	StatusProcessing         = 102 // RFC 2518, 10.1
	StatusEarlyHints         = 103 // RFC 8297

	StatusOK                   = 200 // RFC 9110, 15.3.1
	StatusCreated              = 201 // RFC 9110, 15.3.2
	StatusAccepted             = 202 // RFC 9110, 15.3.3
	StatusNonAuthoritativeInfo = 203 // RFC 9110, 15.3.4
	StatusNoContent            = 204 // RFC 9110, 15.3.5
	StatusResetContent         = 205 // RFC 9110, 15.3.6
	StatusPartialContent       = 206 // RFC 9110, 15.3.7
	StatusMultiStatus          = 207 // RFC 4918, 11.1
	StatusAlreadyReported      = 208 // RFC 5842, 7.1
	StatusIMUsed               = 226 // RFC 3229, 10.4.1

	StatusMultipleChoices  = 300 // RFC 9110, 15.4.1
	StatusMovedPermanently = 301 // RFC 9110, 15.4.2
	StatusFound            = 302 // RFC 9110, 15.4.3
	StatusSeeOther         = 303 // RFC 9110, 15.4.4
	StatusNotModified      = 304 // RFC 9110, 15.4.5
	StatusUseProxy         = 305 // RFC 9110, 15.4.6

	StatusTemporaryRedirect = 307 // RFC 9110, 15.4.8
	StatusPermanentRedirect = 308 // RFC 9110, 15.4.9

	StatusBadRequest                   = 400 // RFC 9110, 15.5.1
	StatusUnauthorized                 = 401 // RFC 9110, 15.5.2
	StatusPaymentRequired              = 402 // RFC 9110, 15.5.3
	StatusForbidden                    = 403 // RFC 9110, 15.5.4
	StatusNotFound                     = 404 // RFC 9110, 15.5.5
	StatusMethodNotAllowed             = 405 // RFC 9110, 15.5.6
	StatusNotAcceptable                = 406 // RFC 9110, 15.5.7
	StatusProxyAuthRequired            = 407 // RFC 9110, 15.5.8
	StatusRequestTimeout               = 408 // RFC 9110, 15.5.9
	StatusConflict                     = 409 // RFC 9110, 15.5.10
	StatusGone                         = 410 // RFC 9110, 15.5.11
	StatusLengthRequired               = 411 // RFC 9110, 15.5.12
	StatusPreconditionFailed           = 412 // RFC 9110, 15.5.13
	StatusRequestEntityTooLarge        = 413 // RFC 9110, 15.5.14
	StatusRequestURITooLong            = 414 // RFC 9110, 15.5.15
	StatusUnsupportedMediaType         = 415 // RFC 9110, 15.5.16
	StatusRequestedRangeNotSatisfiable = 416 // RFC 9110, 15.5.17
	StatusExpectationFailed            = 417 // RFC 9110, 15.5.18
	StatusTeapot                       = 418 // RFC 9110, 15.5.19 (Unused)
	StatusMisdirectedRequest           = 421 // RFC 9110, 15.5.20
	StatusUnprocessableEntity          = 422 // RFC 9110, 15.5.21
	StatusLocked                       = 423 // RFC 4918, 11.3
	StatusFailedDependency             = 424 // RFC 4918, 11.4
	StatusTooEarly                     = 425 // RFC 8470, 5.2.
	StatusUpgradeRequired              = 426 // RFC 9110, 15.5.22
	StatusPreconditionRequired         = 428 // RFC 6585, 3
	StatusTooManyRequests              = 429 // RFC 6585, 4
	StatusRequestHeaderFieldsTooLarge  = 431 // RFC 6585, 5
	StatusUnavailableForLegalReasons   = 451 // RFC 7725, 3

	StatusInternalServerError           = 500 // RFC 9110, 15.6.1
	StatusNotImplemented                = 501 // RFC 9110, 15.6.2
	StatusBadGateway                    = 502 // RFC 9110, 15.6.3
	StatusServiceUnavailable            = 503 // RFC 9110, 15.6.4
	StatusGatewayTimeout                = 504 // RFC 9110, 15.6.5
	StatusHTTPVersionNotSupported       = 505 // RFC 9110, 15.6.6
	StatusVariantAlsoNegotiates         = 506 // RFC 2295, 8.1
	StatusInsufficientStorage           = 507 // RFC 4918, 11.5
	StatusLoopDetected                  = 508 // RFC 5842, 7.2
	StatusNotExtended                   = 510 // RFC 2774, 7
	StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6
)

HTTP коды состояния (HTTP status codes)

Коды состояния HTTP зарегистрированы в IANA. См.: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml

Константы

const DefaultMaxHeaderBytes = 1 << 20 // 1 МБ

DefaultMaxHeaderBytes - максимально допустимый размер заголовков в HTTP-запросе. Можно переопределить через [Server.MaxHeaderBytes].

const DefaultMaxIdleConnsPerHost = 2

DefaultMaxIdleConnsPerHost - значение по умолчанию для Transport.MaxIdleConnsPerHost.

const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"

TimeFormat - формат времени для генерации временных меток в HTTP-заголовках. Аналогичен time.RFC1123, но использует GMT. Время должно быть в UTC.

const TrailerPrefix = "Trailer:"

TrailerPrefix - префикс для ключей [ResponseWriter.Header], указывающий, что значение относится к трейлерам ответа, а не к заголовкам.

Переменные

var (
    ErrNotSupported = &ProtocolError{"feature not supported"}
    ErrMissingBoundary = &ProtocolError{"no multipart boundary param in Content-Type"}
    ErrNotMultipart = &ProtocolError{"request Content-Type isn't multipart/form-data"}
    // Устаревшие ошибки...
)
var (
    ErrBodyNotAllowed = errors.New("http: request method or response status code does not allow body")
    ErrHijacked = errors.New("http: connection has been hijacked")
    ErrContentLength = errors.New("http: wrote more than the declared Content-Length")
    // Устаревшие ошибки...
)

Ошибки, используемые HTTP-сервером.

var (
    ServerContextKey = &contextKey{"http-server"}
    LocalAddrContextKey = &contextKey{"local-addr"}
)

Ключи контекста для доступа к серверу и локальному адресу.

var DefaultClient = &Client{}

DefaultClient - клиент по умолчанию, используемый Get, Head и Post.

var DefaultServeMux = &defaultServeMux

DefaultServeMux - ServeMux по умолчанию, используемый Serve.

var ErrAbortHandler = errors.New("net/http: abort Handler")

ErrAbortHandler - значение для прерывания обработчика без логирования стека.

var ErrBodyReadAfterClose = errors.New("http: invalid Read on closed Body")

Ошибка при чтении закрытого тела запроса/ответа.

var NoBody = noBody{}

NoBody - пустое тело запроса (io.ReadCloser), всегда возвращает EOF.

1 - Функции пакета net/http языка Go

Функции пакета http для реализации HTTP-клиента и сервера.

func CanonicalHeaderKey

func CanonicalHeaderKey(s string) string

CanonicalHeaderKey возвращает канонический формат заголовка. Преобразует первую букву и буквы после дефиса в верхний регистр, остальные - в нижний. Например, “accept-encoding” → “Accept-Encoding”. Если s содержит пробелы или недопустимые символы, возвращается без изменений.

func DetectContentType

func DetectContentType(data []byte) string

DetectContentType определяет Content-Type данных по алгоритму https://mimesniff.spec.whatwg.org/. Анализирует первые 512 байт. Всегда возвращает валидный MIME-тип, по умолчанию “application/octet-stream”.

func Error

func Error(w ResponseWriter, error string, code int)

Error отправляет ответ с указанным HTTP-кодом и текстом ошибки. Устанавливает заголовки:

  • Удаляет Content-Length
  • Content-Type: “text/plain; charset=utf-8”
  • X-Content-Type-Options: “nosniff”

func Handle

func Handle(pattern string, handler Handler)

Регистрирует обработчик для шаблона в DefaultServeMux.

Пример
package main

import (
	"fmt"
	"log"
	"net/http"
	"sync"
)

type countHandler struct {
	mu sync.Mutex // guards n
	n  int
}

func (h *countHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h.mu.Lock()
	defer h.mu.Unlock()
	h.n++
	fmt.Fprintf(w, "count is %d\n", h.n)
}

func main() {
	http.Handle("/count", new(countHandler))
	log.Fatal(http.ListenAndServe(":8080", nil))
}

func HandleFunc

func HandleFunc(pattern string, handler func(ResponseWriter, *Request))

Регистрирует функцию-обработчик для шаблона в DefaultServeMux.

Пример
package main

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

func main() {
	h1 := func(w http.ResponseWriter, _ *http.Request) {
		io.WriteString(w, "Hello from a HandleFunc #1!\n")
	}
	h2 := func(w http.ResponseWriter, _ *http.Request) {
		io.WriteString(w, "Hello from a HandleFunc #2!\n")
	}

	http.HandleFunc("/", h1)
	http.HandleFunc("/endpoint", h2)

	log.Fatal(http.ListenAndServe(":8080", nil))
}

func ListenAndServe

func ListenAndServe(addr string, handler Handler) error

Запускает HTTP-сервер на указанном адресе. Если handler=nil, используется DefaultServeMux.

Пример
package main

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

func main() {
	// Hello world, the web server

	helloHandler := func(w http.ResponseWriter, req *http.Request) {
		io.WriteString(w, "Hello, world!\n")
	}

	http.HandleFunc("/hello", helloHandler)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

func ListenAndServeTLS

func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error

Аналогично ListenAndServe, но для HTTPS-соединений. Требует сертификат и приватный ключ.

Пример
package main

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

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		io.WriteString(w, "Hello, TLS!\n")
	})

	// One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
	log.Printf("About to listen on 8443. Go to https://127.0.0.1:8443/")
	err := http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", nil)
	log.Fatal(err)
}

func MaxBytesReader

func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser

Ограничивает размер тела запроса. В отличие от io.LimitReader:

  • Возвращает ReadCloser
  • При превышении лимита возвращает ошибку *MaxBytesError
  • Закрывает исходный reader при вызове Close

func NotFound

func NotFound(w ResponseWriter, r *Request)

Отправляет ответ с HTTP 404.

func ParseHTTPVersion

func ParseHTTPVersion(vers string) (major, minor int, ok bool)

Разбирает строку версии HTTP (например, “HTTP/1.1” → (1, 1, true)).

func ParseTime

func ParseTime(text string) (t time.Time, err error)

Разбирает временную метку из заголовка, поддерживая три формата: TimeFormat, RFC850 и ANSIC.

func ProxyFromEnvironment

func ProxyFromEnvironment(req *Request) (*url.URL, error)

ProxyFromEnvironment возвращает URL прокси-сервера для указанного запроса на основе переменных окружения:

  • HTTP_PROXY/https_proxy - для HTTP-запросов
  • HTTPS_PROXY/https_proxy - для HTTPS-запросов
  • NO_PROXY/no_proxy - исключения из проксирования

Форматы значений:

  • Полный URL (http://proxy.example.com:8080)
  • host:port (подразумевается схема http)

Возвращаемые значения:

  • Если прокси не задан или запрос исключен через NO_PROXYnil, nil
  • При некорректном формате → ошибка
  • Для localhost (с портом или без) → nil, nil (специальный случай)

Примеры использования:

proxyUrl, err := http.ProxyFromEnvironment(req)
if err != nil {
    // обработка ошибки конфигурации прокси
}
if proxyUrl != nil {
    // настроить транспорт с этим прокси
}

Особенности:

  1. Автоматически выбирает переменную окружения по схеме запроса
  2. Учитывает исключения в NO_PROXY
  3. Всегда пропускает запросы к localhost
  4. Поддерживает оба регистра переменных (UPPER и lower case)

func ProxyURL

func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error)

Возвращает функцию прокси, всегда возвращающую указанный URL.

func Redirect

func Redirect(w ResponseWriter, r *Request, url string, code int)

Перенаправляет запрос на указанный URL (может быть относительным путем). Код ответа должен быть в диапазоне 3xx (обычно 301, 302 или 303). Если Content-Type не установлен, автоматически добавляет “text/html; charset=utf-8” и простой HTML-ответ. Установка любого значения Content-Type отключает это поведение.

func Serve

func Serve(l net.Listener, handler Handler) error

Принимает входящие HTTP-соединения через listener, создавая новую горутину для каждого соединения. Если handler=nil, используется DefaultServeMux. Поддержка HTTP/2 требует TLS-соединений с “h2” в Config.NextProtos. Всегда возвращает non-nil ошибку.

func ServeContent

func ServeContent(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker)

Отвечает на запрос содержимым из ReadSeeker с поддержкой:

  • Range-запросов
  • Заголовков If-Match/If-None-Match
  • If-Modified-Since/If-Unmodified-Since

Автоматически определяет Content-Type (по расширению файла или через DetectContentType). Использует modtime для Last-Modified и проверки If-Modified-Since. Требует работающий Seek() для определения размера.

func ServeFile

func ServeFile(w ResponseWriter, r *Request, name string)

Отправляет содержимое файла или директории. Особенности:

  • Отклоняет пути с “..” (защита от traversal-атак)
  • Перенаправляет запросы к “/index.html” на родительский каталог
  • Использует только параметр name (игнорирует r.URL.Path)
  • Относительные пути разрешаются от текущего каталога

func ServeFileFS

func ServeFileFS(w ResponseWriter, r *Request, fsys fs.FS, name string)

Отправляет содержимое указанного файла или директории из файловой системы fsys в ответ на запрос. Файлы в fsys должны реализовывать интерфейс io.Seeker.

Меры предосторожности:

  1. Если имя (name) формируется из пользовательского ввода, его необходимо санировать перед вызовом
  2. Автоматически отклоняет запросы с “..” в r.URL.Path (защита от path traversal)
  3. Специальный случай: перенаправляет запросы, оканчивающиеся на “/index.html”, на путь без этого суффикса

Важно: выбор файла/директории осуществляется только по параметру name, r.URL.Path игнорируется (кроме двух указанных случаев).

func ServeTLS

func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error

Принимает входящие HTTPS-соединения через listener l, создавая новую горутину для обработки каждого соединения. Требования:

  • Если handler не указан (nil), используется DefaultServeMux
  • Необходимо указать файлы сертификата (certFile) и приватного ключа (keyFile)
  • Для цепочки сертификатов certFile должен содержать: серверный сертификат, промежуточные и корневой CA

Особенности:

  • Всегда возвращает non-nil ошибку
  • Для корректной работы требуется правильная настройка TLS

Технические детали:

  1. Для ServeFileFS:

    • Работает с абстрактной файловой системой (fs.FS)
    • Требуется поддержка Seek() для обработки Range-запросов
    • Поведение с “index.html” аналогично классическим веб-серверам
  2. Для ServeTLS:

    • Автоматически активирует HTTP/2 при поддержке
    • Рекомендуется использовать современные параметры шифрования
    • Для production-среды следует использовать полную цепочку сертификатов

func SetCookie

func SetCookie(w ResponseWriter, cookie *Cookie)

Добавляет Set-Cookie заголовок в ответ. Некорректные cookie могут игнорироваться.

func StatusText

func StatusText(code int) string

Возвращает текстовое описание HTTP-статуса. Для неизвестных кодов возвращает пустую строку.

2 - Типы пакета net/http языка Go

Типы и методы пакета http для реализации HTTP-клиента и сервера.

type Client

type Client struct {
    // Transport определяет механизм выполнения HTTP-запросов.
    // Если nil, используется DefaultTransport.
    Transport RoundTripper

    // CheckRedirect определяет политику обработки редиректов.
    // Если задан, вызывается перед каждым редиректом.
    // Принимает новый запрос (req) и цепочку выполненных запросов (via).
    // Если возвращает ошибку, клиент прекращает выполнение.
    // Особый случай: ErrUseLastResponse возвращает последний Response без закрытия тела.
    // Если nil, используется политика по умолчанию (максимум 10 редиректов).
    CheckRedirect func(req *Request, via []*Request) error

    // Jar хранит куки для автоматической подстановки в запросы.
    // Обновляется при получении ответов с Set-Cookie.
    // Если nil, куки отправляются только если явно заданы в Request.
    Jar CookieJar

    // Timeout устанавливает общий таймаут для запроса:
    // включает подключение, редиректы и чтение тела ответа.
    // Таймер продолжает работать после вызова Get/Post/Do.
    // Нулевое значение отключает таймаут.
    // Для отмены используется контекст запроса.
    Timeout time.Duration
}

Client представляет HTTP-клиент. Нулевое значение (DefaultClient) - готовый к использованию клиент с DefaultTransport.

Особенности реализации:

  1. Transport обычно содержит состояние (кешированные TCP-соединения), поэтому клиенты должны переиспользоваться
  2. Потокобезопасен для использования из нескольких горутин
  3. Работает на более высоком уровне, чем RoundTripper, обрабатывая:
    • Куки (через Jar)
    • Редиректы (через CheckRedirect)
    • Таймауты

Политика редиректов:

При перенаправлениях клиент:

  1. Не пересылает sensitive-заголовки (Authorization, WWW-Authenticate, Cookie) на:
    • Домены, не являющиеся поддоменами исходного (с foo.com на bar.com)
  2. Особенности Cookie:
    • При наличии Jar: мутировавшие куки исключаются (Jar сам добавит обновленные)
    • Без Jar: исходные куки пересылаются без изменений

Пример использования:

client := &http.Client{
    Timeout: 10 * time.Second,
    Jar:     cookieJar,
}
resp, err := client.Get("https://example.com")

func (*Client) CloseIdleConnections

(добавлено в Go 1.12)

func (c *Client) CloseIdleConnections()

Закрывает все бездействующие keep-alive соединения в Transport. Не прерывает активные соединения. Если Transport не поддерживает этот метод, операция не выполняется.

func (*Client) Do

func (c *Client) Do(req *Request) (*Response, error)

Выполняет HTTP-запрос с учетом настроек клиента (редиректы, куки, аутентификация). Особенности:

  • Возвращает ошибку только при проблемах сети или срабатывании политик (CheckRedirect)
  • Не считает HTTP-коды ≠ 2xx ошибкой
  • Тело ответа (Body) всегда требует закрытия, даже при ошибках
  • При редиректах:
    • 301/302/303 → GET/HEAD (тело не сохраняется)
    • 307/308 → сохраняет метод и тело (если определен Request.GetBody)
  • Ошибки имеют тип *url.Error с флагом Timeout()

Пример:

req, _ := http.NewRequest("GET", url, nil)
resp, err := client.Do(req)
if err != nil { /* обработка */ }
defer resp.Body.Close()

func (*Client) Get

func (c *Client) Get(url string) (*Response, error)

Выполняет GET-запрос с автоматическим следованием редиректам (301, 302, 303, 307, 308). Особенности:

  • Не возвращает ошибку при кодах ≠ 2xx
  • Тело ответа требует закрытия
  • Для кастомных заголовков используйте NewRequest + Do

func (*Client) Head

func (c *Client) Head(url string) (*Response, error)

Аналогично Get, но отправляет HEAD-запрос. Также обрабатывает редиректы.

func (*Client) Post

func (c *Client) Post(url, contentType string, body io.Reader) (*Response, error)

Выполняет POST-запрос с указанным Content-Type. Особенности:

  • Если body реализует io.Closer, оно закрывается автоматически
  • Для сложных запросов используйте NewRequest + Do

func (*Client) PostForm

func (c *Client) PostForm(url string, data url.Values) (*Response, error)

Отправляет POST с x-www-form-urlencoded данными. Автоматически:

  • Кодирует данные
  • Устанавливает Content-Type
  • Обрабатывает редиректы

type ConnState

type ConnState int

ConnState представляет состояние клиентского соединения с сервером. Используется в хуке Server.ConnState для отслеживания жизненного цикла соединений.

Состояния соединения:

const (
    // StateNew - новое соединение, ожидается отправка запроса
    StateNew ConnState = iota
    
    // StateActive - соединение получило данные запроса (1+ байт)
    StateActive
    
    // StateIdle - соединение в режиме keep-alive между запросами
    StateIdle
    
    // StateHijacked - соединение было захвачено (hijacked)
    StateHijacked
    
    // StateClosed - соединение закрыто
    StateClosed
)

Особенности:

  1. Для HTTP/2:

    • StateActive активируется при переходе от 0 к 1 активному запросу
    • Переход в другое состояние только после завершения всех запросов
  2. Терминальные состояния:

    • StateHijacked - не переходит в StateClosed
    • StateClosed - конечное состояние

func (ConnState) String

func (c ConnState) String() string

Возвращает строковое представление состояния соединения.

Примеры использования:

  1. Базовый мониторинг соединений:
server := &http.Server{
    ConnState: func(conn net.Conn, state http.ConnState) {
        log.Printf("Соединение %v: %v -> %v", 
            conn.RemoteAddr(), 
            conn.LocalAddr(), 
            state.String())
    },
}
  1. Ограничение активных соединений:
var activeConns int32

server := &http.Server{
    ConnState: func(conn net.Conn, state http.ConnState) {
        switch state {
        case http.StateActive:
            if atomic.AddInt32(&activeConns, 1) > 100 {
                conn.Close() // закрываем при превышении лимита
            }
        case http.StateClosed, http.StateHijacked:
            atomic.AddInt32(&activeConns, -1)
        }
    },
}
  1. Логирование времени жизни соединения:
type connInfo struct {
    start time.Time
}

server := &http.Server{
    ConnState: func(conn net.Conn, state http.ConnState) {
        ctx := conn.Context()
        if state == http.StateNew {
            ctx = context.WithValue(ctx, "connInfo", &connInfo{
                start: time.Now(),
            })
            conn = conn.WithContext(ctx)
            return
        }
        
        if state == http.StateClosed {
            if info, ok := ctx.Value("connInfo").(*connInfo); ok {
                duration := time.Since(info.start)
                log.Printf("Соединение жило %v", duration)
            }
        }
    },
}

Типичный жизненный цикл соединения:

StateNew → StateActive → StateIdle → StateActive → ... → StateClosed
                    \           /
                     → StateHijacked

Для HTTP/2 состояния меняются реже, так как одно соединение обслуживает множество запросов параллельно.

Вот профессиональный перевод документации типа Cookie с примерами использования:

type Cookie struct {
    Name   string    // Название cookie (обязательное)
    Value  string    // Значение cookie
    Quoted bool      // Флаг, было ли значение в кавычках

    // Опциональные атрибуты:
    Path       string    // Путь действия cookie
    Domain     string    // Домен действия
    Expires    time.Time // Время истечения
    RawExpires string    // Оригинальное значение Expires (только для чтения)

    // MaxAge определяет срок жизни в секундах:
    //  0 - без Max-Age
    // <0 - немедленное удаление (аналог Max-Age: 0)
    // >0 - срок жизни в секундах
    MaxAge      int
    Secure      bool     // Только для HTTPS
    HttpOnly    bool     // Недоступно для JavaScript
    SameSite    SameSite // Политика SameSite
    Partitioned bool     // Разделенные cookie (CHIPS)
    Raw         string   // Оригинальное значение заголовка
    Unparsed    []string // Неразобранные атрибуты
}

Тип Cookie представляет HTTP-куки, используемые в заголовках:

  • Set-Cookie - при установке сервером
  • Cookie - при отправке клиентом

Соответствует спецификации RFC 6265.

// Простая cookie
sessionCookie := &http.Cookie{
    Name:  "session_id",
    Value: "abc123",
}

// Защищенная cookie с атрибутами
secureCookie := &http.Cookie{
    Name:     "prefs",
    Value:    "dark_theme=true",
    Path:     "/",
    Domain:   "example.com",
    MaxAge:   3600, // 1 час
    Secure:   true,
    HttpOnly: true,
    SameSite: http.SameSiteLaxMode,
}

func ParseCookie

(добавлено в Go 1.23)

func ParseCookie(line string) ([]*Cookie, error)

Разбирает заголовок Cookie (клиентские куки), возвращая все найденные куки. Одно имя может встречаться несколько раз.

Пример:

cookies, err := http.ParseCookie("name1=val1; name2=val2; name1=val3")
if err != nil { /* обработка ошибки */ }
for _, c := range cookies {
    fmt.Printf("%s: %s\n", c.Name, c.Value)
}
// Вывод:
// name1: val1
// name2: val2
// name1: val3

func ParseSetCookie

(добавлено в Go 1.23)

func ParseSetCookie(line string) (*Cookie, error)

Разбирает заголовок Set-Cookie (серверные куки), возвращая одну куку.

Пример:

cookie, err := http.ParseSetCookie("session=abc123; Path=/; HttpOnly; Max-Age=3600")
if err != nil { /* обработка ошибки */ }
fmt.Printf("Cookie: %s=%s, Path=%s\n", cookie.Name, cookie.Value, cookie.Path)
func (c *Cookie) String() string

Форматирует куку для заголовка:

  • Для Cookie: только имя и значение (name=value)
  • Для Set-Cookie: со всеми атрибутами

Пример:

c := &http.Cookie{Name: "test", Value: "123"}
fmt.Println(c.String()) // "test=123"

c.Path = "/"
c.HttpOnly = true
fmt.Println(c.String()) // "test=123; Path=/; HttpOnly"
func (c *Cookie) Valid() error

Проверяет валидность куки (корректность имени и других атрибутов).

Пример:

err := (&http.Cookie{Name: "invalid name", Value: "test"}).Valid()
if err != nil {
    fmt.Println("Invalid cookie:", err)
}

Практические примеры:

  1. Установка cookie в ResponseWriter:
func handler(w http.ResponseWriter, r *http.Request) {
    cookie := &http.Cookie{
        Name:  "user",
        Value: "john",
        Path:  "/",
    }
    http.SetCookie(w, cookie)
}
  1. Чтение cookie из Request:
func handler(w http.ResponseWriter, r *http.Request) {
    cookie, err := r.Cookie("session_id")
    if err != nil {
        // Обработка отсутствия cookie
    }
    fmt.Fprintf(w, "Value: %s", cookie.Value)
}
  1. Удаление cookie:
func logoutHandler(w http.ResponseWriter, r *http.Request) {
    http.SetCookie(w, &http.Cookie{
        Name:   "session",
        Value:  "",
        Path:   "/",
        MaxAge: -1, // Удалить cookie
    })
}
  1. Проверка SameSite политики:
cookie := &http.Cookie{
    Name:     "csrf_token",
    Value:    generateToken(),
    SameSite: http.SameSiteStrictMode,
    Secure:   true,
}

Вот перевод документации с примерами:

type CookieJar

type CookieJar interface {
    // SetCookies сохраняет полученные куки для указанного URL
    SetCookies(u *url.URL, cookies []*Cookie)
    
    // Cookies возвращает куки, которые должны быть отправлены для URL
    Cookies(u *url.URL) []*Cookie
}

CookieJar управляет хранением и использованием кук в HTTP-запросах. Реализации должны быть потокобезопасными.

Пример использования:

jar, _ := cookiejar.New(nil)
client := &http.Client{
    Jar: jar,
}

// Первый запрос (получаем куки)
resp, _ := client.Get("https://example.com/login")

// Последующие запросы автоматически включают куки
resp, _ = client.Get("https://example.com/dashboard")

type Dir

type Dir string

Dir реализует FileSystem для работы с файловой системой в пределах указанной директории.

Важные предупреждения:

  1. Может предоставлять доступ к чувствительным файлам
  2. Следует по символическим ссылкам за пределы директории
  3. Не фильтрует файлы, начинающиеся с точки (например, .git)

Пример:

fs := http.Dir("/var/www")
http.Handle("/static/", http.FileServer(fs))

func (Dir) Open

func (d Dir) Open(name string) (File, error)

Открывает файл для чтения, используя os.Open. Пути должны использовать / как разделитель.

Пример:

fs := http.Dir("public")
file, err := fs.Open("css/styles.css")
if err != nil {
    // обработка ошибки
}
defer file.Close()

type File

type File interface {
    io.Closer
    io.Reader
    io.Seeker
    Readdir(count int) ([]fs.FileInfo, error)
    Stat() (fs.FileInfo, error)
}

Интерфейс файла, возвращаемый FileSystem.Open. Аналогичен *os.File.

type FileSystem

type FileSystem interface {
    Open(name string) (File, error)
}

Интерфейс для работы с коллекцией файлов. Использует / как разделитель путей.

Пример реализации:

type CustomFS struct {
    base string
}

func (c CustomFS) Open(name string) (http.File, error) {
    return os.Open(filepath.Join(c.base, name))
}

func FS

func FS(fsys fs.FS) FileSystem

Конвертирует fs.FS в FileSystem. Файлы должны реализовывать io.Seeker.

Пример с embed:

//go:embed static/*
var staticFiles embed.FS

func main() {
    http.Handle("/", http.FileServer(http.FS(staticFiles)))
    http.ListenAndServe(":8080", nil)
}

Дополнительные примеры:

  1. Защищенная FileSystem (без доступа к скрытым файлам):
type SafeFS struct {
    http.Dir
}

func (s SafeFS) Open(name string) (http.File, error) {
    if strings.Contains(name, "..") || strings.HasPrefix(filepath.Base(name), ".") {
        return nil, os.ErrNotExist
    }
    return s.Dir.Open(name)
}
  1. Кастомный CookieJar:
type MemoryJar struct {
    cookies map[string][]*http.Cookie
    sync.Mutex
}

func (j *MemoryJar) SetCookies(u *url.URL, cookies []*http.Cookie) {
    j.Lock()
    defer j.Unlock()
    j.cookies[u.Host] = cookies
}

func (j *MemoryJar) Cookies(u *url.URL) []*http.Cookie {
    j.Lock()
    defer j.Unlock()
    return j.cookies[u.Host]
}

type Flusher

type Flusher interface {
	// Flush sends any buffered data to the client.
	Flush()
}

Интерфейс Flusher реализуется в ResponseWriter, которые позволяют HTTP-обработчику отправлять буферизованные данные клиенту.

Реализации ResponseWriter по умолчанию HTTP/1.x и HTTP/2 поддерживают Flusher, но обертки ResponseWriter могут этого не делать. Обработчики всегда должны проверять эту возможность во время выполнения.

Обратите внимание, что даже для ResponseWriter, поддерживающих Flush, если клиент подключен через HTTP-прокси, буферизованные данные могут не дойти до клиента до завершения ответа.

type HTTP2Config

type HTTP2Config struct {
	// MaxConcurrentStreams опционально задает количество
	// параллельных потоков, которые могут быть открыты у пира одновременно.
	// Если значение равно нулю, то по умолчанию MaxConcurrentStreams равно как минимум 100.
	MaxConcurrentStreams int

	// MaxDecoderHeaderTableSize опционально задает верхний предел для
	// размера таблицы сжатия заголовков, используемой для декодирования заголовков, отправленных
	// пиром.
	// Допустимое значение - менее 4 Мбайт.
	// Если значение равно нулю или недействительно, используется значение по умолчанию.
	MaxDecoderHeaderTableSize int

	// MaxEncoderHeaderTableSize опционально задает верхний предел для
	// таблицы сжатия заголовков, используемой для отправки заголовков сверстнику.
	// Допустимое значение - менее 4 Мбайт.
	// Если значение равно нулю или недействительно, используется значение по умолчанию.
	MaxEncoderHeaderTableSize int

	// MaxReadFrameSize опционально указывает самый большой кадр.
	// который эта конечная точка готова прочитать.
	// Допустимое значение - от 16КиБ до 16МиБ, включительно.
	// Если значение равно нулю или недействительно, используется значение по умолчанию.
	MaxReadFrameSize int

	// MaxReceiveBufferPerConnection - это максимальный размер
	// окна управления потоком для данных, получаемых по соединению.
	// Допустимое значение - не менее 64КиБ и не более 4МиБ.
	// Если значение недействительно, используется значение по умолчанию.
	MaxReceiveBufferPerConnection int

	// MaxReceiveBufferPerStream - это максимальный размер
	// окна управления потоком для данных, получаемых в потоке (запросе).
	// Допустимое значение - менее 4 Мбайт.
	// Если значение равно нулю или недействительно, используется значение по умолчанию.
	MaxReceiveBufferPerStream int

	// SendPingTimeout - таймаут, по истечении которого проверка работоспособности с помощью ping
	// кадра будет проведена, если на соединении не будет получено ни одного кадра.
	// Если ноль, проверка работоспособности не выполняется.
	SendPingTimeout time.Duration

	// PingTimeout - таймаут, по истечении которого соединение будет закрыто.
	// если не будет получен ответ на пинг.
	// Если значение равно нулю, используется значение по умолчанию 15 секунд.
	PingTimeout time.Duration

	// WriteByteTimeout - таймаут, по истечении которого соединение будет // закрыто, если не удастся записать данные.
	// закрыто, если в него не могут быть записаны данные. Таймаут начинается, когда данные // доступны для записи.
	// доступны для записи, и продлевается каждый раз, когда записываются какие-либо байты.
	WriteByteTimeout time.Duration

	// PermitProhibitedCipherSuites, если true, разрешает использование
	// наборов шифров, запрещенных спецификацией HTTP/2.
	PermitProhibitedCipherSuites bool

	// CountError, если не равен nil, вызывается при ошибках HTTP/2.
	// Она предназначена для инкрементирования метрики для мониторинга.
	// Тип errType содержит только строчные буквы, цифры и символы подчеркивания.
	// (a-z, 0-9, _).
	CountError func(errType string)
}

HTTP2Config определяет параметры конфигурации HTTP/2, общие для транспорта и сервера.

type Handler

type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}

Обработчик отвечает на HTTP-запрос.

[Handler.ServeHTTP] должен записать заголовки и данные ответа в ResponseWriter, а затем вернуться. Возврат сигнализирует о том, что запрос завершен; использование ResponseWriter или чтение из [Request.Body] после или одновременно с завершением вызова ServeHTTP недопустимо.

В зависимости от программного обеспечения HTTP-клиента, версии протокола HTTP и любых посредников между клиентом и Go-сервером, чтение из [Request.Body] после записи в ResponseWriter может быть невозможным. Осторожные обработчики должны сначала прочитать [Request.Body], а затем ответить.

Кроме чтения тела, обработчики не должны изменять предоставленный Запрос.

Если ServeHTTP паникует, сервер (вызывающий ServeHTTP) предполагает, что эффект паники был изолирован от активного запроса. Он восстанавливает панику, записывает трассировку стека в журнал ошибок сервера и либо закрывает сетевое соединение, либо отправляет HTTP/2 RST_STREAM, в зависимости от протокола HTTP. Чтобы прервать обработчик, чтобы клиент увидел прерванный ответ, но сервер не зафиксировал ошибку, вызовите панику со значением ErrAbortHandler.

Обработчик отвечает на HTTP-запрос.

[Handler.ServeHTTP] должен записать заголовки и данные ответа в ResponseWriter, а затем вернуться. Возврат сигнализирует о том, что запрос завершен; использование ResponseWriter или чтение из [Request.Body] после или одновременно с завершением вызова ServeHTTP недопустимо.

В зависимости от программного обеспечения HTTP-клиента, версии протокола HTTP и любых посредников между клиентом и Go-сервером, чтение из [Request.Body] после записи в ResponseWriter может быть невозможным. Осторожные обработчики должны сначала прочитать [Request.Body], а затем ответить.

Кроме чтения тела, обработчики не должны изменять предоставленный Запрос.

Если ServeHTTP паникует, сервер (вызывающий ServeHTTP) предполагает, что эффект паники был изолирован от активного запроса. Он восстанавливает панику, записывает трассировку стека в журнал ошибок сервера и либо закрывает сетевое соединение, либо отправляет HTTP/2 RST_STREAM, в зависимости от протокола HTTP. Чтобы прервать обработчик, чтобы клиент увидел прерванный ответ, но сервер не зафиксировал ошибку, вызовите панику со значением ErrAbortHandler.

func AllowQuerySemicolons

func AllowQuerySemicolons(h Handler) Handler

AllowQuerySemicolons возвращает обработчик, который обслуживает запросы, преобразуя любые неэскэпированные точки с запятой в URL-запросе в амперсанд и вызывая обработчик h.

Это восстанавливает поведение, существовавшее до версии Go 1.17, когда параметры запроса разделялись как на точки с запятой, так и на амперсанд. (См. golang.org/issue/25192). Обратите внимание, что такое поведение не соответствует поведению многих прокси-серверов, и это несоответствие может привести к проблемам безопасности.

AllowQuerySemicolons должен быть вызван до вызова Request.ParseForm.

func FileServer

func FileServer(root FileSystem) Handler

FileServer возвращает обработчик, который обслуживает HTTP-запросы с содержимым файловой системы, укорененной в root.

В качестве особого случая, возвращаемый файловый сервер перенаправляет любой запрос, заканчивающийся на «/index.html», на тот же путь, без конечного «index.html».

Чтобы использовать реализацию файловой системы операционной системы, используйте http.Dir:

http.Handle(«/», http.FileServer(http.Dir(«/tmp»)))

Чтобы использовать реализацию fs.FS, используйте http.FileServerFS.

Пример
package main

import (
	"log"
	"net/http"
)

func main() {
	// Simple static webserver:
	log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("/usr/share/doc"))))
}
Пример DotFileHiding
пакет main

импорт (
	«io»
	«io/fs»
	«log»
	«net/http»
	«strings»
)

// containsDotFile сообщает, содержит ли имя элемент пути, начинающийся с точки.
// Предполагается, что имя представляет собой файл, разделенный прямыми косыми чертами, как это гарантируется
// интерфейсом http.FileSystem.
func containsDotFile(name string) bool {
	parts := strings.Split(name, «/»)
	for _, part := range parts {
		if strings.HasPrefix(part, «.») {
			return true
		}
	}
	return false
}

// dotFileHidingFile - это http.File, используемый в dotFileHidingFileSystem.
// Он используется для обертывания метода Readdir из http.File, чтобы мы могли
// удалять из его вывода файлы и каталоги, начинающиеся с точки.
тип dotFileHidingFile struct {
	http.File
}

// Readdir - это обертка вокруг метода Readdir встроенного File.
// которая отфильтровывает все файлы, имя которых начинается с точки.
func (f dotFileHidingFile) Readdir(n int) (fis []fs.FileInfo, err error) {
	files, err := f.File.Readdir(n)
	for _, file := range files { // Отфильтровываем файлы с точками
		if !strings.HasPrefix(file.Name(), «.») {
			fis = append(fis, file)
		}
	}
	if err == nil && n > 0 && len(fis) == 0 {
		err = io.EOF
	}
	return
}

// dotFileHidingFileSystem - это http.FileSystem, которая скрывает
// скрытые «dot-файлы» от обслуживания.
тип dotFileHidingFileSystem struct {
	http.FileSystem
}

// Open - это обертка вокруг метода Open встроенной файловой системы.
// который выдает ошибку разрешения 403, если в имени есть файл или каталог
// в пути которого имя начинается с точки.
func (fsys dotFileHidingFileSystem) Open(name string) (http.File, error) {
	if containsDotFile(name) { // Если файл с точкой, возвращаем ответ 403
		return nil, fs.ErrPermission
	}

	file, err := fsys.FileSystem.Open(name)
	if err != nil {
		return nil, err
	}
	return dotFileHidingFile{file}, err
}

func main() {
	fsys := dotFileHidingFileSystem{http.Dir(«.»)}
	http.Handle(«/», http.FileServer(fsys))
	log.Fatal(http.ListenAndServe(«:8080», nil))
}
Пример StripPrefix
пакет main

импорт (
	«net/http»
)

func main() {
	// Чтобы обслужить каталог на диске (/tmp) по альтернативному URL
	// пути (/tmpfiles/), используйте StripPrefix для изменения пути запроса
	// путь URL до того, как его увидит файловый сервер:
	http.Handle(«/tmpfiles/», http.StripPrefix(«/tmpfiles/», http.FileServer(http.Dir(«/tmp»))))
}

func FileServerFS

func FileServerFS(root fs.FS) Обработчик

FileServerFS возвращает обработчик, который обслуживает HTTP-запросы с содержимым файловой системы fsys. Файлы, предоставляемые fsys, должны реализовывать io.Seeker.

В качестве особого случая, возвращаемый файловый сервер перенаправляет любой запрос, заканчивающийся на «/index.html», на тот же путь, без конечного «index.html».

http.Handle(«/», http.FileServerFS(fsys))

func MaxBytesHandler

func MaxBytesHandler(h Handler, n int64) Handler

MaxBytesHandler возвращает обработчик, который запускает h с его ResponseWriter и [Request.Body], обернутыми MaxBytesReader.

func NotFoundHandler

func NotFoundHandler() Handler

NotFoundHandler возвращает простой обработчик запросов, который отвечает на каждый запрос ответом «404 страница не найдена».

Пример
package main

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

func newPeopleHandler() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "This is the people handler.")
	})
}

func main() {
	mux := http.NewServeMux()

	// Create sample handler to returns 404
	mux.Handle("/resources", http.NotFoundHandler())

	// Create sample handler that returns 200
	mux.Handle("/resources/people/", newPeopleHandler())

	log.Fatal(http.ListenAndServe(":8080", mux))
}

func RedirectHandler

func RedirectHandler(url string, code int) Обработчик

RedirectHandler возвращает обработчик запроса, который перенаправляет каждый полученный запрос на заданный url с использованием заданного кода состояния.

Заданный код должен быть в диапазоне 3xx и обычно является StatusMovedPermanently, StatusFound или StatusSeeOther.

func StripPrefix

func StripPrefix(prefix string, h Handler) Handler

StripPrefix возвращает обработчик, который обслуживает HTTP-запросы, удаляя заданный префикс из Path (и RawPath, если задан) URL запроса и вызывая обработчик h. StripPrefix обрабатывает запрос на путь, который не начинается с префикса, отвечая ошибкой HTTP 404 not found. Префикс должен точно совпадать: если префикс в запросе содержит экранированные символы, ответом также будет ошибка HTTP 404 not found.

Пример
package main

import (
	"net/http"
)

func main() {
	// To serve a directory on disk (/tmp) under an alternate URL
	// path (/tmpfiles/), use StripPrefix to modify the request
	// URL's path before the FileServer sees it:
	http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))
}

func TimeoutHandler

func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler

TimeoutHandler возвращает обработчик, который запускает h с заданным лимитом времени.

Новый обработчик вызывает h.ServeHTTP для обработки каждого запроса, но если вызов выполняется дольше установленного лимита времени, обработчик отвечает ошибкой 503 Service Unavailable с заданным сообщением в теле. (Если msg пустое, будет отправлено подходящее сообщение по умолчанию). После такого таймаута запись h в свой ResponseWriter будет возвращать ErrHandlerTimeout.

TimeoutHandler поддерживает интерфейс Pusher, но не поддерживает интерфейсы Hijacker и Flusher.

type HandlerFunc

type HandlerFunc func(ResponseWriter, *Request)

Тип HandlerFunc - это адаптер, позволяющий использовать обычные функции в качестве HTTP-обработчиков. Если f - функция с соответствующей сигнатурой, то HandlerFunc(f) - это обработчик, вызывающий f.

func (HandlerFunc) ServeHTTP

func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request)

ServeHTTP вызывает f(w, r).

type Header

type Header map[string][]string

Header представляет пары ключ-значение в HTTP-заголовке.

Ключи должны быть в канонической форме, как возвращает CanonicalHeaderKey.

func (Header) Add

func (h Header) Add(key, value string)

Add добавляет пару ключ-значение в заголовок. Она добавляется ко всем существующим значениям, связанным с ключом. Ключ не чувствителен к регистру; он канонизируется с помощью CanonicalHeaderKey.

func (Header) Clone

func (h Header) Clone() Header

Clone возвращает копию h или nil, если h - nil.

func (Header) Del

func (h Header) Del(key string)

Del удаляет значения, связанные с ключом. Ключ не чувствителен к регистру; он канонизируется с помощью CanonicalHeaderKey.

func (Header) Get

func (h Header) Get(key string) string

Get получает первое значение, связанное с заданным ключом. Если значений, связанных с ключом, нет, Get возвращает “”. Нечувствительно к регистру; textproto.CanonicalMIMEHeaderKey используется для канонизации предоставленного ключа. Get предполагает, что все ключи хранятся в канонической форме. Чтобы использовать неканонические ключи, обращайтесь к карте напрямую.

func (Header) Set

func (h Header) Set(key, value string)

Set устанавливает записи заголовка, связанные с ключом, в значение одного элемента. Она заменяет все существующие значения, связанные с ключом. Ключ не чувствителен к регистру; он канонизируется с помощью textproto.CanonicalMIMEHeaderKey. Чтобы использовать неканонические ключи, присваивайте их непосредственно карте.

func (Header) Values

func (h Header) Values(key string) []string

Values возвращает все значения, связанные с заданным ключом. Нечувствительно к регистру; textproto.CanonicalMIMEHeaderKey используется для канонизации заданного ключа. Чтобы использовать неканонические ключи, обращайтесь к карте напрямую. Возвращаемый фрагмент не является копией.

func (Header) Write

func (h Header) Write(w io.Writer) error

Write записывает заголовок в формате wire.

func (Header) WriteSubset

func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error

WriteSubset записывает заголовок в формате wire. Если exclude не равно nil, ключи, для которых exclude[key] == true, не записываются. Ключи не канонизируются перед проверкой карты exclude.

type Hijacker

type Hijacker interface
	// Hijack позволяет вызывающей стороне взять на себя управление соединением.
	// После вызова Hijack библиотека HTTP-сервера
	// больше ничего не будет делать с соединением.
	//
	// Ответственность за управление // и закрытие соединения ложится на вызывающую сторону.
	// и закрывать соединение.
	//
	// Возвращаемый net.Conn может иметь дедлайны чтения или записи.
	// уже установленными, в зависимости от конфигурации
	// сервера. Вызывающая сторона несет ответственность за установку
	// или очистить эти сроки по мере необходимости.
	//
	// Возвращаемый файл bufio.Reader может содержать необработанные буферизованные
	// данные от клиента.
	//
	// После вызова Hijack исходное Request.Body не должно
	// использоваться. Контекст исходного запроса остается действительным и
	// не отменяется до тех пор, пока метод ServeHTTP запроса
	// возвращается.
	Hijack() (net.Conn, *bufio.ReadWriter, error)
}

Интерфейс Hijacker реализуется в ResponseWriter’ах, которые позволяют HTTP-обработчику взять на себя управление соединением.

ResponseWriter по умолчанию для соединений HTTP/1.x поддерживает Hijacker, но соединения HTTP/2 намеренно не поддерживают его. Обертки ResponseWriter также могут не поддерживать Hijacker. Обработчики всегда должны проверять эту возможность во время выполнения.

Пример
package main

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

func main() {
	http.HandleFunc("/hijack", func(w http.ResponseWriter, r *http.Request) {
		hj, ok := w.(http.Hijacker)
		if !ok {
			http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
			return
		}
		conn, bufrw, err := hj.Hijack()
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		// Don't forget to close the connection:
		defer conn.Close()
		bufrw.WriteString("Now we're speaking raw TCP. Say hi: ")
		bufrw.Flush()
		s, err := bufrw.ReadString('\n')
		if err != nil {
			log.Printf("error reading string: %v", err)
			return
		}
		fmt.Fprintf(bufrw, "You said: %q\nBye.\n", s)
		bufrw.Flush()
	})
}

type MaxBytesError

type MaxBytesError struct {
	Limit int64
}

MaxBytesError возвращается MaxBytesReader, когда его лимит чтения превышен.

func (*MaxBytesError) Error

func (e *MaxBytesError) Error() string

type ProtocolError

устаревший

type Protocols

type Protocols struct {
	// содержит отфильтрованные или неэкспонированные поля
}

Protocols - это набор протоколов HTTP. Нулевое значение - это пустой набор протоколов.

Поддерживаются следующие протоколы:

  • HTTP1 - протоколы HTTP/1.0 и HTTP/1.1. HTTP1 поддерживается как на незащищенных TCP, так и на защищенных TLS соединениях.
  • HTTP2 - протокол HTTP/2 через TLS-соединение.
  • UnencryptedHTTP2 - протокол HTTP/2 через незащищенное TCP-соединение.
Пример Http1
package main

import (
	"log"
	"net/http"
)

func main() {
	srv := http.Server{
		Addr: ":8443",
	}

	// Serve only HTTP/1.
	srv.Protocols = new(http.Protocols)
	srv.Protocols.SetHTTP1(true)

	log.Fatal(srv.ListenAndServeTLS("cert.pem", "key.pem"))
}
Пример Http1or2
package main

import (
	"log"
	"net/http"
)

func main() {
	t := http.DefaultTransport.(*http.Transport).Clone()

	// Use either HTTP/1 and HTTP/2.
	t.Protocols = new(http.Protocols)
	t.Protocols.SetHTTP1(true)
	t.Protocols.SetHTTP2(true)

	cli := &http.Client{Transport: t}
	res, err := cli.Get("http://www.google.com/robots.txt")
	if err != nil {
		log.Fatal(err)
	}
	res.Body.Close()
}

func (Protocols) HTTP1

func (p Protocols) HTTP1() bool

HTTP1 сообщает, включает ли p протокол HTTP/1.

func (Протоколы) HTTP2

func (p Protocols) HTTP2() bool

HTTP2 сообщает, включает ли p протокол HTTP/2.

func (*Protocols) SetHTTP1

func (p *Protocols) SetHTTP1(ok bool)

SetHTTP1 добавляет или удаляет HTTP/1 из p.

func (*Protocols) SetHTTP2

func (p *Protocols) SetHTTP2(ok bool)

SetHTTP2 добавляет или удаляет HTTP/2 из p.

func (*Protocols) SetUnencryptedHTTP2

func (p *Protocols) SetUnencryptedHTTP2(ok bool)

SetUnencryptedHTTP2 добавляет или удаляет незашифрованный HTTP/2 из p.

func (Protocols) String

func (p Protocols) String() string

func (Protocols) UnencryptedHTTP2

func (p Protocols) UnencryptedHTTP2() bool

UnencryptedHTTP2 сообщает, включает ли p незашифрованный HTTP/2.

type PushOptions

type PushOptions struct {
	// Method указывает HTTP-метод для обещанного запроса.
	// Если установлен, он должен быть «GET» или «HEAD». Пустое значение означает «GET».
	Method string

	// Header указывает дополнительные заголовки обещанного запроса. Они не могут
	// включать поля псевдозаголовков HTTP/2, такие как «:path» и «:scheme»,
	// которые будут добавлены автоматически.
	Заголовок Header
}

PushOptions описывает опции для [Pusher.Push].

type Pusher

type Pusher interface {
	// Push инициирует HTTP/2 серверный push. При этом создается синтетический
	// запрос, используя заданную цель и опции, сериализует этот запрос
	// в фрейм PUSH_PROMISE, затем отправляет этот запрос с помощью
	// обработчика запроса сервера. Если opts равно nil, используются параметры по умолчанию.
	//
	// Цель должна быть либо абсолютным путем (например, «/path»), либо абсолютным
	// URL, содержащий действительный хост и ту же схему, что и родительский запрос.
	// Если цель - это путь, то она наследует схему и хост // родительского запроса.
	// родительского запроса.
	//
	// Спецификация HTTP/2 запрещает рекурсивные и кросс-авторитарные проталкивания.
	// Push может обнаружить или не обнаружить эти недействительные проталкивания; однако недействительные
	// push будут обнаружены и отменены соответствующими клиентами.
	//
	// Обработчики, желающие передать URL X, должны вызывать Push перед отправкой любых
	// данные, которые могут вызвать запрос на URL X. Это позволяет избежать гонки, когда
	// клиент отправляет запрос на X до получения PUSH_PROMISE для X.
	//
	// Push будет выполняться в отдельной горутине, что делает порядок прибытия
	// недетерминированным. Любая требуемая синхронизация должна быть реализована
	// вызывающей стороной.
	//
	// Push возвращает ErrNotSupported, если клиент отключил push или если push
	// не поддерживается на базовом соединении.
	Ошибка Push(target string, opts *PushOptions)
}

Pusher - это интерфейс, реализованный в ResponseWriters, которые поддерживают HTTP/2 server push. Более подробную информацию можно найти на сайте https://tools.ietf.org/html/rfc7540#section-8.2.

type Request

type Request struct {
	// Method задает метод HTTP (GET, POST, PUT и т.д.).
	// Для клиентских запросов пустая строка означает GET.
	Строка Method

	// URL указывает либо запрашиваемый URI (для серверных
	// запросов), либо URL для доступа (для клиентских запросов).
	//
	// Для серверных запросов URL анализируется из URI.
	// предоставленного в строке запроса и хранящегося в RequestURI.  Для
	// большинства запросов поля, кроме Path и RawQuery, будут // пустыми.
	// пустыми. (См. RFC 7230, раздел 5.3)
	//
	// Для клиентских запросов URL's Host указывает сервер, к которому нужно // подключиться.
	// соединиться с ним, а поле Request's Host опционально
	// определяет значение заголовка Host для отправки в HTTP
	// запросе.
	URL *url.URL

	// Версия протокола для входящих запросов сервера.
	//
	// Для клиентских запросов эти поля игнорируются. HTTP
	// клиентский код всегда использует либо HTTP/1.1, либо HTTP/2.
	// Подробнее см. документацию по транспорту.
	Proto string // «HTTP/1.0»
	ProtoMajor int // 1
	ProtoMinor int // 0

	// Заголовок содержит поля заголовка запроса, которые либо получены
	// сервером, либо должны быть отправлены клиентом.
	//
	// Если сервер получил запрос со строками заголовка,
	//
	// Host: example.com
	// accept-encoding: gzip, deflate
	// Accept-Language: en-us
	// fOO: Bar
	// foo: two
	//
	// тогда
	//
	// Header = map[string][]string{
	// «Accept-Encoding»: { «gzip», «deflate» }
	// «Accept-Language»: {«en-us»},
	// «Foo»: { «Bar», «2»},
	// }
	//
	// Для входящих запросов заголовок Host переводится в поле
	// поле Request.Host и удаляется из карты Header.
	//
	// HTTP определяет, что имена заголовков не чувствительны к регистру. В
	// парсер запросов реализует это с помощью CanonicalHeaderKey,
	// делая первый символ и все символы, следующие за
	// дефисом прописными, а остальные - строчными.
	//
	// Для клиентских запросов некоторые заголовки, такие как Content-Length
	// и Connection, записываются автоматически, когда это необходимо, и
	// значения в Header могут игнорироваться. См. документацию
	// по методу Request.Write.
	Request Header

	// Body - это тело запроса.
	//
	// Для клиентских запросов нулевое тело означает, что запрос не имеет
	// тело, например, запрос GET. Транспорт HTTP-клиента
	// отвечает за вызов метода Close.
	//
	// Для серверных запросов тело запроса всегда не является nil
	// но при отсутствии тела немедленно возвращается EOF.
	// Сервер закроет тело запроса. Обработчику ServeHTTP
	// обработчику не нужно.
	//
	// Тело должно позволять вызывать Read одновременно с Close.
	// В частности, вызов Close должен разблокировать Read, ожидающий
	// ввода.
	Body io.ReadCloser

	// GetBody определяет необязательную функцию для возврата новой копии
	// Body. Она используется для клиентских запросов, когда перенаправление требует.
	// чтения тела более одного раза. Использование GetBody по-прежнему
	// требует установки Body.
	//
	// Для серверных запросов он не используется.
	GetBody func() (io.ReadCloser, error)

	// ContentLength записывает длину связанного содержимого.
	// Значение -1 указывает на то, что длина неизвестна.
	// Значения >= 0 указывают, что данное количество байт может быть
	// быть прочитано из Body.
	//
	// Для клиентских запросов значение 0 с ненулевым Body
	// также рассматривается как неизвестное.
	ContentLength int64

	// TransferEncoding перечисляет кодировки передачи данных от крайних к
	// внутренней. Пустой список обозначает «идентичную» кодировку.
	// TransferEncoding обычно можно игнорировать; кодировка chunked
	// автоматически добавляется и удаляется по мере необходимости при отправке и
	// получении запросов.
	TransferEncoding []string

	// Close указывает, закрывать ли соединение после
	// ответа на этот запрос (для серверов) или после отправки этого
	// запроса и чтения его ответа (для клиентов).
	//
	// Для серверных запросов HTTP-сервер обрабатывает это автоматически.
	// и это поле не нужно обработчикам.
	//
	// Для клиентских запросов установка этого поля предотвращает повторное использование
	// TCP-соединений между запросами к одним и тем же хостам, как если бы
	// Transport.DisableKeepAlives был установлен.
	Close bool

	// Для серверных запросов поле Host указывает хост, на котором
	// URL-адрес. Для HTTP/1 (согласно RFC 7230, раздел 5.4), это
	// это либо значение заголовка «Host», либо имя хоста.
	// указанное в самом URL. Для HTTP/2 это значение заголовка
	// поля псевдозаголовка «:authority».
	// Оно может иметь вид «хост:порт». Для международных доменных
	// имен, Host может быть в форме Punycode или Unicode. Используйте
	// golang.org/x/net/idna для преобразования его в любой формат, если
	// необходимо.
	// Для предотвращения атак перепривязки DNS обработчики сервера должны
	// проверять, что заголовок Host имеет значение, для которого обработчик считает себя авторитетным.
	// обработчик считает себя авторитетным. Включенный
	// ServeMux поддерживает шаблоны, зарегистрированные на определенные хосты.

	// называет и таким образом защищает свои зарегистрированные обработчики.
	//
	// Для клиентских запросов Host опционально переопределяет заголовок Host
	// заголовок для отправки. Если он пуст, метод Request.Write использует
	// значение URL.Host. Host может содержать международное
	// доменное имя.
	Host String

	// Form содержит разобранные данные формы, включая параметры запроса поля URL
	// параметры запроса поля, так и данные формы PATCH, POST или PUT.
	// Это поле доступно только после вызова ParseForm.
	// HTTP-клиент игнорирует Form и использует вместо нее Body.
	Form url.Values

	// PostForm содержит разобранные данные формы из параметров тела PATCH, POST
	// или параметров тела PUT.
	//
	// Это поле доступно только после вызова ParseForm.
	// HTTP-клиент игнорирует PostForm и использует вместо него Body.
	PostForm url.Values

	// MultipartForm - это разобранная многочастная форма, включая загрузку файлов.
	// Это поле доступно только после вызова ParseMultipartForm.
	// HTTP-клиент игнорирует MultipartForm и использует вместо нее Body.
	MultipartForm *multipart.Form

	// Trailer определяет дополнительные заголовки, которые отправляются после запроса
	// body.
	//
	// Для серверных запросов карта Trailer изначально содержит только
	// ключи трейлеров, со значениями nil. (Клиент объявляет, какие трейлеры он
	// будет отправлять позже.)  Пока обработчик читает из Body, он не должен // ссылаться на Trailer.
	// не ссылаться на Trailer. После того как чтение из Body возвращает EOF, Trailer
	// может быть прочитан снова и будет содержать значения non-nil, если они были отправлены
	// клиентом.
	//
	// Для клиентских запросов Trailer должен быть инициализирован картой, содержащей
	// ключи трейлера для последующей отправки. Значения могут быть nil или их конечные
	// значениями. ContentLength должен быть 0 или -1, чтобы отправить чанкированный запрос.
	// После отправки HTTP-запроса значения карты могут быть обновлены, пока
	// пока читается тело запроса. Как только тело вернется в EOF, вызывающая сторона должна.
	// не мутировать Trailer.
	//
	// Немногие HTTP-клиенты, серверы или прокси поддерживают HTTP-трейлеры.
	Trailer Header

	// RemoteAddr позволяет HTTP-серверам и другому программному обеспечению записывать.
	// сетевой адрес, отправивший запрос, обычно для
	// протоколирования. Это поле не заполняется ReadRequest и // не имеет определенного формата.
	// не имеет определенного формата. HTTP-сервер в этом пакете
	// устанавливает RemoteAddr в адрес «IP:порт» перед вызовом
	// обработчика.
	// Это поле игнорируется HTTP-клиентом.
	RemoteAddr String

	// RequestURI - это немодифицированный запрос-цель в
	// Request-Line (RFC 7230, раздел 3.1.1), отправленный клиентом
	// на сервер. Обычно вместо этого поля следует использовать поле URL.
	// Ошибкой является установка этого поля в HTTP-запросе клиента.
	RequestURI String

	// TLS позволяет HTTP-серверам и другому программному обеспечению записывать
	// информацию о TLS-соединении, по которому был получен запрос
	// был получен. Это поле не заполняется ReadRequest.
	// HTTP-сервер в этом пакете устанавливает поле для
	// соединений с поддержкой TLS перед вызовом обработчика;
	// в противном случае он оставляет поле нулевым.
	// Это поле игнорируется HTTP-клиентом.
	TLS *tls.ConnectionState

	// Cancel - необязательный канал, закрытие которого указывает на то, что клиентский
	// запрос следует считать отмененным. Не все реализации
	// RoundTripper могут поддерживать Cancel.
	//
	// Для серверных запросов это поле неприменимо.
	//
	// Исправлено: Установите контекст запроса с помощью NewRequestWithContext
	// вместо этого. Если поле Cancel и контекст запроса одновременно // установлены.
	// установлены, не определено, соблюдается ли Cancel.
	Cancel <-chan struct{}

	// Response - это ответ перенаправления, который вызвал этот запрос.
	// быть создан. Это поле заполняется только во время клиентских
	// перенаправления.
	Response *Response

	// Pattern - шаблон [ServeMux], который соответствует запросу.
	// Оно пустое, если запрос не был сопоставлен с шаблоном.
	Строка Pattern
	// содержит отфильтрованные или неотфильтрованные поля
}

Запрос представляет собой HTTP-запрос, полученный сервером или отправляемый клиентом.

Семантика полей немного отличается при использовании клиентом и сервером. В дополнение к примечаниям к полям, приведенным ниже, смотрите документацию по Request.Write и RoundTripper.

func NewRequest

func NewRequest(method, url string, body io.Reader) (*Request, error)

NewRequest оборачивает NewRequestWithContext, используя context.Background.

func NewRequestWithContext

func NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error)

NewRequestWithContext возвращает новый запрос, заданный методом, URL и необязательным телом.

Если предоставленное тело также является io.Closer, возвращаемое [Request.Body] устанавливается в body и будет закрыто (возможно, асинхронно) методами клиента Do, Post и PostForm, а также Transport.RoundTrip.

NewRequestWithContext возвращает запрос, подходящий для использования с Client.Do или Transport.RoundTrip. Чтобы создать запрос для использования при тестировании обработчика сервера, используйте функцию net/http/httptest.NewRequest, ReadRequest или вручную обновите поля Request. Для исходящего клиентского запроса контекст контролирует все время жизни запроса и его ответа: получение соединения, отправку запроса, чтение заголовков и тела ответа. Разницу между полями входящего и исходящего запроса смотрите в документации к типу Request.

Если body имеет тип *bytes.Buffer, *bytes.Reader или *strings.Reader, то ContentLength возвращаемого запроса устанавливается в точное значение (вместо -1), GetBody заполняется (чтобы 307 и 308 редиректы могли воспроизвести тело), а Body устанавливается в NoBody, если ContentLength равен 0.

func ReadRequest

func ReadRequest(b *bufio.Reader) (*Request, error)

ReadRequest читает и разбирает входящий запрос от b.

ReadRequest является низкоуровневой функцией и должна использоваться только в специализированных приложениях; большинство кода должно использовать сервер для чтения запросов и обрабатывать их через интерфейс Handler. ReadRequest поддерживает только запросы HTTP/1.x. Для HTTP/2 используйте golang.org/x/net/http2.

func (*Request) AddCookie

func (r *Request) AddCookie(c *Cookie)

AddCookie добавляет cookie в запрос. Согласно разделу 5.4 RFC 6265, AddCookie не добавляет более одного поля заголовка Cookie. Это означает, что все куки, если они есть, записываются в одну строку, разделенную точкой с запятой. AddCookie дезинфицирует только имя и значение c, и не дезинфицирует заголовок Cookie, уже присутствующий в запросе.

func (*Request) BasicAuth

func (r *Request) BasicAuth() (имя пользователя, строка пароля, ok bool)

BasicAuth возвращает имя пользователя и пароль, указанные в заголовке авторизации запроса, если запрос использует базовую аутентификацию HTTP. См. RFC 2617, раздел 2.

func (*Request) Clone

func (r *Request) Clone(ctx context.Context) *Request

Clone возвращает глубокую копию r с измененным контекстом на ctx. Предоставленный ctx должен быть ненулевым.

Clone делает неглубокую копию только поля Body.

Для исходящего клиентского запроса контекст контролирует все время жизни запроса и его ответа: получение соединения, отправку запроса, чтение заголовков и тела ответа.

func (*Request) Context

func (r *Request) Context() context.Context

Context возвращает контекст запроса. Чтобы изменить контекст, используйте Request.Clone или Request.WithContext.

Возвращаемый контекст всегда не имеет значения nil; по умолчанию это фоновый контекст.

Для исходящих клиентских запросов контекст управляет отменой.

Для входящих запросов сервера контекст отменяется при закрытии соединения клиента, отмене запроса (при использовании HTTP/2) или при возврате метода ServeHTTP.

func (r *Request) Cookie(name string) (*Cookie, error)

Cookie возвращает именованный cookie, указанный в запросе, или ErrNoCookie, если он не найден. Если несколько cookie соответствуют заданному имени, будет возвращен только один cookie.

func (*Request) Cookies

func (r *Request) Cookies() []*Cookie

Cookies разбирает и возвращает HTTP-куки, отправленные вместе с запросом.

func (*Request) CookiesNamed

func (r *Request) CookiesNamed(name string) []*Cookie

CookiesNamed анализирует и возвращает именованные HTTP-куки, отправленные с запросом, или пустой фрагмент, если ни один из них не соответствует.

func (*Request) FormFile

func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error)

FormFile возвращает первый файл для предоставленного ключа формы. При необходимости FormFile вызывает Request.ParseMultipartForm и Request.ParseForm.

func (*Request) FormValue

func (r *Request) FormValue(key string) string

FormValue возвращает первое значение для именованного компонента запроса. Порядок старшинства:

  • тело формы в формате application/x-www-form-urlencoded (только POST, PUT, PATCH)
  • параметры запроса (всегда)
  • тело формы multipart/form-data (всегда)

FormValue вызывает Request.ParseMultipartForm и Request.ParseForm, если это необходимо, и игнорирует любые ошибки, возвращаемые этими функциями. Если ключ отсутствует, FormValue возвращает пустую строку. Чтобы получить доступ к нескольким значениям одного и того же ключа, вызовите ParseForm, а затем проверьте [Request.Form] напрямую.

func (*Request) MultipartReader

func (r *Request) MultipartReader() (*multipart.Reader, error)

MultipartReader возвращает читателя MIME multipart, если это запрос multipart/form-data или multipart/mixed POST, иначе возвращает nil и ошибку. Используйте эту функцию вместо Request.ParseMultipartForm для обработки тела запроса в виде потока.

func (*Request) ParseForm

func (r *Request) ParseForm() error

ParseForm заполняет r.Form и r.PostForm.

Для всех запросов ParseForm разбирает необработанный запрос из URL и обновляет r.Form.

Для запросов POST, PUT и PATCH он также считывает тело запроса, разбирает его как форму и помещает результаты в r.PostForm и r.Form. Параметры тела запроса имеют приоритет перед значениями строки запроса URL в r.Form.

Если размер тела запроса еще не был ограничен MaxBytesReader, его размер ограничивается 10 МБ.

Для других методов HTTP или если Content-Type не является application/x-www-form-urlencoded, тело запроса не считывается, а r.PostForm инициализируется не нулевым, пустым значением.

Request.ParseMultipartForm автоматически вызывает ParseForm. ParseForm является идемпотентным.

func (*Request) ParseMultipartForm

func (r *Request) ParseMultipartForm(maxMemory int64) error

ParseMultipartForm разбирает тело запроса как multipart/form-data. Разбирается все тело запроса, и не более maxMemory байт его файловых частей сохраняется в памяти, а остальная часть хранится на диске во временных файлах. При необходимости ParseMultipartForm вызывает Request.ParseForm. Если ParseForm возвращает ошибку, ParseMultipartForm возвращает ее, но при этом продолжает разбирать тело запроса. После одного вызова ParseMultipartForm последующие вызовы не имеют эффекта.

func (*Request) PathValue

func (r *Request) PathValue(name string) string

PathValue возвращает значение именованного подстановочного знака пути в шаблоне ServeMux, который соответствует запросу. Возвращается пустая строка, если запрос не был сопоставлен с шаблоном или в шаблоне нет такого подстановочного знака.

func (*Request) PostFormValue

func (r *Request) PostFormValue(key string) string

PostFormValue возвращает первое значение для именованного компонента в теле запроса POST, PUT или PATCH. Параметры запроса URL игнорируются. При необходимости PostFormValue вызывает Request.ParseMultipartForm и Request.ParseForm и игнорирует любые ошибки, возвращаемые этими функциями. Если ключ отсутствует, PostFormValue возвращает пустую строку.

func (*Request) ProtoAtLeast

func (r *Request) ProtoAtLeast(major, minor int) bool

ProtoAtLeast сообщает, является ли протокол HTTP, используемый в запросе, хотя бы мажорным и минорным.

func (*Request) Referer

func (r *Request) Referer() string

Referer возвращает ссылающийся URL, если он был отправлен в запросе.

Referer пишется неправильно, как и в самом запросе, что является ошибкой с самых ранних дней существования HTTP. Это значение также может быть получено из карты Header как Header[«Referer»]; преимущество предоставления его в виде метода заключается в том, что компилятор может диагностировать программы, использующие альтернативное (правильное английское) написание req.Referrer(), но не может диагностировать программы, использующие Header[«Referrer»].

func (*Request) SetBasicAuth

func (r *Request) SetBasicAuth(имя пользователя, пароль string)

SetBasicAuth устанавливает заголовок авторизации запроса на использование базовой аутентификации HTTP с указанными именем пользователя и паролем.

При использовании HTTP Basic Authentication предоставленные имя пользователя и пароль не шифруются. Обычно их следует использовать только в запросах HTTPS.

Имя пользователя не должно содержать двоеточие. Некоторые протоколы могут предъявлять дополнительные требования к предварительному введению имени пользователя и пароля. Например, при использовании OAuth2 оба аргумента должны быть сначала закодированы в URL с помощью url.QueryEscape.

func (*Request) SetPathValue

func (r *Request) SetPathValue(name, value string)

SetPathValue устанавливает имя в значение, так что последующие вызовы r.PathValue(name) возвращают значение.

func (*Request) UserAgent

func (r *Request) UserAgent() string

UserAgent возвращает User-Agent клиента, если он был отправлен в запросе.

func (*Request) WithContext

func (r *Request) WithContext(ctx context.Context) *Request

WithContext возвращает неглубокую копию r с измененным контекстом на ctx. Предоставленный ctx должен быть ненулевым.

Для исходящего клиентского запроса контекст контролирует все время жизни запроса и его ответа: получение соединения, отправку запроса, чтение заголовков и тела ответа.

Чтобы создать новый запрос с контекстом, используйте NewRequestWithContext. Чтобы создать глубокую копию запроса с новым контекстом, используйте Request.Clone.

func (*Request) Write

func (r *Request) Write(w io.Writer) error

Write записывает HTTP/1.1 запрос, который представляет собой заголовок и тело, в формате wire. Этот метод обрабатывает следующие поля запроса:

Host
URL
Method (defaults to "GET")
Header
ContentLength
TransferEncoding
Body

Если присутствует Body, Content-Length <= 0 и для [Request.TransferEncoding] не установлено значение «identity», Write добавляет в заголовок «Transfer-Encoding: chunked». Тело закрывается после отправки.

func (*Request) WriteProxy

func (r *Request) WriteProxy(w io.Writer) error

WriteProxy похож на Request.Write, но записывает запрос в форме, ожидаемой HTTP-прокси. В частности, Request.WriteProxy записывает начальную строку Request-URI запроса с абсолютным URI, согласно разделу 5.3 RFC 7230, включая схему и хост. В любом случае WriteProxy также записывает заголовок Host, используя либо r.Host, либо r.URL.Host.

type Response

type Response struct {
	Status string // например, «200 OK»
	StatusCode int // например, 200
	Proto string // например, «HTTP/1.0»
	ProtoMajor int // например, 1
	ProtoMinor int // например, 0

	// Header сопоставляет ключи заголовков со значениями. Если в ответе было несколько
	// заголовков с одним и тем же ключом, они могут быть объединены с помощью запятой
	// разделителями.  (RFC 7230, раздел 3.2.2 требует, чтобы несколько заголовков
	// были семантически эквивалентны последовательности, разделенной запятыми.) Когда
	// значения заголовков дублируются другими полями в этой структуре (например,
	// ContentLength, TransferEncoding, Trailer), значения полей являются
	// авторитетное.
	//
	// Ключи в карте канонизированы (см. CanonicalHeaderKey).
	Header Header

    // Body представляет собой тело ответа.
	//
	// Тело ответа передается по требованию, когда поле Body
	// считывается. Если сетевое соединение обрывается или сервер
	// завершает ответ, вызов Body.Read возвращает ошибку.
	//
	// Клиент и транспорт http гарантируют, что Body всегда
	// non-nil, даже в ответах без тела или в ответах с
	// телом нулевой длины. Вызывающая сторона обязана // закрыть Body.
	// закрыть Body. Транспорт HTTP-клиента по умолчанию не может
	// повторно использовать TCP-соединения HTTP/1.x «keep-alive», если тело
	// не прочитано до конца и не закрыто.
	//
	// Тело автоматически дешанкируется, если сервер ответил
	// с «chunked» Transfer-Encoding.
	//
	// Начиная с Go 1.12, тело также будет реализовывать io.Writer
	// при успешном ответе «101 Switching Protocols»,
	// как это используется в WebSockets и режиме «h2c» HTTP/2.
	Body io.ReadCloser

	// ContentLength записывает длину связанного содержимого. Значение
	// значение -1 указывает на то, что длина неизвестна. Если Request.Method
	// является «HEAD», значения >= 0 указывают, что данное количество байт может быть
	// быть прочитано из Body.
	ContentLength int64

	// Содержит кодировки передачи данных от крайнего внешнего к крайнему внутреннему. Значение
	// nil, означает, что используется кодировка «identity».
	TransferEncoding []string

	// Close записывает, указывал ли заголовок, что соединение должно быть
	// закрыть после прочтения Body. Значение является рекомендательным для клиентов: ни
	// ни ReadResponse, ни Response.Write никогда не закрывают соединение.
	Close bool

	// Uncompressed сообщает, был ли ответ отправлен в сжатом виде, но
	// был распакован пакетом http. Если значение равно true, чтение из
	// Body выдает несжатое содержимое вместо сжатого
	// содержимое, фактически переданное с сервера, ContentLength устанавливается в -1,
	// а поля «Content-Length» и «Content-Encoding» удаляются
	// из responseHeader. Чтобы получить оригинальный ответ от
	// сервера, установите Transport.DisableCompression в true.
	Uncompressed bool

	// Трейлер сопоставляет ключи трейлера со значениями в том же
	// формате, что и Header.
	//
	// Изначально трейлер содержит только значения nil, по одному для
	// каждого ключа, указанного в заголовке «Trailer» сервера.
	// значение. Эти значения не добавляются в Header.
	//
	// К трейлеру нельзя обращаться одновременно с вызовами Read
	// на Body.
	//
	// После того как Body.Read вернет io.EOF, Trailer будет содержать.
	// любые значения трейлера, отправленные сервером.
	Trailer Header

	// Request - это запрос, который был отправлен для получения данного Response.
	// Тело запроса равно нулю (оно уже было использовано).
	// Это значение заполняется только для клиентских запросов.
	Request *Request

	// TLS содержит информацию о TLS-соединении, по которому был получен
	// был получен ответ. Он равен nil для незашифрованных ответов.
	// Указатель разделяется между ответами и не должен быть // изменен.
	// изменяться.
	TLS *tls.ConnectionState
}

Response представляет собой ответ на HTTP-запрос.

Клиент и транспорт возвращают ответы от серверов после получения заголовков ответа. Тело ответа передается по запросу по мере считывания поля Body.

func Get

func Get(url string) (resp *Response, err error)

Get выполняет GET на указанный URL. Если ответ содержит один из следующих кодов перенаправления, Get следует за этим перенаправлением, максимум 10 перенаправлений:

301 (Moved Permanently)
302 (найдено)
303 (См. другое)
307 (Временное перенаправление)
308 (постоянное перенаправление)

Ошибка возвращается, если было слишком много перенаправлений или если произошла ошибка протокола HTTP. Ответ не-2xx не приводит к ошибке. Любая возвращаемая ошибка будет иметь тип *url.Error. Метод Timeout значения url.Error сообщит true, если запрос завершился по таймеру.

Если err равен nil, resp всегда содержит ненулевой resp.Body. Вызывающая сторона должна закрыть resp.Body, когда закончит чтение из него.

Get - это обертка вокруг DefaultClient.Get.

Чтобы сделать запрос с пользовательскими заголовками, используйте NewRequest и DefaultClient.Do.

Чтобы сделать запрос с заданным контекстом (context.Context), используйте NewRequestWithContext и DefaultClient.Do.

Пример
package main

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

func main() {
	res, err := http.Get("http://www.google.com/robots.txt")
	if err != nil {
		log.Fatal(err)
	}
	body, err := io.ReadAll(res.Body)
	res.Body.Close()
	if res.StatusCode > 299 {
		log.Fatalf("Response failed with status code: %d and\nbody: %s\n", res.StatusCode, body)
	}
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", body)
}

func Head

func Head(url string) (resp *Response, err error)

Head выдает HEAD на указанный URL. Если ответ представляет собой один из следующих кодов перенаправления, Head следует за этим перенаправлением, максимум 10 перенаправлений:

301 (Moved Permanently)
302 (найдено)
303 (См. другое)
307 (Временное перенаправление)
308 (постоянный редирект)

Head - это обертка вокруг DefaultClient.Head.

Чтобы сделать запрос с указанным контекстом, используйте NewRequestWithContext и DefaultClient.Do.

func Post

func Post(url, contentType string, body io.Reader) (resp *Response, err error)

Post выполняет POST на указанный URL.

Вызывающая сторона должна закрыть resp.Body, когда закончит читать из него.

Если предоставленное тело является io.Closer, оно будет закрыто после выполнения запроса.

Post является оберткой вокруг DefaultClient.Post.

Чтобы установить пользовательские заголовки, используйте NewRequest и DefaultClient.Do.

Подробнее о том, как обрабатываются перенаправления, смотрите документацию по методу Client.Do.

Чтобы выполнить запрос с указанным контекстом (context.Context), используйте NewRequestWithContext и DefaultClient.Do.

func PostForm

func PostForm(url string, data url.Values) (resp *Response, err error)

PostForm выполняет POST-запрос на указанный URL, с ключами и значениями данных в URL-кодировке в качестве тела запроса.

Заголовок Content-Type имеет значение application/x-www-form-urlencoded. Чтобы установить другие заголовки, используйте NewRequest и DefaultClient.Do.

Когда err равен nil, resp всегда содержит ненулевое resp.Body. Вызывающая сторона должна закрыть resp.Body, когда закончит чтение из него.

PostForm - это обертка вокруг DefaultClient.PostForm.

Подробнее о том, как обрабатываются перенаправления, смотрите документацию метода Client.Do.

Чтобы выполнить запрос с указанным контекстом (context.Context), используйте NewRequestWithContext и DefaultClient.Do.

func ReadResponse

func ReadResponse(r *bufio.Reader, req *Request) (*Response, error)

ReadResponse считывает и возвращает HTTP-ответ от r. Параметр req опционально указывает запрос, который соответствует этому ответу. Если параметр nil, предполагается, что это GET-запрос. Клиенты должны вызвать resp.Body.Close после завершения чтения resp.Body. После этого вызова клиенты могут просмотреть resp.Trailer, чтобы найти пары ключ/значение, включенные в трейлер ответа.

func (*Response) Cookies

func (r *Response) Cookies() []*Cookie

Cookies разбирает и возвращает cookie, установленные в заголовках Set-Cookie.

func (*Response) Location

func (r *Response) Location() (*url.URL, error)

Location возвращает URL заголовка «Location» ответа, если он присутствует. Относительные перенаправления разрешаются относительно [Response.Request]. Возвращается ErrNoLocation, если заголовок Location отсутствует.

func (*Response) ProtoAtLeast

func (r *Response) ProtoAtLeast(major, minor int) bool

ProtoAtLeast сообщает, является ли протокол HTTP, используемый в ответе, хотя бы мажорным и минорным.

func (*Response) Write

func (r *Response) Write(w io.Writer) error

Write записывает r в w в формате ответа сервера HTTP/1.x, включая строку состояния, заголовки, тело и необязательный трейлер.

Этот метод обрабатывает следующие поля ответа r:

StatusCode
ProtoMajor
ProtoMinor
Request.Method
TransferEncoding
Trailer
Body
ContentLength
Header, значения для неканонических ключей будут иметь непредсказуемое поведение

Тело ответа закрывается после отправки.

type ResponseController

type ResponseController struct {
	// содержит отфильтрованные или неэкспонированные поля
}

ResponseController используется HTTP-обработчиком для управления ответом.

ResponseController не может быть использован после возврата метода [Handler.ServeHTTP].

func NewResponseController

func NewResponseController(rw ResponseWriter) *ResponseController

NewResponseController создает ResponseController для запроса.

ResponseWriter должен быть исходным значением, переданным в метод [Handler.ServeHTTP], или иметь метод Unwrap, возвращающий исходный ResponseWriter.

Если ResponseWriter реализует любой из следующих методов, ResponseController будет вызывать их по мере необходимости:

Flush()
FlushError() error // альтернативный вариант Flush, возвращающий ошибку
Hijack() (net.Conn, *bufio.ReadWriter, error)
SetReadDeadline(deadline time.Time) error
SetWriteDeadline(deadline time.Time) ошибка
EnableFullDuplex() error

Если ResponseWriter не поддерживает метод, ResponseController возвращает ошибку, соответствующую ErrNotSupported.

func (*ResponseController) EnableFullDuplex

func (c *ResponseController) EnableFullDuplex() error

EnableFullDuplex указывает, что обработчик запроса будет чередовать чтение из [Request.Body] с записью в ResponseWriter.

Для запросов HTTP/1 HTTP-сервер Go по умолчанию потребляет всю непрочитанную часть тела запроса перед началом записи ответа, что не позволяет обработчикам одновременно читать из запроса и записывать ответ. Вызов EnableFullDuplex отключает это поведение и позволяет обработчикам продолжать читать из запроса, одновременно записывая ответ.

Для запросов HTTP/2 HTTP-сервер Go всегда разрешает одновременное чтение и запись ответа.

func (*ResponseController) Flush

func (c *ResponseController) Flush() error

Flush сбрасывает буферизованные данные клиенту.

func (*ResponseController) Hijack

func (c *ResponseController) Hijack() (net.Conn, *bufio.ReadWriter, error)

Hijack позволяет вызывающей стороне взять на себя управление соединением. Подробности см. в интерфейсе Hijacker.

func (*ResponseController) SetReadDeadline

func (c *ResponseController) SetReadDeadline(deadline time.Time) error

SetReadDeadline устанавливает крайний срок для чтения всего запроса, включая тело. Чтение из тела запроса после превышения установленного срока вернет ошибку. Нулевое значение означает отсутствие дедлайна.

Установка крайнего срока чтения после того, как он был превышен, не продлевает его.

func (*ResponseController) SetWriteDeadline

func (c *ResponseController) SetWriteDeadline(deadline time.Time) error

SetWriteDeadline устанавливает крайний срок для написания ответа. Запись в тело ответа после превышения установленного срока не блокируется, но может быть успешной, если данные были забуферизированы. Нулевое значение означает отсутствие крайнего срока.

Установка крайнего срока записи после его превышения не приведет к его продлению.

type ResponseWriter

type ResponseWriter interface {
	// Header возвращает карту заголовков, которая будет отправлена
	// [ResponseWriter.WriteHeader]. Карта [Header] также является механизмом, с помощью которого
	// реализации [Handler] могут устанавливать HTTP-трейлеры.
	//
	// Изменение карты заголовков после вызова [ResponseWriter.WriteHeader] (или
	// [ResponseWriter.Write]) не имеет никакого эффекта, если только код состояния HTTP не был класса
	// 1xx или измененные заголовки являются трейлерами.
	//
	// Существует два способа установки трейлеров. Предпочтительным является.
	// заранее объявить в заголовках, какие трейлеры вы будете впоследствии
	// отправлять, устанавливая в заголовке «Trailer» имена
	// ключей трейлеров, которые появятся позже. В этом случае эти
	// ключи карты заголовков рассматриваются так, как если бы они были
	// трейлерами. См. пример. Второй способ - для трейлеров.
	// ключей, не известных [Обработчику] до первого [ResponseWriter.Write],
	// является префикс ключей карты [Header] с помощью константного значения [TrailerPrefix]
	// константным значением.
	//
	// Чтобы подавить автоматические заголовки ответа (например, «Дата»), установите
	// их значение в nil.
	Header() Header

	// Write записывает данные в соединение как часть HTTP-ответа.
	//
	// Если функция [ResponseWriter.WriteHeader] еще не была вызвана, Write вызывает
	// WriteHeader(http.StatusOK) перед записью данных. Если заголовок
	// не содержит строки Content-Type, Write добавляет набор Content-Type
	// к результату передачи начальных 512 байт записанных данных в
	// [DetectContentType]. Кроме того, если общий размер всех записанных
	// данных меньше нескольких КБ и нет вызовов Flush, то
	// заголовок Content-Length добавляется автоматически.
	//
	// В зависимости от версии протокола HTTP и клиента, вызов
	// Write или WriteHeader может предотвратить последующее чтение // Request.Body.
	// Request.Body. Для запросов HTTP/1.x обработчики должны считывать любые // необходимые данные тела запроса перед записью ответа.
	// необходимые данные тела запроса перед записью ответа. После того как
	// заголовки будут смыты (либо из-за явного вызова Flusher.Flush
	// вызова или записи достаточного количества данных, чтобы вызвать флэш), тело запроса
	// может быть недоступно. Для запросов HTTP/2 HTTP-сервер Go разрешает // обработчикам продолжать считывать // тело запроса.
	// обработчикам продолжать читать тело запроса, одновременно // записывая ответ.
	// записи ответа. Однако такое поведение может поддерживаться не // всеми клиентами HTTP/2.
	// всеми клиентами HTTP/2. Обработчики должны читать перед записью, если
	// по возможности, чтобы обеспечить максимальную совместимость.
	Write([]byte) (int, error)

	// WriteHeader отправляет заголовок ответа HTTP с указанным
	// кодом состояния.
	//
	// Если WriteHeader не вызывается явно, то первый вызов Write
	// вызовет неявный WriteHeader(http.StatusOK).
	// Таким образом, явные вызовы WriteHeader используются в основном для.
	// отправки кодов ошибок или информационных ответов 1xx.
	//
	// Предоставленный код должен быть действительным кодом состояния HTTP 1xx-5xx.
	// Может быть записано любое количество заголовков 1xx, за которыми следует не более
	// один заголовок 2xx-5xx. Заголовки 1xx отправляются немедленно, но заголовки 2xx-5xx
	// заголовки могут буферизироваться. Используйте интерфейс Flusher для отправки
	// буферизованных данных. Карта заголовков очищается при отправке заголовков 2xx-5xx.
	// при отправке заголовков 2xx-5xx, но не при отправке заголовков 1xx.
	//
	// Сервер автоматически отправляет заголовок 100 (Continue)
	// при первом чтении из тела запроса, если в запросе есть
	// заголовок «Expect: 100-continue».
	WriteHeader(statusCode int)
}

Интерфейс ResponseWriter используется HTTP-обработчиком для создания HTTP-ответа.

ResponseWriter не может быть использован после возврата [Handler.ServeHTTP].

Пример трейлеры

HTTP-трейлеры — это набор пар «ключ/значение», подобных заголовкам, которые следуют после HTTP-ответа, а не перед ним.

package main

import (
	"io"
	"net/http"
)

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/sendstrailers", func(w http.ResponseWriter, req *http.Request) {
		// Before any call to WriteHeader or Write, declare
		// the trailers you will set during the HTTP
		// response. These three headers are actually sent in
		// the trailer.
		w.Header().Set("Trailer", "AtEnd1, AtEnd2")
		w.Header().Add("Trailer", "AtEnd3")

		w.Header().Set("Content-Type", "text/plain; charset=utf-8") // normal header
		w.WriteHeader(http.StatusOK)

		w.Header().Set("AtEnd1", "value 1")
		io.WriteString(w, "This HTTP response has both headers before this text and trailers at the end.\n")
		w.Header().Set("AtEnd2", "value 2")
		w.Header().Set("AtEnd3", "value 3") // These will appear as trailers.
	})
}

type RoundTripper

type RoundTripper interface {
	// RoundTrip выполняет одну HTTP-транзакцию, возвращая
	// ответ на предоставленный запрос.
	//
	// RoundTrip не должен пытаться интерпретировать ответ. В
	// частности, RoundTrip должен вернуть err == nil, если он получил
	// ответ, независимо от кода состояния ответа HTTP.
	// Ненулевое значение err должно быть зарезервировано на случай неудачи в получении
	// ответа. Аналогично, RoundTrip не должен пытаться.
	// обрабатывать детали протокола более высокого уровня, такие как перенаправления,
	// аутентификация или cookies.
	//
	// RoundTrip не должен модифицировать запрос, кроме как.
	// потребления и закрытия тела запроса. RoundTrip может.
	// читать поля запроса в отдельной горутине. Вызывающие стороны
	// не должны мутировать или повторно использовать запрос до тех пор, пока не будет закрыто тело ответа
	// Body не будет закрыто.
	//
	// RoundTrip должен всегда закрывать тело, в том числе при ошибках,
	// но в зависимости от реализации может делать это в отдельной
	// горутине даже после возвращения RoundTrip. Это означает, что
	// вызывающие стороны, желающие повторно использовать тело для последующих запросов
	// должны дождаться вызова Close, прежде чем сделать это.
	//
	// Поля URL и Header запроса должны быть инициализированы.
	RoundTrip(*Request) (*Response, error)
}

RoundTripper - это интерфейс, представляющий возможность выполнения одной HTTP-транзакции с получением ответа на заданный запрос.

RoundTripper должен быть безопасным для одновременного использования несколькими горутинами.

var DefaultTransport RoundTripper = &Transport{
	Proxy: ProxyFromEnvironment,
	DialContext: defaultTransportDialContext(&net.Dialer{
		Таймаут:   30 * time.Second,
		KeepAlive: 30 * time.Second,
	}),
	ForceAttemptHTTP2: true,
	MaxIdleConns:          100,
	IdleConnTimeout: 90 * time.Second,
	TLSHandshakeTimeout:   10 * time.Second,
	ExpectContinueTimeout: 1 * time.Second,
}

DefaultTransport является реализацией Transport по умолчанию и используется DefaultClient. Он устанавливает сетевые соединения по мере необходимости и кэширует их для повторного использования при последующих вызовах. Он использует HTTP-прокси по указанию переменных окружения HTTP_PROXY, HTTPS_PROXY и NO_PROXY (или их строчных версий).

func NewFileTransport

func NewFileTransport(fs FileSystem) RoundTripper

NewFileTransport возвращает новый RoundTripper, обслуживающий предоставленную FileSystem. Возвращаемый RoundTripper игнорирует URL host в своих входящих запросах, а также большинство других свойств запроса.

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

t := &http.Transport{}
t.RegisterProtocol(«file», http.NewFileTransport(http.Dir(«/»)))
c := &http.Client{Transport: t}
res, err := c.Get(«file:///etc/passwd»)
...

func NewFileTransportFS

func NewFileTransportFS(fsys fs.FS) RoundTripper

NewFileTransportFS возвращает новый RoundTripper, обслуживающий предоставленную файловую систему fsys. Возвращаемый RoundTripper игнорирует URL host в своих входящих запросах, а также большинство других свойств запроса. Файлы, предоставляемые fsys, должны реализовывать io.Seeker.

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

fsys := os.DirFS(«/»)
t := &http.Transport{}
t.RegisterProtocol(«file», http.NewFileTransportFS(fsys))
c := &http.Client{Transport: t}
res, err := c.Get(«file:///etc/passwd»)
...

type SameSite

type SameSite int

SameSite позволяет серверу определить атрибут cookie, делающий невозможным для браузера отправку этого cookie вместе с межсайтовыми запросами. Основная цель - снизить риск утечки межсайтовой информации и обеспечить некоторую защиту от атак подделки межсайтовых запросов.

Подробности см. на сайте https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00.

const (
	SameSiteDefaultMode SameSite = iota + 1
	SameSiteLaxMode
	SameSiteStrictMode
	SameSiteNoneMode
)

type ServeMux

type ServeMux struct {
	// содержит отфильтрованные или неотфильтрованные поля
}

ServeMux - это мультиплексор HTTP-запросов. Он сопоставляет URL каждого входящего запроса со списком зарегистрированных шаблонов и вызывает обработчик шаблона, который наиболее точно соответствует URL.

Шаблоны

Шаблоны могут соответствовать методу, хосту и пути запроса. Некоторые примеры:

- «/index.html» соответствует пути „/index.html“ для любого хоста и метода.
- «GET /static/» соответствует GET-запросу, путь которого начинается с „/static/“.
- «example.com/» соответствует любому запросу к хосту „example.com“.
- «example.com/{$}» соответствует запросам с хостом „example.com“ и путем „/“.
- «/b/{bucket}/o/{objectname...}» соответствует путям, первый сегмент которых - „b“, а третий - „o“. Имя «bucket» обозначает второй сегмент, а «objectname» - оставшуюся часть пути.

В общем случае шаблон выглядит следующим образом

[METHOD ][HOST]/[PATH]

Все три части необязательны; «/» является допустимым шаблоном. Если присутствует METHOD, за ним должен следовать хотя бы один пробел или табуляция.

Буквальные (т. е. не содержащие символы дикого символа) части шаблона соответствуют соответствующим частям запроса с учетом регистра.

Шаблон без метода соответствует любому методу. Шаблон с методом GET соответствует запросам GET и HEAD. В противном случае метод должен совпадать в точности.

Шаблон без хоста соответствует всем хостам. Шаблон с указанием хоста соответствует URL-адресам только на этом хосте.

Путь может включать сегменты подстановочных знаков вида {NAME} или {NAME…}. Например, «/b/{bucket}/o/{objectname…}». Имя подстановочного знака должно быть действительным идентификатором Go. Подстановочные знаки должны быть полными сегментами пути: им должна предшествовать косая черта, а за ней следовать либо косая черта, либо конец строки. Например, «/b_{bucket}» не является правильным шаблоном.

Обычно подстановочный знак соответствует только одному сегменту пути, заканчивающемуся следующим буквенным слешем (не %2F) в URL-адресе запроса. Но если присутствует «…», то подстановочный знак соответствует оставшейся части пути URL, включая косые черты. (Поэтому подстановочный знак «…» не должен появляться нигде, кроме конца шаблона). Соответствие для подстановочного знака можно получить, вызвав Request.PathValue с именем подстановочного знака. Косая черта в пути действует как анонимный подстановочный знак «…».

Специальный подстановочный знак {$} совпадает только с концом URL. Например, шаблон «/{$}» соответствует только пути «/», в то время как шаблон «/» соответствует всем путям.

Для сопоставления пути шаблонов и пути входящих запросов сегментно разгруппировываются. Так, например, путь «/a%2Fb/100%25» рассматривается как состоящий из двух сегментов, «a/b» и «100%». Шаблон «/a%2fb/» соответствует ему, а шаблон «/a/b/» - нет.

Приоритет

Если запросу соответствуют два или более шаблонов, то приоритет имеет наиболее специфичный шаблон. Шаблон P1 более специфичен, чем P2, если P1 соответствует строгому подмножеству запросов P2; то есть, если P2 соответствует всем запросам P1 и более. Если ни один из шаблонов не является более специфичным, то они конфликтуют. Из этого правила есть одно исключение для обратной совместимости: если два шаблона в противном случае будут конфликтовать, но один из них имеет хост, а другой - нет, то приоритет имеет шаблон с хостом. Если шаблон, переданный в ServeMux.Handle или ServeMux.HandleFunc, конфликтует с другим шаблоном, который уже зарегистрирован, эти функции паникуют.

В качестве примера общего правила можно привести «/images/thumbnails/», который является более конкретным, чем «/images/», поэтому оба шаблона могут быть зарегистрированы. Первый соответствует путям, начинающимся с «/images/thumbnails/», а второй будет соответствовать любому другому пути в поддереве «/images/».

В качестве другого примера рассмотрим шаблоны «GET /» и «/index.html»: оба соответствуют GET-запросу на «/index.html», но первый шаблон соответствует всем остальным GET- и HEAD-запросам, а второй - любому запросу на «/index.html», который использует другой метод. Шаблоны конфликтуют.

Перенаправление по следам косой черты

Рассмотрим ServeMux с обработчиком для поддерева, зарегистрированного с использованием слэша в конце или подстановочного символа «…». Если ServeMux получает запрос на корень поддерева без скрепки, он перенаправляет запрос, добавляя скрепку. Это поведение можно отменить, зарегистрировав отдельный путь без косой черты или подстановочного знака «…». Например, регистрация «/images/» заставляет ServeMux перенаправлять запрос «/images» на «/images/», если только «/images» не был зарегистрирован отдельно.

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

ServeMux также заботится о дезинфекции пути запроса URL и заголовка Host, удаляя номер порта и перенаправляя любой запрос, содержащий сегменты . или … или повторяющиеся косые черты, на эквивалентный, более чистый URL. Сбегающие элементы пути, такие как «%2e» для «.» и «%2f» для «/», сохраняются и не считаются разделителями при маршрутизации запроса.

Совместимость

Синтаксис шаблонов и поведение ServeMux при сопоставлении значительно изменились в Go 1.22. Чтобы восстановить старое поведение, установите переменную окружения GODEBUG в значение «httpmuxgo121=1». Эта настройка считывается один раз, при запуске программы; изменения во время выполнения будут проигнорированы.

Изменения, несовместимые с предыдущими, включают:

  • Дикие символы в 1.21 - это обычные литеральные сегменты пути. Например, шаблон «/{x}» будет соответствовать только этому пути в 1.21, но будет соответствовать любому односегментному пути в 1.22.
  • В 1.21 ни один шаблон не отклонялся, если он не был пустым или не конфликтовал с существующим шаблоном. В 1.22 синтаксически некорректные шаблоны приводят к панике ServeMux.Handle и ServeMux.HandleFunc. Например, в 1.21 шаблоны «/{» и «/a{x}» совпадают сами по себе, но в 1.22 они недействительны и при регистрации вызовут панику.
  • В 1.22 каждый сегмент шаблона разгруппировывается; в 1.21 этого не делалось. Например, в 1.22 шаблон «/%61» соответствует пути «/a» («%61» - управляющая последовательность URL для «a»), а в 1.21 он соответствовал бы только пути «/%2561» (где «%25» - управляющая последовательность для знака процента).
  • При сопоставлении шаблонов с путями в версии 1.22 каждый сегмент пути раскрывается, а в версии 1.21 раскрывается весь путь. Это изменение в основном влияет на то, как обрабатываются пути с эскейпами %2F, расположенными рядом со слешами. Подробности см. на https://go.dev/issue/21955.

func NewServeMux

func NewServeMux() *ServeMux

NewServeMux выделяет и возвращает новый ServeMux.

func (*ServeMux) Handle

func (mux *ServeMux) Handle(pattern string, handler Handler)

Handle регистрирует обработчик для заданного шаблона. Если заданный шаблон конфликтует с уже зарегистрированным, Handle паникует.

Пример
package main

import (
	"fmt"
	"net/http"
)

type apiHandler struct{}

func (apiHandler) ServeHTTP(http.ResponseWriter, *http.Request) {}

func main() {
	mux := http.NewServeMux()
	mux.Handle("/api/", apiHandler{})
	mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		// The "/" pattern matches everything, so we need to check
		// that we're at the root here.
		if req.URL.Path != "/" {
			http.NotFound(w, req)
			return
		}
		fmt.Fprintf(w, "Welcome to the home page!")
	})
}

func (*ServeMux) HandleFunc

func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))

HandleFunc регистрирует функцию-обработчик для заданного шаблона. Если заданный шаблон конфликтует с уже зарегистрированным, HandleFunc паникует.

func (*ServeMux) Handler

func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string)

Handler возвращает обработчик, который будет использоваться для данного запроса, консультируясь с r.Method, r.Host и r.URL.Path. Всегда возвращается ненулевой обработчик. Если путь не является каноническим, то обработчик будет внутренне сгенерированным обработчиком, который перенаправляет на канонический путь. Если хост содержит порт, он игнорируется при подборе обработчиков.

Путь и хост используются без изменений для запросов CONNECT.

Обработчик также возвращает зарегистрированный шаблон, соответствующий запросу, или, в случае внутренне сгенерированных перенаправлений, путь, который будет соответствовать после выполнения перенаправления.

Если для запроса не существует зарегистрированного обработчика, Handler возвращает обработчик «страница не найдена» и пустой шаблон.

func (*ServeMux) ServeHTTP

func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request)

ServeHTTP отправляет запрос обработчику, чей шаблон наиболее точно соответствует URL запроса.

type Server

type Server struct {
	// Addr опционально указывает TCP-адрес сервера для прослушивания,
	// в форме «host:port». Если он пуст, то используется «:http» (порт 80).
	// Имена служб определены в RFC 6335 и назначены IANA.
	// Подробнее о формате адресов см. в разделе net.Dial.
	Addr string

	Handler Handler // обработчик для вызова, http.DefaultServeMux, если nil

	// DisableGeneralOptionsHandler, если true, передает запросы «OPTIONS *» обработчику,
	// в противном случае отвечает 200 OK и Content-Length: 0.
	DisableGeneralOptionsHandler bool

	// TLSConfig опционально предоставляет конфигурацию TLS для использования
	// функциями ServeTLS и ListenAndServeTLS. Обратите внимание, что это значение
	// клонируется ServeTLS и ListenAndServeTLS, поэтому не
	// невозможно изменить конфигурацию с помощью методов типа
	// tls.Config.SetSessionTicketKeys. Чтобы использовать
	// SetSessionTicketKeys, используйте Server.Serve с TLS-слушателем
	// вместо него.
	TLSConfig *tls.Config

	// ReadTimeout - максимальная продолжительность чтения всего // запроса.
	// запроса, включая тело. Нулевое или отрицательное значение означает.
	// что таймаута не будет.
	//
	// Поскольку ReadTimeout не позволяет обработчикам принимать по каждому запросу
	// решения о допустимом сроке выполнения или // скорости загрузки каждого тела запроса, большинство пользователей предпочтут использовать ReadTimeout.
	// скорости загрузки, большинство пользователей предпочтут использовать
	// ReadHeaderTimeout. Вполне допустимо использовать их оба.
	ReadTimeout time.Duration

	// ReadHeaderTimeout - это количество времени, разрешенное для чтения
	// заголовков запросов. Срок чтения соединения сбрасывается.
	// после чтения заголовков, и обработчик может решить, что
	// считается слишком медленным для тела запроса. Если значение равно нулю, используется значение
	// ReadTimeout используется. Если отрицательно, или если ноль и ReadTimeout
	// равно нулю или отрицательно, то таймаут не используется.
	ReadHeaderTimeout time.Duration

	// WriteTimeout - максимальная продолжительность до завершения тайминга
	// записи ответа. Она сбрасывается каждый раз, когда считывается новый
	// чтении заголовка запроса. Как и ReadTimeout, он не // позволяет обработчикам принимать решения.
	// позволяет обработчикам принимать решения на основе каждого запроса.
	// Нулевое или отрицательное значение означает, что таймаута не будет.
	WriteTimeout time.Duration

	// IdleTimeout - это максимальное время ожидания
	// следующего запроса, когда включены keep-alives. Если значение равно нулю, то используется значение
	// из ReadTimeout используется. Если отрицательно, или если ноль и ReadTimeout
	// равно нулю или отрицательно, таймаут не используется.
	IdleTimeout time.Duration

	// MaxHeaderBytes управляет максимальным количеством байтов, которые
	// сервер будет читать, разбирая ключи и // значения заголовка запроса, включая строку запроса.
	// значения, включая строку запроса. Оно не ограничивает
	// размер тела запроса.
	// Если значение равно нулю, используется значение DefaultMaxHeaderBytes.
	MaxHeaderBytes int

	// TLSNextProto опционально указывает функцию, которая принимает на себя
	// владение предоставленным TLS-соединением, когда происходит обновление протокола ALPN
	// произошло обновление протокола. Ключом карты является протокол.
	// согласованное имя. Аргумент Handler должен использоваться для.
	// обработки HTTP-запросов и инициализирует TLS запроса
	// и RemoteAddr, если они еще не заданы. Соединение
	// автоматически закрывается при возврате функции.
	// Если TLSNextProto не равно nil, поддержка HTTP/2 не включается
	// автоматически.
	TLSNextProto map[string]func(*Server, *tls.Conn, Handler)

	// ConnState задает необязательную функцию обратного вызова, которая
	// вызывается при изменении состояния клиентского соединения. См.
	// Тип ConnState и связанные с ним константы для получения подробной информации.
	ConnState func(net.Conn, ConnState)

	// ErrorLog задает необязательный регистратор ошибок при принятии // соединения, неожиданного поведения обработчиков.
	// соединения, неожиданного поведения обработчиков и
	// базовых ошибок файловой системы.
	// Если nil, то протоколирование осуществляется через стандартный логгер пакета log.
	ErrorLog *log.Logger

	// BaseContext опционально указывает функцию, которая возвращает
	// базовый контекст для входящих запросов на этом сервере.
	// Предоставленный слушатель - это конкретный слушатель, который
	// собирается начать принимать запросы.
	// Если BaseContext равен nil, по умолчанию используется context.Background().
	// Если не nil, то должен быть возвращен не nil контекст.
	BaseContext func(net.Listener) context.Context

	// ConnContext опционально задает функцию, которая изменяет
	// контекст, используемый для нового соединения c. Предоставляемый ctx
	// является производным от базового контекста и имеет ServerContextKey
	// значение.
	ConnContext func(ctx context.Context, c net.Conn) context.Context

	// HTTP2 настраивает HTTP/2 соединения.
	//
	// Это поле пока не имеет никакого эффекта.
	// См. https://go.dev/issue/67813.
	HTTP2 *HTTP2Config

	// Протоколы - это набор протоколов, принимаемых сервером.
	//
	// Если Protocols включает UnencryptedHTTP2, сервер будет принимать
	// незашифрованные соединения HTTP/2. Сервер может обслуживать как
	// HTTP/1 и незашифрованный HTTP/2 на одном и том же адресе и порту.
	//
	// Если значение Protocols равно nil, по умолчанию обычно используются HTTP/1 и HTTP/2.
	// Если TLSNextProto не имеет значения nil и не содержит записи «h2»,
	// по умолчанию используется только HTTP/1.
	Protocols *Protocols
	// содержит отфильтрованные или неэкспонированные поля
}

Server определяет параметры для запуска HTTP-сервера. Нулевое значение для Server является допустимой конфигурацией.

func (*Server) Close

func (s *Server) Close() error

Close немедленно закрывает все активные net.Listeners и все соединения в состоянии StateNew, StateActive или StateIdle. Для изящного завершения работы используйте Server.Shutdown.

Close не пытается закрыть (и даже не знает об этом) любые перехваченные соединения, такие как WebSockets.

Close возвращает любую ошибку, возникшую при закрытии базового слушателя(ей) сервера.

func (*Server) ListenAndServe

func (s *Server) ListenAndServe() error

ListenAndServe прослушивает сетевой TCP-адрес s.Addr и затем вызывает Serve для обработки запросов на входящих соединениях. Принимаемые соединения настроены на включение TCP keep-alives.

Если s.Addr пуст, используется «:http».

ListenAndServe всегда возвращает ошибку, отличную от нуля. После Server.Shutdown или Server.Close возвращаемая ошибка будет ErrServerClosed.

func (*Server) ListenAndServeTLS

func (s *Server) ListenAndServeTLS(certFile, keyFile string) error

ListenAndServeTLS прослушивает сетевой TCP-адрес s.Addr и затем вызывает ServeTLS для обработки запросов на входящих TLS-соединениях. Принимаемые соединения настроены на включение TCP keep-alives.

Если не заполнены ни TLSConfig.Certificates, ни TLSConfig.GetCertificate сервера, необходимо предоставить файлы, содержащие сертификат и соответствующий закрытый ключ для сервера. Если сертификат подписан центром сертификации, certFile должен представлять собой объединение сертификата сервера, всех промежуточных сертификатов и сертификата центра сертификации.

Если s.Addr пуст, используется «:https».

ListenAndServeTLS всегда возвращает ошибку, отличную от нуля. После Server.Shutdown или Server.Close возвращаемая ошибка - ErrServerClosed.

func (*Server) RegisterOnShutdown

func (s *Server) RegisterOnShutdown(f func())

RegisterOnShutdown регистрирует функцию для вызова на Server.Shutdown. Она может использоваться для изящного завершения соединений, которые подверглись обновлению протокола ALPN или были перехвачены. Эта функция должна запускать специфическое для данного протокола изящное отключение, но не должна ждать завершения отключения.

func (*Server) Serve

func (s *Server) Serve(l net.Listener) error

Serve принимает входящие соединения на слушателе l, создавая для каждого новую сервисную горутину. Сервисные программы читают запросы и затем вызывают s.Handler для ответа на них.

Поддержка HTTP/2 включена только в том случае, если Слушатель возвращает соединения *tls.Conn и они были настроены на «h2» в TLS Config.NextProtos.

Serve всегда возвращает ненулевую ошибку и закрывает l. После Server.Shutdown или Server.Close возвращаемая ошибка будет ErrServerClosed.

func (*Server) ServeTLS

func (s *Server) ServeTLS(l net.Listener, certFile, keyFile string) error

ServeTLS принимает входящие соединения на слушателе l, создавая для каждого новую сервисную горутину. Сервисные программы выполняют настройку TLS, а затем считывают запросы, вызывая s.Handler для ответа на них.

Если не заполнены ни TLSConfig.Certificates, ни TLSConfig.GetCertificate, ни config.GetConfigForClient сервера, необходимо предоставить файлы, содержащие сертификат и соответствующий закрытый ключ для сервера. Если сертификат подписан центром сертификации, файл certFile должен быть конкатенацией сертификата сервера, всех промежуточных сертификатов и сертификата центра сертификации.

ServeTLS всегда возвращает ошибку, отличную от нуля. После Server.Shutdown или Server.Close возвращаемая ошибка будет ErrServerClosed.

func (*Server) SetKeepAlivesEnabled

func (s *Server) SetKeepAlivesEnabled(v bool)

SetKeepAlivesEnabled управляет тем, включены ли HTTP keep-alives. По умолчанию keep-alives всегда включены. Только очень ограниченные ресурсы или серверы, находящиеся в процессе выключения, должны отключать их.

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Выключение изящно отключает сервер, не прерывая активных соединений. Shutdown работает, сначала закрывая все открытые слушатели, затем закрывая все простаивающие соединения, а затем ожидая неопределенное время, пока соединения не вернутся в состояние простоя, и затем выключается. Если предоставленный контекст истекает до завершения выключения, Shutdown возвращает ошибку контекста, в противном случае возвращается любая ошибка, возникшая при закрытии базового слушателя (слушателей) сервера.

Когда вызывается Shutdown, Serve, ListenAndServe и ListenAndServeTLS немедленно возвращают ErrServerClosed. Убедитесь, что программа не завершается, а ждет возврата Shutdown.

Shutdown не пытается закрыть или дождаться перехваченных соединений, таких как WebSockets. Вызывающая Shutdown программа должна отдельно уведомить такие долгоживущие соединения о закрытии и дождаться их закрытия, если это необходимо. Способ регистрации функций уведомления о выключении см. в Server.RegisterOnShutdown.

После вызова Shutdown на сервере его нельзя использовать повторно; будущие вызовы таких методов, как Serve, будут возвращать ErrServerClosed.

Пример
package main

import (
	"context"
	"log"
	"net/http"
	"os"
	"os/signal"
)

func main() {
	var srv http.Server

	idleConnsClosed := make(chan struct{})
	go func() {
		sigint := make(chan os.Signal, 1)
		signal.Notify(sigint, os.Interrupt)
		<-sigint

		// We received an interrupt signal, shut down.
		if err := srv.Shutdown(context.Background()); err != nil {
			// Error from closing listeners, or context timeout:
			log.Printf("HTTP server Shutdown: %v", err)
		}
		close(idleConnsClosed)
	}()

	if err := srv.ListenAndServe(); err != http.ErrServerClosed {
		// Error starting or closing listener:
		log.Fatalf("HTTP server ListenAndServe: %v", err)
	}

	<-idleConnsClosed
}

type Transport

type Transport struct {

	// Proxy определяет функцию для возврата прокси для данного
	// запроса. Если функция возвращает ошибку, отличную от нуля, то
	// запрос будет прерван с указанной ошибкой.
	//
	// Тип прокси определяется схемой URL. «http»,
	// «https», «socks5» и «socks5h» поддерживаются. Если схема пуста,
	// предполагается «http».
	// «socks5» обрабатывается так же, как и «socks5h».
	//
	// Если URL прокси содержит подкомпонент userinfo,
	// в прокси-запросе будут переданы имя пользователя и пароль
	// в заголовке Proxy-Authorization.
	//
	// Если Proxy равно nil или возвращает nil *URL, прокси не используется.
	Proxy func(*Request) (*url.URL, error)

	// OnProxyConnectResponse вызывается, когда транспорт получает HTTP-ответ от
	// прокси для запроса CONNECT. Он вызывается перед проверкой ответа 200 OK.
	// Если он возвращает ошибку, запрос завершается с этой ошибкой.
	OnProxyConnectResponse func(ctx context.Context, proxyURL *url.URL, connectReq *Request, connectRes *Response) error

	// DialContext задает функцию dial для создания незашифрованных TCP-соединений.
	// Если DialContext равен nil (и устаревшая Dial ниже также равна nil),
	// то транспорт набирает номер, используя пакет net.
	//
	// DialContext работает параллельно с вызовами RoundTrip.
	// Вызов RoundTrip, инициирующий набор номера, может в конечном итоге использовать
	// соединение, набранное ранее, когда предыдущее соединение
	// становится нерабочим до завершения последующего DialContext.
	DialContext func(ctx context.Context, network, addr string) (net.Conn, error)

	// Dial определяет функцию dial для создания незашифрованных TCP-соединений.
	//
	// Dial выполняется одновременно с вызовами RoundTrip.
	// Вызов RoundTrip, инициирующий набор, может в конечном итоге использовать
	// соединение, набранное ранее, если предыдущее соединение
	// становится нерабочим до завершения последующего Dial.
	//
	// Исправлено: Вместо этого используйте DialContext, который позволяет транспорту
	// отменять дозвоны, как только они больше не нужны.
	// Если оба значения установлены, приоритет имеет DialContext.
	Dial func(network, addr string) (net.Conn, error)

	// DialTLSContext задает необязательную функцию набора номера для создания
	// TLS-соединений для непроксированных HTTPS-запросов.
	//
	// Если DialTLSContext равен nil (и устаревшая DialTLS ниже также равна nil),
	// используются DialContext и TLSClientConfig.
	//
	// Если DialTLSContext установлен, крючки Dial и DialContext не используются для HTTPS
	// запросы, а параметры TLSClientConfig и TLSHandshakeTimeout
	// игнорируются. Предполагается, что возвращаемый net.Conn уже // прошел квитирование TLS.
	// прошло рукопожатие TLS.
	DialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)

	// DialTLS определяет необязательную функцию набора номера для создания
	// TLS-соединений для непроксированных HTTPS-запросов.
	//
	// Исправлено: Вместо этого используйте DialTLSContext, который позволяет транспорту
	// отменять циклы, как только они больше не нужны.
	// Если оба значения установлены, приоритет имеет DialTLSContext.
	DialTLS func(network, addr string) (net.Conn, error)

	// TLSClientConfig задает конфигурацию TLS для использования с
	// tls.Client.
	// Если nil, используется конфигурация по умолчанию.
	// Если не nil, то поддержка HTTP/2 может быть не включена по умолчанию.
	TLSClientConfig *tls.Config

	// TLSHandshakeTimeout задает максимальное количество времени.
	// ожидание рукопожатия TLS. Ноль означает отсутствие таймаута.
	TLSHandshakeTimeout time.Duration

	// DisableKeepAlives, если true, отключает HTTP keep-alives и
	// будет использовать соединение с сервером только для одного
	// HTTP-запроса.
	//
	// Это не связано с аналогичным названием TCP keep-alives.
	DisableKeepAlives bool

	// DisableCompression, если значение равно true, запрещает транспорту
	// запрашивать сжатие с помощью заголовка запроса «Accept-Encoding: gzip»
	// заголовком запроса, если запрос не содержит существующего
	// значение Accept-Encoding. Если Транспорт запрашивает gzip самостоятельно
	// самостоятельно и получает gzip-ответ, то он прозрачно
	// декодируется в Response.Body. Однако если пользователь
	// явно запросил gzip, он не будет автоматически // распакован.
	// не сжимается.
	DisableCompression bool

	// MaxIdleConns контролирует максимальное количество простаивающих (keep-alive)
	// соединений на всех хостах. Ноль означает отсутствие ограничения.
	MaxIdleConns int

	// MaxIdleConnsPerHost, если ненулевое значение, контролирует максимальное количество простаивающих
	// (keep-alive) соединений для каждого хоста. Если ноль,
	// используется значение по умолчаниюMaxIdleConnsPerHost.
	MaxIdleConnsPerHost int

	// MaxConnsPerHost опционально ограничивает общее количество
	// соединений на хост, включая соединения в состоянии дозвона,
	// активном и неактивном состояниях. При нарушении лимита соединения будут блокироваться.
	//
	// Ноль означает отсутствие ограничения.
	MaxConnsPerHost int

	// IdleConnTimeout - это максимальное количество времени, в течение которого неработающее
	// (keep-alive) соединение будет простаивать перед закрытием
	// само.
	// Ноль означает отсутствие ограничений.
	IdleConnTimeout time.Duration

	// ResponseHeaderTimeout, если ненулевое значение, определяет количество
	// времени для ожидания заголовков ответа сервера после полной
	// записи запроса (включая его тело, если таковое имеется). Это
	// время не включает время на чтение тела ответа.
	ResponseHeaderTimeout time.Duration

	// ExpectContinueTimeout, если ненулевое значение, определяет количество
	// времени для ожидания первых заголовков ответа сервера после полной
	// записи заголовков запроса, если запрос содержит
	// заголовок «Expect: 100-continue». Ноль означает отсутствие таймаута и
	// приводит к тому, что тело запроса отправляется немедленно, без
	// ожидания одобрения сервера.
	// Это время не включает время отправки заголовка запроса.
	ExpectContinueTimeout time.Duration

	// TLSNextProto определяет, как транспорт переключается на.
	// альтернативному протоколу (например, HTTP/2) после TLS ALPN
	// согласования протокола. Если транспорт набирает TLS-соединение
	// с непустым именем протокола и TLSNextProto содержит
	// запись в карте для этого ключа (например, «h2»), то функция
	// вызывается с полномочиями запроса (например, «example.com»
	// или «example.com:1234») и TLS-соединением. Функция
	// должна возвращать RoundTripper, который затем обрабатывает запрос.
	// Если TLSNextProto не равно nil, поддержка HTTP/2 не включается
	// автоматически.
	TLSNextProto map[string]func(authority string, c *tls.Conn) RoundTripper

	// ProxyConnectHeader опционально указывает заголовки, которые следует отправлять на
	// прокси во время запросов CONNECT.
	// Чтобы динамически установить заголовок, смотрите GetProxyConnectHeader.
	ProxyConnectHeader Header

	// GetProxyConnectHeader опционально указывает функцию для возврата
	// заголовки для отправки в proxyURL во время запроса CONNECT к
	// ip:port target.
	// Если она возвращает ошибку, то раундтрип транспорта завершается с ошибкой.
	// этой ошибкой. Он может вернуть (nil, nil), чтобы не добавлять заголовки.
	// Если GetProxyConnectHeader не равен nil, ProxyConnectHeader
	// игнорируется.
	GetProxyConnectHeader func(ctx context.Context, proxyURL *url.URL, target string) (Header, error)

	// MaxResponseHeaderBytes задает ограничение на то, сколько
	// байтов в ответе сервера
	// заголовок.
	//
	// Ноль означает использование ограничения по умолчанию.
	MaxResponseHeaderBytes int64

	// WriteBufferSize определяет размер буфера записи, используемого
	// при записи на транспорт.
	// Если ноль, то используется значение по умолчанию (в настоящее время 4 КБ).
	WriteBufferSize int

	// ReadBufferSize задает размер буфера чтения, используемого
	// при чтении с транспорта.
	// Если ноль, то используется значение по умолчанию (в настоящее время 4 КБ).
	ReadBufferSize int

	// ForceAttemptHTTP2 определяет, будет ли включен HTTP/2 при ненулевом значении
	// Dial, DialTLS, или DialContext func или TLSClientConfig.
	// По умолчанию использование любого из этих полей консервативно отключает HTTP/2.
	// Чтобы использовать пользовательские конфигурации дозвона или TLS и при этом пытаться HTTP/2
	// обновления, установите это значение в true.
	ForceAttemptHTTP2 bool

	// HTTP2 настраивает HTTP/2 соединения.
	//
	// Это поле пока не имеет никакого эффекта.
	// См. https://go.dev/issue/67813.
	HTTP2 *HTTP2Config

	// Протоколы - это набор протоколов, поддерживаемых транспортом.
	//
	// Если Protocols включает UnencryptedHTTP2 и не включает HTTP1,
	// транспорт будет использовать незашифрованный HTTP/2 для запросов к URL http://.
	//
	// Если Protocols равно nil, то по умолчанию обычно используется только HTTP/1.
	// Если ForceAttemptHTTP2 равен true, или если TLSNextProto содержит запись «h2»,
	// по умолчанию используются HTTP/1 и HTTP/2.
	Protocols *Protocols
	// содержит отфильтрованные или неэкспонированные поля
}

Transport - это реализация RoundTripper, поддерживающая HTTP, HTTPS и HTTP-прокси (для HTTP или HTTPS с CONNECT).

По умолчанию Transport кэширует соединения для последующего повторного использования. Это может оставить много открытых соединений при доступе ко многим хостам. Таким поведением можно управлять с помощью метода Transport.CloseIdleConnections и полей [Transport.MaxIdleConnsPerHost] и [Transport.DisableKeepAlives].

Транспорты следует использовать повторно, а не создавать по мере необходимости. Транспорты безопасны для одновременного использования несколькими горутинами.

Транспорт - это низкоуровневый примитив для выполнения HTTP- и HTTPS-запросов. Для высокоуровневой функциональности, такой как куки и редиректы, смотрите раздел Клиент.

Транспорт использует HTTP/1.1 для HTTP URL и либо HTTP/1.1, либо HTTP/2 для HTTPS URL, в зависимости от того, поддерживает ли сервер HTTP/2, и как настроен транспорт. DefaultTransport поддерживает HTTP/2. Чтобы явно включить HTTP/2 на транспорте, установите [Transport.Protocols].

Ответы с кодами состояния в диапазоне 1xx либо обрабатываются автоматически (100 expect-continue), либо игнорируются. Исключением является код состояния HTTP 101 (Switching Protocols), который считается терминальным статусом и возвращается Transport.RoundTrip. Чтобы увидеть проигнорированные ответы 1xx, используйте ClientTrace.Got1xxResponse пакета трассировки httptrace.

Transport повторяет запрос при возникновении сетевой ошибки только в том случае, если соединение уже было успешно использовано и если запрос является идемпотентным и либо не имеет тела, либо определено его [Request.GetBody]. HTTP-запросы считаются идемпотентными, если они имеют HTTP-методы GET, HEAD, OPTIONS или TRACE; или если их карта заголовков содержит запись «Idempotency-Key» или «X-Idempotency-Key». Если значение ключа idempotency является фрагментом нулевой длины, запрос рассматривается как idempotent, но заголовок не передается по проводам.

func (*Transport) CancelRequest deprecated

func (*Transport) Clone

func (t *Transport) Clone() *Transport

Clone возвращает глубокую копию экспортированных полей t.

func (*Transport) CloseIdleConnections

func (t *Транспорт) CloseIdleConnections()

CloseIdleConnections закрывает все соединения, которые были ранее подключены в результате предыдущих запросов, но теперь простаивают в состоянии «keep-alive». Она не прерывает используемые в данный момент соединения.

func (*Transport) RegisterProtocol

func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper)

RegisterProtocol регистрирует новый протокол с помощью схемы. Транспорт будет передавать запросы, использующие заданную схему, в rt. Ответственность rt заключается в имитации семантики HTTP-запросов.

RegisterProtocol может быть использован другими пакетами для обеспечения реализаций схем протоколов типа «ftp» или «file».

Если rt.RoundTrip возвращает ErrSkipAltProtocol, транспорт будет сам обрабатывать Transport.RoundTrip для этого одного запроса, как если бы протокол не был зарегистрирован.

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(req *Request) (*Response, error)

RoundTrip реализует интерфейс RoundTripper.

Для более высокоуровневой поддержки HTTP-клиентов (например, обработка cookies и перенаправлений) смотрите Get, Post и тип Client.

Как и в интерфейсе RoundTripper, типы ошибок, возвращаемых RoundTrip, не определены.