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

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

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

Пакет net предоставляет переносимый интерфейс для сетевого ввода-вывода, включая TCP/IP, UDP, разрешение доменных имен и сокеты доменов Unix.

Пакет обеспечивает доступ к примитивам низкоуровневых сетей, большинству клиентов понадобится только базовый интерфейс, предоставляемый функциями Dial, Listen и Accept и связанными интерфейсами Conn и Listener. Пакет crypto/tls использует те же интерфейсы и похожие функции Dial и Listen.

Функция Dial подключается к серверу:

conn, err := net.Dial("tcp", "golang.org:80")
if err != nil {
	// handle error
}
fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
status, err := bufio.NewReader(conn).ReadString('\n')
// ...

Функция Listen создает серверы:

ln, err := net.Listen("tcp", ":8080")
if err != nil {
	// handle error
}
for {
	conn, err := ln.Accept()
	if err != nil {
		// handle error
	}
	go handleConnection(conn)
}

Разрешение имен (Name Resolution)

Метод разрешения доменных имен (DNS) в пакете net зависит от операционной системы. Функции, такие как Dial, используют разрешение имен косвенно, а функции вроде LookupHost и LookupAddr делают это напрямую.

На Unix-системах

Ресолвер имеет два варианта работы:

  1. Чистый Go-ресолвер – отправляет DNS-запросы напрямую к серверам, указанным в /etc/resolv.conf.
  2. CGO-ресолвер – использует системные вызовы C (getaddrinfo, getnameinfo).

Чистый Go-ресолвер предпочтительнее, потому что:

  • Заблокированный DNS-запрос потребляет только горутину (легковесный поток Go).
  • Заблокированный вызов C занимает системный поток ОС (более затратно).

Когда используется CGO-ресолвер?

  • На системах, где запрещены прямые DNS-запросы (например, macOS).
  • Если заданы переменные окружения:
    • LOCALDOMAIN (даже пустая),
    • RES_OPTIONS,
    • HOSTALIASES (не пустые),
    • ASR_CONFIG (только OpenBSD).
  • Если /etc/resolv.conf или /etc/nsswitch.conf требуют функциональности, не реализованной в Go.

Лимит на CGO-запросы
Во всех системах (кроме Plan 9) действует ограничение в 500 одновременных CGO-запросов, чтобы избежать исчерпания системных потоков.


Управление выбором ресолвера

Можно переопределить выбор ресолвера через переменную окружения GODEBUG:

export GODEBUG=netdns=go    # принудительно использовать чистый Go-ресолвер
export GODEBUG=netdns=cgo   # принудительно использовать нативный (CGO) ресолвер

Также можно задать поведение при сборке через теги:

  • netgoтолько Go-ресолвер (CGO полностью отключен).
  • netcgo – оба ресолвера, но CGO имеет приоритет (можно переопределить через GODEBUG=netdns=go).

Отладочная информация
Если установить GODEBUG=netdns=1, ресолвер будет выводить отладочную информацию. Можно комбинировать:

export GODEBUG=netdns=go+1  # принудительно Go + отладка

EDNS0 и проблемы с роутерами
Go-ресолвер по умолчанию отправляет EDNS0-заголовок, чтобы запрашивать большие DNS-пакеты. Это может вызывать ошибки на некоторых модемах/роутерах. Отключить:

export GODEBUG=netedns0=0

Особенности на разных ОС

  • macOS:
    • Если Go-код собран с -buildmode=c-archive, для линковки в C-программу требуется флаг -lresolv.
  • Plan 9:
    • Ресолвер всегда использует /net/cs и /net/dns.
  • Windows (Go 1.18.x и старше):
    • Всегда используются C-функции (GetAddrInfo, DnsQuery).

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

  • Ресолвер (Resolver) – механизм преобразования доменных имен в IP-адреса.
  • CGO – вызовы C-кода из Go.
  • EDNS0 – расширение DNS, позволяющее увеличить размер пакета.
  • GODEBUG – переменная окружения для настройки поведения Go-рантайма.

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

Функции пакета net

func JoinHostPort

func JoinHostPort(host, port string) string

JoinHostPort объединяет хост и порт в сетевой адрес вида «хост:порт». Если хост содержит двоеточие, как в буквенных IPv6-адресах, то JoinHostPort возвращает «[хост]:порт».

Описание параметров хоста и порта см. в func Dial.

func LookupAddr

func LookupAddr(addr string) (names []string, err error)

LookupAddr выполняет обратный поиск по заданному адресу, возвращая список имен, сопоставленных с этим адресом.

Возвращаемые имена проверяются на правильность форматирования доменных имен в формате представления. Если в ответе содержатся недопустимые имена, эти записи отфильтровываются, и вместе с оставшимися результатами, если таковые имеются, возвращается ошибка.

При использовании хост-резольвера библиотеки C будет возвращено не более одного результата. Чтобы обойти хост-резольвер, используйте собственный резольвер.

LookupAddr внутренне использует context.Background; чтобы указать контекст, используйте Resolver.LookupAddr.

func LookupCNAME

func LookupCNAME(host string) (cname string, err error)

LookupCNAME возвращает каноническое имя для заданного хоста. Те, кому не важно каноническое имя, могут вызвать LookupHost или LookupIP напрямую; оба они позаботятся о разрешении канонического имени в процессе поиска.

Каноническое имя - это конечное имя после следования нуля или более записей CNAME. LookupCNAME не возвращает ошибку, если хост не содержит записей DNS «CNAME», при условии, что хост разрешается в адресные записи.

Возвращаемое каноническое имя проверяется на то, что оно является правильно отформатированным доменным именем формата представления.

LookupCNAME внутренне использует context.Background; чтобы указать контекст, используйте Resolver.LookupCNAME.

func LookupHost

func LookupHost(host string) (addrs []string, err error)

LookupHost ищет заданный хост с помощью локального резольвера. Он возвращает фрагмент адресов этого хоста.

Внутри LookupHost используется context.Background; чтобы указать контекст, используйте Resolver.LookupHost.

func LookupPort

func LookupPort(network, service string) (port int, err error)

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

Внутри LookupPort используется context.Background; чтобы указать контекст, используйте Resolver.LookupPort.

func LookupTXT

func LookupTXT(name string) ([]string, error)

LookupTXT возвращает записи DNS TXT для заданного доменного имени.

Если DNS TXT-запись содержит несколько строк, они объединяются в одну строку.

Внутри LookupTXT используется context.Background; чтобы указать контекст, используйте Resolver.LookupTXT.

func ParseCIDR

func ParseCIDR(s string) (IP, *IPNet, error)

ParseCIDR анализирует s как IP-адрес в нотации CIDR и длину префикса, например «192.0.2.0/24» или «2001:db8::/32», как определено в RFC 4632 и RFC 4291.

Он возвращает IP-адрес и сеть, подразумеваемую IP-адресом и длиной префикса. Например, ParseCIDR(«192.0.2.1/24») возвращает IP-адрес 192.0.2.1 и сеть 192.0.2.0/24.

Пример
package main

import (
	"fmt"
	"log"
	"net"
)

func main() {
	ipv4Addr, ipv4Net, err := net.ParseCIDR("192.0.2.1/24")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(ipv4Addr)
	fmt.Println(ipv4Net)

	ipv6Addr, ipv6Net, err := net.ParseCIDR("2001:db8:a0b:12f0::1/32")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(ipv6Addr)
	fmt.Println(ipv6Net)

}
Output:

192.0.2.1
192.0.2.0/24
2001:db8:a0b:12f0::1
2001:db8::/32

func Pipe ¶

func Pipe() (Conn, Conn)

Pipe создает синхронное, в памяти, полнодуплексное сетевое соединение; оба конца реализуют интерфейс Conn. Чтение на одном конце совпадает с записью на другом, копируя данные непосредственно между ними; внутренней буферизации нет.

func SplitHostPort

func SplitHostPort(hostport string) (host, port string, err error)

SplitHostPort разделяет сетевой адрес вида «host:port», «host%zone:port», «[host]:port» или «[host%zone]:port» на host или host%zone и port.

Буквальный IPv6-адрес в hostport должен быть заключен в квадратные скобки, как в «[::1]:80», «[::1%lo0]:80».

Описание параметра hostport, а также результатов хоста и порта см. в разделе func Dial.

2 - Типы и методы пакета net языка Go

Типы и методы пакета net

type Addr

type Addr интерфейс {
	Network() string // имя сети (например, "tcp", "udp")
	String() string // строковая форма адреса (например, "192.0.2.1:25", "[2001:db8::1]:80")
}

Addr представляет адрес конечной точки сети.

Два метода [Addr.Network] и [Addr.String] условно возвращают строки, которые могут быть переданы в качестве аргументов в Dial, но точная форма и значение строк зависят от реализации.

func InterfaceAddrs

func InterfaceAddrs() ([]Addr, error)

InterfaceAddrs возвращает список адресов одноадресных интерфейсов системы.

Возвращаемый список не идентифицирует связанный с ним интерфейс; для получения более подробной информации используйте Interfaces и Interface.Addrs.

type AddrError

type AddrError struct {
	строка Err
	Addr string
}

func (*AddrError) Error

func (e *AddrError) Error() string

func (*AddrError) Temporary

func (e *AddrError) Temporary() bool

func (*AddrError) Timeout

func (e *AddrError) Timeout() bool

type Buffers

type Buffers [][]byte

Buffers содержит ноль или более байтов для записи.

На некоторых машинах для определенных типов соединений это оптимизируется в специфическую для ОС операцию пакетной записи (например, “writev”).

func (*Buffers) Read

func (v *Буферы) Read(p []byte) (n int, err error)

Чтение из буферов.

Read реализует io.Reader для буферов.

Read изменяет фрагмент v, а также v[i] для 0 <= i < len(v), но не изменяет v[i][j] для любых i, j.

func (*Buffers) WriteTo

func (v *Буферы) WriteTo(w io.Writer) (n int64, err error)

WriteTo записывает содержимое буферов в w.

WriteTo реализует io.WriterTo для буферов.

WriteTo изменяет фрагмент v, а также v[i] для 0 <= i < len(v), но не изменяет v[i][j] для любых i, j.

type Conn ¶

type Conn interface {
	// Read считывает данные из соединения.
	// Чтение можно сделать тайм-аутом и вернуть ошибку по истечении фиксированного
	// времени; см. SetDeadline и SetReadDeadline.
	Read(b []byte) (n int, err error)

	// Write записывает данные в соединение.
	// Запись может быть сделана так, чтобы тайм-аут и возврат ошибки происходили через фиксированное
	// времени; см. SetDeadline и SetWriteDeadline.
	Write(b []byte) (n int, err error)

	// Close закрывает соединение.
	// Любые заблокированные операции чтения или записи будут разблокированы и вернут ошибку.
	Close() error

	// LocalAddr возвращает адрес локальной сети, если он известен.
	LocalAddr() Addr

	// RemoteAddr возвращает адрес удаленной сети, если он известен.
	RemoteAddr() Addr

	// SetDeadline устанавливает крайние сроки чтения и записи, связанные
	// с данным соединением. Это эквивалентно вызову обеих функций.
	// SetReadDeadline и SetWriteDeadline.
	//
	// Крайний срок - это абсолютное время, по истечении которого операции ввода-вывода
	// прекращаются, а не блокируются. Крайний срок применяется ко всем будущим
	// и ожидающим операциям ввода-вывода, а не только к непосредственно следующему вызову
	// чтения или записи. После превышения крайнего срока
	// соединение можно обновить, установив крайний срок в будущем.
	//
	// Если крайний срок превышен, вызов Read или Write или других
	// методы ввода/вывода вернут ошибку, обернутую в os.ErrDeadlineExceeded.
	// Это можно проверить с помощью errors.Is(err, os.ErrDeadlineExceeded).
	// Метод Timeout ошибки вернет true, но обратите внимание, что существуют
	// есть и другие возможные ошибки, для которых метод Timeout
	// вернет true, даже если срок не был превышен.
	//
	// Таймаут простоя может быть реализован путем многократного продления
	// крайнего срока после успешных вызовов чтения или записи.
	//
	// Нулевое значение t означает, что операции ввода-вывода не будут выполняться по тайм-ауту.
	SetDeadline(t time.Time) error

	// SetReadDeadline устанавливает крайний срок для будущих вызовов Read
	// и любого заблокированного в данный момент вызова Read.
	// Нулевое значение t означает, что операции Read не будут завершаться.
	SetReadDeadline(t time.Time) error

	// SetWriteDeadline устанавливает крайний срок для будущих вызовов записи
	// и любого заблокированного в данный момент вызова Write.
	// Даже если запись завершится, она может вернуть n > 0, указывая на то, что
	// часть данных была успешно записана.
	// Нулевое значение t означает, что Write не будет завершаться.
	SetWriteDeadline(t time.Time) error
}

Conn - это общее потоково-ориентированное сетевое соединение.

Несколько горутинов могут вызывать методы на Conn одновременно.

func Dial

func Dial(network, address string) (Conn, error)

Dial подключается к адресу в указанной сети.

Известные сети: “tcp”, “tcp4” (только для IPv4), “tcp6” (только для IPv6), “udp”, “udp4” (только для IPv4), “udp6” (только для IPv6), “ip”, “ip4” (только для IPv4), “ip6” (только для IPv6), “unix”, “unixgram” и “unixpacket”.

Для сетей TCP и UDP адрес имеет вид “хост:порт”. Хост должен быть буквальным IP-адресом или именем хоста, которое может быть преобразовано в IP-адрес. Порт должен быть буквенным номером порта или именем службы. Если хост является литеральным IPv6-адресом, он должен быть заключен в квадратные скобки, как в “[2001:db8::1]:80” или “[fe80::1%zone]:80”. Зона определяет область действия буквального IPv6-адреса, как определено в RFC 4007. Функции JoinHostPort и SplitHostPort манипулируют парой хост-порт в таком виде. При использовании TCP, когда хост разрешается в несколько IP-адресов, Dial будет пробовать каждый IP-адрес по порядку, пока один не будет успешным.

Примеры:

Dial("tcp", "golang.org:http")
Dial("tcp", "192.0.2.1:http")
Dial("tcp", "198.51.100.1:80")
Dial("udp", "[2001:db8::1]:domain")
Dial("udp", "[fe80::1%lo0]:53")
Dial("tcp", ":80")

Для IP-сетей сеть должна быть “ip”, “ip4” или “ip6”, за которой следует двоеточие и литеральный номер протокола или имя протокола, а адрес имеет вид “host”. Хост должен быть буквальным IP-адресом или буквальным IPv6-адресом с зоной. От каждой операционной системы зависит, как она поведет себя с номером протокола, не являющимся общеизвестным, например “0” или “255”.

Примеры:

Dial("ip4:1", "192.0.2.1")
Dial("ip6:ipv6-icmp", "2001:db8::1")
Dial("ip6:58", "fe80::1%lo0")

Для сетей TCP, UDP и IP, если хост пуст или является буквальным неопределенным IP-адресом, как в “:80”, “0.0.0.0:80” или “[::]:80” для TCP и UDP, “”, “0.0.0.0” или “::” для IP, предполагается локальная система.

Для сетей Unix адрес должен быть путем к файловой системе.

func DialTimeout

func DialTimeout(network, address string, timeout time.Duration) (Conn, error)

DialTimeout действует как Dial, но берет таймаут.

Таймаут включает разрешение имен, если это необходимо. Если используется TCP и хост в параметре адреса разрешается в несколько IP-адресов, таймаут распределяется на каждый последовательный набор, так что каждому дается соответствующая доля времени для соединения.

Описание параметров сети и адреса см. в func Dial.

func FileConn

func FileConn(f *os.File) (c Conn, err error)

FileConn возвращает копию сетевого соединения, соответствующего открытому файлу f. Ответственность за закрытие f по завершении работы лежит на вызывающей стороне. Закрытие c не влияет на f, а закрытие f не влияет на c.

type DNSConfigError

type DNSConfigError struct {
	Err error
}

DNSConfigError представляет ошибку чтения конфигурации DNS машины. (Больше не используется; сохранено для совместимости).

func (*DNSConfigError) Error

func (e *DNSConfigError) Error() string

func (*DNSConfigError) Temporary

func (e *DNSConfigError) Temporary() bool

func (*DNSConfigError) Timeout

func (e *DNSConfigError) Timeout() bool

func (*DNSConfigError) Unwrap

func (e *DNSConfigError) Unwrap() error

type DNSError

type DNSError struct {
	UnwrapErr error // ошибка, возвращаемая методом [DNSError.Unwrap], может быть nil
	Err string // описание ошибки
	Name string // искомое имя
	Server string // используемый сервер
	IsTimeout bool // если true, то таймаут истек; не все таймауты устанавливают это значение
	IsTemporary bool // если true, то ошибка временная; не все ошибки устанавливают это

	// IsNotFound устанавливается в true, если запрашиваемое имя не
	// не содержит записей запрашиваемого типа (данные не найдены),
	// или само имя не найдено (NXDOMAIN).
	IsNotFound bool
}

DNSError представляет ошибку поиска DNS.

func (*DNSError) Error

func (e *DNSError) Error() string

func (*DNSError) Temporary

func (e *DNSError) Temporary() bool

Temporary сообщает, является ли ошибка DNS временной. Это не всегда известно; поиск DNS может завершиться неудачей из-за временной ошибки и вернуть DNSError, для которого Temporary возвращает false.

func (*DNSError) Timeout

func (e *DNSError) Timeout() bool

Таймаут сообщает о том, что поиск DNS завершился по таймеру. Это не всегда известно; поиск DNS может завершиться неудачей из-за таймаута и вернуть DNSError, для которого Timeout возвращает false.

func (*DNSError) Unwrap

func (e *DNSError) Unwrap() error

Unwrap возвращает e.UnwrapErr.

type Dialer

type Dialer struct {
	// Timeout - это максимальное количество времени, в течение которого набор будет ждать
	// завершения соединения. Если также задано значение Deadline, то соединение может завершиться
	// раньше.
	//
	// По умолчанию таймаут отсутствует.
	//
	// При использовании TCP и наборе имени хоста с несколькими IP
	// адресов, тайм-аут может быть разделен между ними.
	//
	// С таймаутом или без него операционная система может установить
	// свой собственный более ранний тайм-аут. Например, тайм-ауты TCP
	// часто составляет около 3 минут.
	Timeout time.Duration

	// Крайний срок - это абсолютный момент времени, после которого набор номера
	// завершится неудачей. Если установлен таймаут, то отказ может произойти раньше.
	// Ноль означает отсутствие крайнего срока, или зависит от операционной системы.
	// как в случае с параметром Timeout.
	Deadline time.Time

	// LocalAddr - локальный адрес, который следует использовать при наборе
	// адреса. Адрес должен быть совместимого типа для
	// набираемой сети.
	// Если nil, локальный адрес выбирается автоматически.
	LocalAddr Addr

	// В DualStack ранее была включена поддержка RFC 6555 Fast Fallback
	// поддержка, также известная как "Happy Eyeballs", при которой IPv4
	// пробует вскоре, если IPv6 оказывается неправильно сконфигурированным и
	// зависает.
	//
	// Утративший силу: Fast Fallback включен по умолчанию. Чтобы
	// отключить, установите FallbackDelay в отрицательное значение.
	DualStack bool

	// FallbackDelay задает время ожидания перед тем, как
	// порождения соединения RFC 6555 Fast Fallback. То есть это
	// это время ожидания успеха IPv6, прежде чем
	// предположить, что IPv6 неправильно сконфигурирован, и вернуться к
	// IPv4.
	//
	// Если значение равно нулю, то по умолчанию используется задержка 300 мс.
	// Отрицательное значение отключает поддержку быстрого отката.
	FallbackDelay time.Duration

	// KeepAlive задает интервал между попытками сохранить активное сетевое соединение.
	// зондами активного сетевого соединения.
	//
	// KeepAlive игнорируется, если KeepAliveConfig.Enable равен true.
	//
	// Если значение равно нулю, то зонды keep-alive отправляются со значением по умолчанию.
	// (в настоящее время 15 секунд), если это поддерживается протоколом и операционной // системой.
	// системой. Сетевые протоколы или операционные системы, которые.
	// не поддерживают keep-alive, игнорируют это поле.
	// Если значение отрицательное, то запросы keep-alive отключаются.
	KeepAlive time.Duration

	// KeepAliveConfig определяет конфигурацию зонда keep-alive
	// для активного сетевого соединения, если оно поддерживается
	// протоколом и операционной системой.
	//
	// Если KeepAliveConfig.Enable равен true, то зонды keep-alive включены.
	// Если KeepAliveConfig.Enable ложно и KeepAlive отрицательно,
	// зонды keep-alive отключены.
	KeepAliveConfig KeepAliveConfig

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

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

	// Если Control не nil, то вызывается после создания сетевого
	// соединения, но до фактического набора номера.
	//
	// Параметры сети и адреса, передаваемые в функцию Control, не являются
	// обязательно те, которые передаются в Dial. Вызов Dial с сетями TCP
	// приведет к вызову функции Control с параметрами "tcp4" или "tcp6",
	// UDP-сети станут "udp4" или "udp6", IP-сети - "ip4" или "ip6",
	// а другие известные сети передаются как есть.
	//
	// Контроль игнорируется, если ControlContext не равен nil.
	Control func(network, address string, c syscall.RawConn) error

	// Если ControlContext не равен nil, то эта функция вызывается после создания сетевого
	// соединения, но до фактического набора номера.
	//
	// Параметры сети и адреса, передаваемые в функцию ControlContext, не являются
	// обязательно те, что переданы в Dial. Вызов Dial с сетями TCP
	// приведет к вызову функции ControlContext с параметрами "tcp4" или "tcp6",
	// UDP-сети станут "udp4" или "udp6", IP-сети - "ip4" или "ip6",
	// а другие известные сети передаются как есть.
	//
	// Если ControlContext не равен nil, Control игнорируется.
	ControlContext func(ctx context.Context, network, address string, c syscall.RawConn) error
	// содержит отфильтрованные или неэкспонированные поля
}

Dialer содержит опции для соединения с адресом.

Нулевое значение для каждого поля эквивалентно дозвону без этой опции. Поэтому набор номера с нулевым значением Dialer эквивалентен простому вызову функции Dial.

Безопасно вызывать методы Dialer одновременно.

Пример
package main

import (
	"context"
	"log"
	"net"
	"time"
)

func main() {
	var d net.Dialer
	ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
	defer cancel()

	conn, err := d.DialContext(ctx, "tcp", "localhost:12345")
	if err != nil {
		log.Fatalf("Failed to dial: %v", err)
	}
	defer conn.Close()

	if _, err := conn.Write([]byte("Hello, World!")); err != nil {
		log.Fatal(err)
	}
}
Пример Unix
package main

import (
	"context"
	"log"
	"net"
	"time"
)

func main() {
	// DialUnix does not take a context.Context parameter. This example shows
	// how to dial a Unix socket with a Context. Note that the Context only
	// applies to the dial operation; it does not apply to the connection once
	// it has been established.
	var d net.Dialer
	ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
	defer cancel()

	d.LocalAddr = nil // if you have a local addr, add it here
	raddr := net.UnixAddr{Name: "/path/to/unix.sock", Net: "unix"}
	conn, err := d.DialContext(ctx, "unix", raddr.String())
	if err != nil {
		log.Fatalf("Failed to dial: %v", err)
	}
	defer conn.Close()
	if _, err := conn.Write([]byte("Hello, socket!")); err != nil {
		log.Fatal(err)
	}
}

func (*Dialer) Dial

func (d *Dialer) Dial(network, address string) (Conn, error)

Dial соединяется с адресом в указанной сети.

Описание параметров сети и адреса см. в func Dial.

Dial внутренне использует context.Background; чтобы указать контекст, используйте Dialer.DialContext.

func (*Dialer) DialContext

func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn, error)

DialContext соединяется с адресом в названной сети, используя предоставленный контекст.

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

При использовании TCP, когда хост в параметре адреса разрешается в несколько сетевых адресов, таймаут набора номера (из d.Timeout или ctx) распределяется на каждый последовательный набор, так что каждому дается соответствующая доля времени для соединения. Например, если у хоста есть 4 IP-адреса и таймаут составляет 1 минуту, то на соединение с каждым отдельным адресом будет дано 15 секунд, прежде чем будет выполнена попытка соединения со следующим адресом.

Описание параметров сети и адреса см. в func Dial.

func (*Dialer) MultipathTCP

func (d *Dialer) MultipathTCP() bool

MultipathTCP сообщает, будет ли использоваться MPTCP.

Этот метод не проверяет, поддерживается ли MPTCP операционной системой или нет.

func (*Dialer) SetMultipathTCP

func (d *Dialer) SetMultipathTCP(use bool)

SetMultipathTCP направляет методы Dial на использование или неиспользование MPTCP, если это поддерживается операционной системой. Этот метод отменяет системное значение по умолчанию и настройку GODEBUG=multipathtcp=…, если таковая имеется.

Если MPTCP недоступен на хосте или не поддерживается сервером, методы набора будут возвращаться к TCP.

type Error

type Error interface {
	error
	Timeout() bool // Является ли ошибка тайм-аутом?

	// Исправлено: Временные ошибки не имеют четкого определения.
	// Большинство "временных" ошибок - это таймауты, а редкие исключения вызывают удивление.
	// Не используйте этот метод.
	Temporary() bool
}

Error представляет сетевую ошибку.

type Flags

type Flags uint
const (
	FlagUp Flags = 1 << iota // интерфейс административно поднят
	FlagBroadcast // интерфейс поддерживает возможность широковещательного доступа
	FlagLoopback // интерфейс является интерфейсом обратной связи
	FlagPointToPoint // интерфейс принадлежит к каналу "точка-точка
	FlagMulticast // интерфейс поддерживает возможность многоадресного доступа
	FlagRunning // интерфейс находится в рабочем состоянии
)

func (Flags) String

func (f Flags) String() string

type HardwareAddr

type HardwareAddr []byte

HardwareAddr представляет физический аппаратный адрес.

func ParseMAC

func ParseMAC(s string) (hw HardwareAddr, err error)

ParseMAC анализирует s как IEEE 802 MAC-48, EUI-48, EUI-64 или 20-октетный адрес канального уровня IP поверх InfiniBand, используя один из следующих форматов:

00:00:5e:00:53:01
02:00:5e:10:00:00:00:01
00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01
00-00-5e-00-53-01
02-00-5e-10-00-00-00-01
00-00-00-00-fe-80-00-00-00-00-00-00-02-00-5e-10-00-00-00-01
0000.5e00.5301
0200.5e10.0000.0001
0000.0000.fe80.0000.0000.0000.0200.5e10.0000.0001

func (HardwareAddr) String

func (a HardwareAddr) String() string

type IP

type IP []byte

IP - это один IP-адрес, представляющий собой фрагмент байтов. Функции этого пакета принимают на вход 4-байтовые (IPv4) или 16-байтовые (IPv6) фрагменты.

Обратите внимание, что в этой документации обращение к IP-адресу как к IPv4-адресу или IPv6-адресу является семантическим свойством адреса, а не просто длиной байтового фрагмента: 16-байтовый фрагмент все еще может быть IPv4-адресом.

func IPv4

func IPv4(a, b, c, d byte) IP

IPv4 возвращает IP-адрес (в 16-байтовой форме) IPv4-адреса a.b.c.d.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	fmt.Println(net.IPv4(8, 8, 8, 8))

}
Output:

8.8.8.8

func LookupIP

func LookupIP(host string) ([]IP, error)

LookupIP ищет хост с помощью локального резольвера. Он возвращает фрагмент IPv4 и IPv6 адресов этого хоста.

func ParseIP

func ParseIP(s string) IP

ParseIP разбирает s как IP-адрес, возвращая результат. Строка s может быть в десятичном точечном формате IPv4 (“192.0.2.1”), IPv6 (“2001:db8::68”) или IPv4-mapped IPv6 ("::ffff:192.0.2.1"). Если s не является корректным текстовым представлением IP-адреса, ParseIP возвращает nil. Возвращаемый адрес всегда имеет размер 16 байт, IPv4-адреса возвращаются в IPv4-сопоставленной IPv6-форме.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	fmt.Println(net.ParseIP("192.0.2.1"))
	fmt.Println(net.ParseIP("2001:db8::68"))
	fmt.Println(net.ParseIP("192.0.2"))

}
Output:

192.0.2.1
2001:db8::68
<nil>

func (IP) AppendText

func (ip IP) AppendText(b []byte) ([]byte, error)

AppendText реализует интерфейс encoding.TextAppender. Кодировка такая же, как и у IP.String, за одним исключением: Если len(ip) равно нулю, то ничего не добавляется.

func (IP) DefaultMask

func (ip IP) DefaultMask() IPMask

DefaultMask возвращает IP-маску по умолчанию для IP-адреса ip. Маски по умолчанию есть только у IPv4-адресов; DefaultMask возвращает nil, если ip не является действительным IPv4-адресом.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	ip := net.ParseIP("192.0.2.1")
	fmt.Println(ip.DefaultMask())

}
Output:

ffffff00

func (IP) Equal

func (ip IP) Equal(x IP) bool

Equal сообщает, являются ли ip и x одним и тем же IP-адресом. IPv4-адрес и тот же адрес в форме IPv6 считаются равными.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	ipv4DNS := net.ParseIP("8.8.8.8")
	ipv4Lo := net.ParseIP("127.0.0.1")
	ipv6DNS := net.ParseIP("0:0:0:0:0:FFFF:0808:0808")

	fmt.Println(ipv4DNS.Equal(ipv4DNS))
	fmt.Println(ipv4DNS.Equal(ipv4Lo))
	fmt.Println(ipv4DNS.Equal(ipv6DNS))

}
Output:

true
false
true

func (IP) IsGlobalUnicast

func (ip IP) IsGlobalUnicast() bool

IsGlobalUnicast сообщает, является ли ip глобальным одноадресным адресом.

Для идентификации глобальных одноадресных адресов используется идентификация типа адреса, как определено в RFC 1122, RFC 4632 и RFC 4291, за исключением адресов направленной широковещательной рассылки IPv4. Возвращает true, даже если ip находится в частном адресном пространстве IPv4 или локальном адресном пространстве IPv6 одноадресной рассылки.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	ipv6Global := net.ParseIP("2000::")
	ipv6UniqLocal := net.ParseIP("2000::")
	ipv6Multi := net.ParseIP("FF00::")

	ipv4Private := net.ParseIP("10.255.0.0")
	ipv4Public := net.ParseIP("8.8.8.8")
	ipv4Broadcast := net.ParseIP("255.255.255.255")

	fmt.Println(ipv6Global.IsGlobalUnicast())
	fmt.Println(ipv6UniqLocal.IsGlobalUnicast())
	fmt.Println(ipv6Multi.IsGlobalUnicast())

	fmt.Println(ipv4Private.IsGlobalUnicast())
	fmt.Println(ipv4Public.IsGlobalUnicast())
	fmt.Println(ipv4Broadcast.IsGlobalUnicast())

}
Output:

true
true
false
true
true
false

func (IP) IsInterfaceLocalMulticast

func (ip IP) IsInterfaceLocalMulticast() bool

IsInterfaceLocalMulticast сообщает, является ли ip интерфейсно-локальным многоадресным адресом.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	ipv6InterfaceLocalMulti := net.ParseIP("ff01::1")
	ipv6Global := net.ParseIP("2000::")
	ipv4 := net.ParseIP("255.0.0.0")

	fmt.Println(ipv6InterfaceLocalMulti.IsInterfaceLocalMulticast())
	fmt.Println(ipv6Global.IsInterfaceLocalMulticast())
	fmt.Println(ipv4.IsInterfaceLocalMulticast())

}
Output:

true
false
false

func (IP) IsLinkLocalMulticast

func (ip IP) IsLinkLocalMulticast() bool

IsLinkLocalMulticast сообщает, является ли ip адресом link-local multicast.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	ipv6LinkLocalMulti := net.ParseIP("ff02::2")
	ipv6LinkLocalUni := net.ParseIP("fe80::")
	ipv4LinkLocalMulti := net.ParseIP("224.0.0.0")
	ipv4LinkLocalUni := net.ParseIP("169.254.0.0")

	fmt.Println(ipv6LinkLocalMulti.IsLinkLocalMulticast())
	fmt.Println(ipv6LinkLocalUni.IsLinkLocalMulticast())
	fmt.Println(ipv4LinkLocalMulti.IsLinkLocalMulticast())
	fmt.Println(ipv4LinkLocalUni.IsLinkLocalMulticast())

}
Output:

true
false
true
false

func (IP) IsLinkLocalUnicast

func (ip IP) IsLinkLocalUnicast() bool

IsLinkLocalUnicast сообщает, является ли ip адресом link-local unicast.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	ipv6LinkLocalUni := net.ParseIP("fe80::")
	ipv6Global := net.ParseIP("2000::")
	ipv4LinkLocalUni := net.ParseIP("169.254.0.0")
	ipv4LinkLocalMulti := net.ParseIP("224.0.0.0")

	fmt.Println(ipv6LinkLocalUni.IsLinkLocalUnicast())
	fmt.Println(ipv6Global.IsLinkLocalUnicast())
	fmt.Println(ipv4LinkLocalUni.IsLinkLocalUnicast())
	fmt.Println(ipv4LinkLocalMulti.IsLinkLocalUnicast())

}
Output:

true
false
true
false

func (IP) IsLoopback

func (ip IP) IsLoopback() bool

IsLoopback сообщает, является ли ip адресом loopback.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	ipv6Lo := net.ParseIP("::1")
	ipv6 := net.ParseIP("ff02::1")
	ipv4Lo := net.ParseIP("127.0.0.0")
	ipv4 := net.ParseIP("128.0.0.0")

	fmt.Println(ipv6Lo.IsLoopback())
	fmt.Println(ipv6.IsLoopback())
	fmt.Println(ipv4Lo.IsLoopback())
	fmt.Println(ipv4.IsLoopback())

}
Output:

true
false
true
false

func (IP) IsMulticast

func (ip IP) IsMulticast() bool

IsMulticast сообщает, является ли ip адресом многоадресной рассылки.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	ipv6Multi := net.ParseIP("FF00::")
	ipv6LinkLocalMulti := net.ParseIP("ff02::1")
	ipv6Lo := net.ParseIP("::1")
	ipv4Multi := net.ParseIP("239.0.0.0")
	ipv4LinkLocalMulti := net.ParseIP("224.0.0.0")
	ipv4Lo := net.ParseIP("127.0.0.0")

	fmt.Println(ipv6Multi.IsMulticast())
	fmt.Println(ipv6LinkLocalMulti.IsMulticast())
	fmt.Println(ipv6Lo.IsMulticast())
	fmt.Println(ipv4Multi.IsMulticast())
	fmt.Println(ipv4LinkLocalMulti.IsMulticast())
	fmt.Println(ipv4Lo.IsMulticast())

}
Output:

true
true
false
true
true
false

func (IP) IsPrivate

func (ip IP) IsPrivate() bool

IsPrivate сообщает, является ли ip частным адресом, в соответствии с RFC 1918 (IPv4-адреса) и RFC 4193 (IPv6-адреса).

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	ipv6Private := net.ParseIP("fc00::")
	ipv6Public := net.ParseIP("fe00::")
	ipv4Private := net.ParseIP("10.255.0.0")
	ipv4Public := net.ParseIP("11.0.0.0")

	fmt.Println(ipv6Private.IsPrivate())
	fmt.Println(ipv6Public.IsPrivate())
	fmt.Println(ipv4Private.IsPrivate())
	fmt.Println(ipv4Public.IsPrivate())

}
Output:

true
false
true
false

func (IP) IsUnspecified

func (ip IP) IsUnspecified() bool

IsUnspecified сообщает, является ли ip неопределенным адресом, либо IPv4-адресом “0.0.0.0”, либо IPv6-адресом “::”.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	ipv6Unspecified := net.ParseIP("::")
	ipv6Specified := net.ParseIP("fe00::")
	ipv4Unspecified := net.ParseIP("0.0.0.0")
	ipv4Specified := net.ParseIP("8.8.8.8")

	fmt.Println(ipv6Unspecified.IsUnspecified())
	fmt.Println(ipv6Specified.IsUnspecified())
	fmt.Println(ipv4Unspecified.IsUnspecified())
	fmt.Println(ipv4Specified.IsUnspecified())

}
Output:

true
false
true
false

func (IP) MarshalText

func (ip IP) MarshalText() ([]byte, error)

MarshalText реализует интерфейс encoding.TextMarshaler. Кодировка та же, что возвращается IP.String, за одним исключением: Если len(ip) равен нулю, возвращается пустой фрагмент.

func (IP) Mask

func (ip IP) Mask(mask IPMask) IP

Mask возвращает результат маскирования IP-адреса ip с помощью маски.

func (IP) String

func (ip IP) String() string

String возвращает строковую форму IP-адреса ip. Возвращается одна из 4 форм:

  • ”, если ip имеет длину 0
  • десятичная точка (“192.0.2.1”), если ip - это IPv4 или IP4-сопоставленный IPv6-адрес.
  • IPv6 в соответствии с RFC 5952 (“2001:db8::1”), если ip - действительный IPv6-адрес
  • шестнадцатеричная форма ip без знаков препинания, если другие случаи не применимы.
Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	ipv6 := net.IP{0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	ipv4 := net.IPv4(10, 255, 0, 0)

	fmt.Println(ipv6.String())
	fmt.Println(ipv4.String())

}
Output:

fc00::
10.255.0.0

func (IP) To16

func (ip IP) To16() IP

To16 преобразует IP-адрес ip в 16-байтовое представление. Если ip не является IP-адресом (имеет неправильную длину), To16 возвращает nil.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	ipv6 := net.IP{0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	ipv4 := net.IPv4(10, 255, 0, 0)

	fmt.Println(ipv6.To16())
	fmt.Println(ipv4.To16())

}
Output:

fc00::
10.255.0.0

func (IP) To4

func (ip IP) To4() IP

To4 преобразует IPv4-адрес ip в 4-байтовое представление. Если ip не является IPv4-адресом, To4 возвращает nil.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	ipv6 := net.IP{0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	ipv4 := net.IPv4(10, 255, 0, 0)

	fmt.Println(ipv6.To4())
	fmt.Println(ipv4.To4())

}
Output:

<nil>
10.255.0.0

func (*IP) UnmarshalText

func (ip *IP) UnmarshalText(text []byte) error

UnmarshalText реализует интерфейс encoding.TextUnmarshaler. IP-адрес ожидается в форме, принимаемой ParseIP.

type IPAddr

type IPAddr struct {
	IP-АДРЕС
	Zone string // Зона масштабируемой адресации IPv6
}

IPAddr представляет адрес конечной точки IP.

func ResolveIPAddr

func ResolveIPAddr(network, address string) (*IPAddr, error)

ResolveIPAddr возвращает адрес конечной IP-точки.

Сеть должна быть именем IP-сети.

Если хост в параметре address не является литеральным IP-адресом, ResolveIPAddr преобразует адрес в адрес конечной точки IP. В противном случае он анализирует адрес как литеральный IP-адрес. В качестве параметра адреса может использоваться имя хоста, но это не рекомендуется, так как будет возвращен не более одного из IP-адресов имени хоста.

Описание параметров сети и адреса см. в разделе func Dial.

func (*IPAddr) Сеть

func (a *IPAddr) Network() string

Network возвращает сетевое имя адреса, “ip”.

func (*IPAddr) String

func (a *IPAddr) String() string

type IPConn

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

IPConn - это реализация интерфейсов Conn и PacketConn для сетевых IP-соединений.

func DialIP

func DialIP(network string, laddr, raddr *IPAddr) (*IPConn, error)

DialIP действует как Dial для IP-сетей.

Сеть должна быть именем IP-сети; подробности см. в func Dial.

Если laddr равен nil, автоматически выбирается локальный адрес. Если поле IP в raddr равно nil или является неопределенным IP-адресом, предполагается локальная система.

func ListenIP

func ListenIP(network string, laddr *IPAddr) (*IPConn, error)

ListenIP действует как ListenPacket для IP-сетей.

Сеть должна быть именем IP-сети; подробности см. в func Dial.

Если поле IP в laddr равно nil или неопределенному IP-адресу, ListenIP прослушивает все доступные IP-адреса локальной системы, кроме IP-адресов многоадресной рассылки.

func (*IPConn) Закрыть

func (c *IPConn) Close() error

Close закрывает соединение.

func (*IPConn) File

func (c *IPConn) File() (f *os.File, err error)

File возвращает копию базового файла os.File. Ответственность за закрытие f по завершении работы лежит на вызывающей стороне. Закрытие c не влияет на f, а закрытие f не влияет на c.

Дескриптор файла возвращаемого os.File отличается от дескриптора соединения. Попытка изменить свойства оригинала с помощью этого дубликата может привести к желаемому результату, а может и не привести.

func (*IPConn) LocalAddr

func (c *IPConn) LocalAddr() Addr

LocalAddr возвращает адрес локальной сети. Возвращаемый Addr является общим для всех вызовов LocalAddr, поэтому не следует его изменять.

func (*IPConn) Read

func (c *IPConn) Read(b []byte) (int, error)

Read реализует метод Conn Read.

func (*IPConn) ReadFrom

func (c *IPConn) ReadFrom(b []byte) (int, Addr, error)

ReadFrom реализует метод PacketConn ReadFrom.

func (*IPConn) ReadFromIP

func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error)

ReadFromIP действует как ReadFrom, но возвращает IPAddr.

func (*IPConn) ReadMsgIP

func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error)

ReadMsgIP считывает сообщение из c, копируя полезную нагрузку в b и связанные с ней внеполосные данные в oob. Возвращается количество байт, скопированных в b, количество байт, скопированных в oob, флаги, которые были установлены для сообщения, и адрес источника сообщения.

Пакеты golang.org/x/net/ipv4 и golang.org/x/net/ipv6 могут быть использованы для манипулирования опциями сокетов IP-уровня в oob.

func (*IPConn) RemoteAddr

func (c *IPConn) RemoteAddr() Addr

RemoteAddr возвращает удаленный сетевой адрес. Возвращаемый Addr является общим для всех вызовов RemoteAddr, поэтому не изменяйте его.

func (*IPConn) SetDeadline

func (c *IPConn) SetDeadline(t time.Time) error

SetDeadline реализует метод Conn SetDeadline.

func (*IPConn) SetReadBuffer

func (c *IPConn) SetReadBuffer(bytes int) error

SetReadBuffer устанавливает размер буфера приема операционной системы, связанного с соединением.

func (*IPConn) SetReadDeadline

func (c *IPConn) SetReadDeadline(t time.Time) error

SetReadDeadline реализует метод Conn SetReadDeadline.

func (*IPConn) SetWriteBuffer

func (c *IPConn) SetWriteBuffer(bytes int) error

SetWriteBuffer устанавливает размер буфера передачи операционной системы, связанного с соединением.

func (*IPConn) SetWriteDeadline

func (c *IPConn) SetWriteDeadline(t time.Time) error

SetWriteDeadline реализует метод Conn SetWriteDeadline.

func (*IPConn) SyscallConn

func (c *IPConn) SyscallConn() (syscall.RawConn, error)

SyscallConn возвращает необработанное сетевое соединение. Оно реализует интерфейс syscall.Conn.

func (*IPConn) Write

func (c *IPConn) Write(b []byte) (int, error)

Write реализует метод Conn Write.

func (*IPConn) WriteMsgIP

func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error)

WriteMsgIP записывает сообщение на addr через c, копируя полезную нагрузку из b и связанные с ней внеполосные данные из oob. Возвращается количество записанных байт полезной нагрузки и внеполосных данных.

Пакеты golang.org/x/net/ipv4 и golang.org/x/net/ipv6 могут быть использованы для манипулирования опциями сокетов IP-уровня в oob.

func (*IPConn) WriteTo

func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error)

WriteTo реализует метод PacketConn WriteTo.

func (*IPConn) WriteToIP

func (c *IPConn) WriteToIP(b []байт, addr *IPAddr) (int, error)

WriteToIP действует подобно IPConn.WriteTo, но принимает IPAddr.

type IPMask

type IPMask []байт

IPMask - это битовая маска, которая может быть использована для манипулирования IP-адресами для IP-адресации и маршрутизации.

Подробнее см. в разделе type IPNet и func ParseCIDR.

func CIDRMask

func CIDRMask(ones, bits int) IPMask

CIDRMask возвращает IPMask, состоящую из битов ‘ones’ 1, за которыми следуют 0 до общей длины ‘bits’ бит. Для маски такой формы CIDRMask является обратной величиной к IPMask.Size.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	// This mask corresponds to a /31 subnet for IPv4.
	fmt.Println(net.CIDRMask(31, 32))

	// This mask corresponds to a /64 subnet for IPv6.
	fmt.Println(net.CIDRMask(64, 128))

}
Output:

fffffffe
ffffffffffffffff0000000000000000

func IPv4Mask

func IPv4Mask(a, b, c, d byte) IPMask

IPv4Mask возвращает IP-маску (в 4-байтовой форме) IPv4-маски a.b.c.d.

Пример
package main

import (
	"fmt"
	"net"
)

func main() {
	fmt.Println(net.IPv4Mask(255, 255, 255, 0))

}
Output:

ffffff00

func (IPMask) Size

func (m IPMask) Size() (ones, bits int)

Size возвращает количество ведущих единиц и общее количество битов в маске. Если маска не имеет канонической формы - за единицами следуют нули - то Size возвращает 0, 0.

func (IPMask) String

func (m IPMask) String() string

String возвращает шестнадцатеричную форму m, без знаков препинания.

type IPNet

type IPNet struct {
	IP IP // номер сети
	Mask IPMask // маска сети
}

IPNet представляет IP-сеть.

func (*IPNet) Contains

func (n *IPNet) Contains(ip IP) bool

Contains сообщает, включает ли сеть ip.

func (*IPNet) Network

func (n *IPNet) Network() string

Network возвращает сетевое имя адреса, “ip+net”.

func (*IPNet) String

func (n *IPNet) String() string

String возвращает CIDR-нотацию n, например “192.0.2.0/24” или “2001:db8::/48”, как определено в RFC 4632 и RFC 4291. Если маска не имеет канонической формы, возвращается строка, состоящая из IP-адреса, за которым следует символ косой черты и маска, выраженная в шестнадцатеричной форме без знаков препинания, например “198.51.100.0/c000ff00”.

type Interface

type Interface struct {
	Index int // положительное целое число, начинающееся с единицы, ноль никогда не используется
	MTU int // максимальная единица передачи
	Name string // например, "en0", "lo0", "eth0.100".
	HardwareAddr HardwareAddr // форма IEEE MAC-48, EUI-48 и EUI-64
	Flags Флаги // например, FlagUp, FlagLoopback, FlagMulticast
}

Интерфейс представляет собой сопоставление между именем и индексом сетевого интерфейса. Он также представляет информацию об объекте сетевого интерфейса.

func InterfaceByIndex

func InterfaceByIndex(index int) (*Interface, error)

InterfaceByIndex возвращает интерфейс, указанный индексом.

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

func InterfaceByName

func InterfaceByName(name string) (*Interface, error)

InterfaceByName возвращает интерфейс, указанный именем.

func Интерфейсы

func Interfaces() ([]Interface, error)

Interfaces возвращает список сетевых интерфейсов системы.

func (*Interface) Addrs

func (ifi *Интерфейс) Addrs() ([]Addr, error)

Addrs возвращает список адресов одноадресных интерфейсов для конкретного интерфейса.

func (*Interface) MulticastAddrs

func (ifi *Интерфейс) MulticastAddrs() ([]Addr, error)

MulticastAddrs возвращает список адресов многоадресной рассылки, объединенных групп для определенного интерфейса.

type InvalidAddrError

type InvalidAddrError string

func (InvalidAddrError) Error

func (e InvalidAddrError) Error() string

func (InvalidAddrError) Temporary

func (e InvalidAddrError) Temporary() bool

func (InvalidAddrError) Timeout

func (e InvalidAddrError) Timeout() bool

type KeepAliveConfig

type KeepAliveConfig struct {
	// Если Enable равно true, то зонды keep-alive включены.
	Enable bool

	// Idle - время, в течение которого соединение должно простаивать, прежде чем
	// отправки первого зонда keep-alive.
	// Если значение равно нулю, то по умолчанию используется значение 15 секунд.
	Idle time.Duration

	// Интервал - время между зондами keep-alive.
	// Если ноль, по умолчанию используется значение 15 секунд.
	Interval time.Duration

	// Count - максимальное количество зондов keep-alive, которые
	// может остаться без ответа до разрыва соединения.
	// Если значение равно нулю, то по умолчанию используется значение 9.
	Count int
}

KeepAliveConfig содержит параметры TCP keep-alive.

Если поля Idle, Interval или Count равны нулю, выбирается значение по умолчанию. Если поле отрицательно, соответствующая опция уровня сокета будет оставлена без изменений.

Обратите внимание, что до версии Windows 10 1709 ни установка Idle и Interval по отдельности, ни изменение Count (которое обычно равно 10) не поддерживаются. Поэтому, если вы хотите настроить параметры TCP keep-alive, рекомендуется установить неотрицательные значения Idle и Interval в сочетании с -1 для Count в старых версиях Windows. Напротив, если только один из Idle и Interval установлен в неотрицательное значение, другой будет установлен в значение по умолчанию, и в конечном итоге установите оба Idle и Interval в отрицательные значения, если вы хотите оставить их без изменений.

Обратите внимание, что Solaris и ее производные не поддерживают установку Interval в неотрицательное значение и Count в отрицательное значение, или наоборот.

type ListenConfig

type ListenConfig struct {
	// Если Control не nil, то вызывается после создания сетевого
	// соединения, но до его привязки к операционной системе.
	//
	// Параметры сети и адреса, передаваемые в функцию Control, не являются
	// обязательно те, которые передаются в функцию Listen. Вызов Listen с сетями TCP
	// приведет к вызову функции Control с параметрами "tcp4" или "tcp6",
	// UDP-сети станут "udp4" или "udp6", IP-сети - "ip4" или "ip6",
	// и другие известные сети передаются как есть.
	Control func(network, address string, c syscall.RawConn) error

	// KeepAlive задает период ожидания для сетевых
	// соединений, принимаемых этим слушателем.
	//
	// KeepAlive игнорируется, если KeepAliveConfig.Enable равен true.
	//
	// Если ноль, то keep-alive включается, если поддерживается протоколом
	// и операционной системой. Сетевые протоколы или операционные системы.
	// которые не поддерживают keep-alive, игнорируют это поле.
	// Если значение отрицательно, keep-alive отключены.
	KeepAlive time.Duration

	// KeepAliveConfig определяет конфигурацию зонда keep-alive
	// для активного сетевого соединения, если оно поддерживается
	// протоколом и операционной системой.
	//
	// Если KeepAliveConfig.Enable равен true, то зонды keep-alive включены.
	// Если KeepAliveConfig.Enable ложно и KeepAlive отрицательно,
	// зонды keep-alive отключены.
	KeepAliveConfig KeepAliveConfig
	// содержит отфильтрованные или неэкспонированные поля
}

ListenConfig содержит опции для прослушивания адреса.

func (*ListenConfig) Listen

func (lc *ListenConfig) Listen(ctx context.Context, network, address string) (Listener, error)

Listener сообщает об адресе локальной сети.

Описание параметров сети и адреса см. в разделе func Listen.

Аргумент ctx используется при разрешении адреса для прослушивания; он не влияет на возвращаемый error.

func (*ListenConfig) ListenPacket

func (lc *ListenConfig) ListenPacket(ctx context.Context, network, address string) (PacketConn, error)

ListenPacket сообщает об адресе локальной сети.

Описание параметров сети и адреса см. в func ListenPacket.

Аргумент ctx используется при разрешении адреса для прослушивания; он не влияет на возвращаемый слушатель.

func (*ListenConfig) MultipathTCP

func (lc *ListenConfig) MultipathTCP() bool

MultipathTCP сообщает, будет ли использоваться MPTCP.

Этот метод не проверяет, поддерживается ли MPTCP операционной системой или нет.

func (*ListenConfig) SetMultipathTCP

func (lc *ListenConfig) SetMultipathTCP(use bool)

SetMultipathTCP направляет метод Listen на использование или неиспользование MPTCP, если это поддерживается операционной системой. Этот метод отменяет системное значение по умолчанию и настройку GODEBUG=multipathtcp=…, если таковая имеется.

Если MPTCP недоступен на хосте или не поддерживается клиентом, метод Listen вернется к TCP.

type Listener ¶

type Listener interface {
	// Accept ожидает и возвращает следующее соединение со слушателем.
	Accept() (Conn, error)

	// Close закрывает слушателя.
	// Любые заблокированные операции Accept будут разблокированы и вернут ошибки.
	Close() error

	// Addr возвращает сетевой адрес слушателя.
	Addr() Addr
}

Listener - это общий сетевой слушатель для потоково-ориентированных протоколов.

Несколько горутинов могут одновременно вызывать методы одного Listener.

Пример
package main

import (
	"io"
	"log"
	"net"
)

func main() {
	// Listen on TCP port 2000 on all available unicast and
	// anycast IP addresses of the local system.
	l, err := net.Listen("tcp", ":2000")
	if err != nil {
		log.Fatal(err)
	}
	defer l.Close()
	for {
		// Wait for a connection.
		conn, err := l.Accept()
		if err != nil {
			log.Fatal(err)
		}
		// Handle the connection in a new goroutine.
		// The loop then returns to accepting, so that
		// multiple connections may be served concurrently.
		go func(c net.Conn) {
			// Echo all incoming data.
			io.Copy(c, c)
			// Shut down the connection.
			c.Close()
		}(conn)
	}
}

func FileListener

func FileListener(f *os.File) (ln Listener, err error)

FileListener возвращает копию сетевого слушателя, соответствующего открытому файлу f. Ответственность за закрытие ln по завершении работы лежит на вызывающей стороне. Закрытие ln не влияет на f, а закрытие f не влияет на ln.

func Listen

func Listen(network, address string) (Listener, error)

Listener сообщает об адресе локальной сети.

Сеть должна быть “tcp”, “tcp4”, “tcp6”, “unix” или “unixpacket”.

Для TCP-сетей, если параметр host в параметре address пуст или является буквальным неуказанным IP-адресом, Listen прослушивает все доступные одноадресные и одноадресные IP-адреса локальной системы. Чтобы использовать только IPv4, используйте сеть “tcp4”. В качестве адреса может использоваться имя хоста, но это не рекомендуется, поскольку в этом случае будет создан слушатель только для одного из IP-адресов хоста. Если порт в параметре адреса пустой или “0”, как в “127.0.0.1:” или “[::1]:0”, номер порта выбирается автоматически. Для определения выбранного порта можно использовать метод Addr Слушателя.

Описание параметров сети и адреса см. в func Dial.

Listen внутренне использует context.Background; чтобы указать контекст, используйте ListenConfig.Listen.

type MX

type MX struct {
	Host string
	Pref uint16
}

MX представляет собой одну запись DNS MX.

func LookupMX

func LookupMX(name string) ([]*MX, error)

LookupMX возвращает DNS MX-записи для заданного доменного имени, отсортированные по предпочтениям.

Возвращаемые имена почтовых серверов проверяются на правильность форматирования доменных имен в формате представления. Если ответ содержит недопустимые имена, эти записи отфильтровываются, и вместе с оставшимися результатами, если таковые имеются, возвращается ошибка.

Внутри LookupMX используется context.Background; чтобы указать контекст, используйте Resolver.LookupMX.

type NS

type NS struct {
	Host string
}

NS представляет собой одну запись DNS NS.

func LookupNS

func LookupNS(name string) ([]*NS, error)

LookupNS возвращает записи DNS NS для заданного доменного имени.

Возвращаемые имена серверов имен проверяются на правильность форматирования доменных имен в формате представления. Если в ответе содержатся недопустимые имена, эти записи отфильтровываются, и вместе с оставшимися результатами возвращается ошибка, если таковая имеется.

Внутри LookupNS используется context.Background; чтобы указать контекст, используйте Resolver.LookupNS.

type OpError

type OpError struct {
	// Op - это операция, вызвавшая ошибку, например.
	// "чтение" или "запись".
	Op string

	// Net - тип сети, в которой произошла ошибка,
	// например, "tcp" или "udp6".
	Net string

	// Для операций, связанных с удаленным сетевым соединением, например.
	// набор, чтение или запись, Source - это соответствующий локальный
	// сетевой адрес.
	Source Addr 

	// Addr - это сетевой адрес, для которого произошла ошибка.
	// Для локальных операций, таких как Listen или SetDeadline, Addr - это
	// адрес локальной конечной точки, с которой производится манипуляция.
	// Для операций с удаленным сетевым соединением, таких как.
	// Dial, Read или Write, Addr - это удаленный адрес этого
	// соединения.
	Addr Addr

	// Err - это ошибка, произошедшая во время операции.
	// Метод Error паникует, если ошибка равна nil.
	Err error
}

OpError - это тип ошибки, обычно возвращаемый функциями пакета net. Он описывает операцию, тип сети и адрес ошибки.

func (*OpError) Error

func (e *OpError) Error() string

func (*OpError) Temporary

func (e *OpError) Temporary() bool

func (*OpError) Timeout

func (e *OpError) Timeout() bool

func (*OpError) Unwrap

func (e *OpError) Unwrap() error

type PacketConn

type PacketConn interface {
	// ReadFrom читает пакет из соединения,
	// копируя полезную нагрузку в p. Возвращается количество
	// байт, скопированных в p, и адрес возврата, который
	// был в пакете.
	// Возвращается количество прочитанных байт (0 <= n <= len(p))
	// и любую возникшую ошибку. Вызывающая сторона всегда должна обрабатывать
	// возвращенные n > 0 байт, прежде чем рассматривать ошибку err.
	// ReadFrom можно сделать так, чтобы тайм-аут и возврат ошибки происходили через
	// фиксированного лимита времени; см. SetDeadline и SetReadDeadline.
	ReadFrom(p []byte) (n int, addr Addr, err error)

	// WriteTo записывает пакет с полезной нагрузкой p в addr.
	// WriteTo можно сделать так, чтобы по истечении фиксированного времени она завершилась и вернула ошибку.
	// фиксированного лимита времени; см. SetDeadline и SetWriteDeadline.
	// На пакетно-ориентированных соединениях таймаут записи случается редко.
	WriteTo(p []byte, addr Addr) (n int, err error)

	// Close закрывает соединение.
	// Любые заблокированные операции ReadFrom или WriteTo будут разблокированы и вернут ошибки.
	Close() error

	// LocalAddr возвращает адрес локальной сети, если он известен.
	LocalAddr() Addr

	// SetDeadline устанавливает крайние сроки чтения и записи, связанные
	// с данным соединением. Это эквивалентно вызову обеих функций.
	// SetReadDeadline и SetWriteDeadline.
	//
	// Крайний срок - это абсолютное время, по истечении которого операции ввода-вывода
	// прекращаются, а не блокируются. Крайний срок применяется ко всем будущим
	// и ожидающим операциям ввода-вывода, а не только к непосредственно следующему вызову
	// чтения или записи. После превышения крайнего срока
	// соединение можно обновить, установив крайний срок в будущем.
	//
	// Если крайний срок превышен, вызов Read или Write или других
	// методы ввода/вывода вернут ошибку, обернутую в os.ErrDeadlineExceeded.
	// Это можно проверить с помощью errors.Is(err, os.ErrDeadlineExceeded).
	// Метод Timeout ошибки вернет true, но обратите внимание, что существуют
	// есть и другие возможные ошибки, для которых метод Timeout
	// вернет true, даже если срок не был превышен.
	//
	// Таймаут ожидания может быть реализован путем многократного продления
	// крайнего срока после успешных вызовов ReadFrom или WriteTo.
	//
	// Нулевое значение t означает, что операции ввода-вывода не будут выполняться по тайм-ауту.
	SetDeadline(t time.Time) error

	// SetReadDeadline устанавливает крайний срок для будущих вызовов ReadFrom
	// и любого заблокированного в данный момент вызова ReadFrom.
	// Нулевое значение t означает, что ReadFrom не будет завершаться по времени.
	SetReadDeadline(t time.Time) error

	// SetWriteDeadline устанавливает крайний срок для будущих вызовов WriteTo
	// и любого текущего заблокированного вызова WriteTo.
	// Даже если запись завершилась, она может вернуть n > 0, указывая на то, что
	// часть данных была успешно записана.
	// Нулевое значение t означает, что WriteTo не прервется.
	SetWriteDeadline(t time.Time) error
}

PacketConn - это общее сетевое соединение, ориентированное на пакеты.

Несколько горутинов могут вызывать методы на PacketConn одновременно.

func FilePacketConn

func FilePacketConn(f *os.File) (c PacketConn, err error)

FilePacketConn возвращает копию пакетного сетевого соединения, соответствующего открытому файлу f. Ответственность за закрытие f по завершении работы лежит на вызывающей стороне. Закрытие c не влияет на f, а закрытие f не влияет на c.

func ListenPacket

func ListenPacket(network, address string) (PacketConn, error)

ListenPacket сообщает адрес локальной сети.

Сеть должна быть “udp”, “udp4”, “udp6”, “unixgram” или IP-транспортом. IP-транспорт - это “ip”, “ip4” или “ip6”, за которым следует двоеточие и буквенный номер протокола или имя протокола, как в “ip:1” или “ip:icmp”.

Для UDP- и IP-сетей, если в параметре address значение host пустое или это буквальный неопределенный IP-адрес, ListenPacket прослушивает все доступные IP-адреса локальной системы, кроме IP-адресов многоадресной рассылки. Чтобы использовать только IPv4, используйте сеть “udp4” или “ip4:proto”. В качестве адреса можно использовать имя хоста, но это не рекомендуется, поскольку в этом случае будет создан слушатель только для одного из IP-адресов хоста. Если порт в параметре адреса пустой или “0”, как в “127.0.0.1:” или “[::1]:0”, номер порта выбирается автоматически. Для обнаружения выбранного порта можно использовать метод LocalAddr программы PacketConn.

Описание параметров сети и адреса см. в func Dial.

ListenPacket внутренне использует context.Background; чтобы указать контекст, используйте ListenConfig.ListenPacket.

type ParseError

type ParseError struct {
	// Тип - это тип ожидаемой строки, например.
	// "IP-адрес", "CIDR-адрес".
	Type string

	// Text - неправильно сформированная текстовая строка.
	Text string
}

ParseError - это тип ошибки синтаксического анализатора сетевых адресов.

func (*ParseError) Error

func (e *ParseError) Error() string

func (*ParseError) Temporary

func (e *ParseError) Temporary() bool

func (*ParseError) Timeout

func (e *ParseError) Timeout() bool

type Resolver

type Resolver struct {
	// PreferGo управляет тем, предпочтителен ли встроенный DNS-резольвер Go.
	// на платформах, где он доступен. Это эквивалентно настройке
	// GODEBUG=netdns=go, но относится только к этому резольверу.
	PreferGo bool

	// StrictErrors управляет поведением временных ошибок
	// (включая таймаут, ошибки сокетов и SERVFAIL) при использовании
	// встроенного в Go резолвера. Для запроса, состоящего из нескольких
	// подзапросов (например, поиск адреса A+AAA или переход по
	// список поиска DNS), эта опция заставляет такие ошибки прерывать
	// весь запрос, а не возвращать частичный результат. Эта опция
	// не включена по умолчанию, поскольку это может повлиять на совместимость
	// с резолверами, которые некорректно обрабатывают запросы AAAA.
	StrictErrors bool

	// Dial опционально задает альтернативный дозвон для использования
	// встроенным DNS-резольвером Go для создания TCP- и UDP-соединений
	// к службам DNS. Хост в параметре address будет
	// всегда будет буквальным IP-адресом, а не именем хоста, а
	// порт в параметре адреса будет буквальным номером порта
	// а не имя службы.
	// Если возвращаемый Conn также является PacketConn, отправленные и полученные DNS
	// сообщения должны соответствовать разделу 4.2.1 RFC 1035, "Использование UDP".
	// В противном случае DNS-сообщения, передаваемые через Conn, должны соответствовать
	// разделу 5 RFC 7766, "Выбор транспортного протокола".
	// Если nil, используется дозвонщик по умолчанию.
	Dial func(ctx context.Context, network, address string) (Conn, error)
	// содержит отфильтрованные или неэкспонированные поля
}

Резольвер ищет имена и номера.

Нулевой *Resolver эквивалентен нулевому Resolver.

func (*Resolver) LookupAddr

func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, error)

LookupAddr выполняет обратный поиск для заданного адреса, возвращая список имен, сопоставленных с этим адресом.

Возвращаемые имена проверяются на правильность форматирования доменных имен в формате представления. Если ответ содержит недопустимые имена, эти записи отфильтровываются, и вместе с оставшимися результатами, если таковые имеются, возвращается ошибка.

func (*Resolver) LookupCNAME

func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error)

LookupCNAME возвращает каноническое имя для данного хоста. Пользователи, которым не важно каноническое имя, могут вызвать LookupHost или LookupIP напрямую; оба они позаботятся о разрешении канонического имени как части поиска.

Каноническое имя - это окончательное имя после следования нуля или более записей CNAME. LookupCNAME не возвращает ошибку, если хост не содержит записей DNS “CNAME”, при условии, что хост разрешается в адресные записи.

Возвращаемое каноническое имя проверяется на то, что оно является правильно отформатированным доменным именем формата представления.

func (*Resolver) LookupHost

func (r *Resolver) LookupHost(ctx context.Context, host string) (addrs []string, err error)

LookupHost ищет заданный хост с помощью локального резольвера. Возвращается фрагмент адресов этого хоста.

func (*Resolver) LookupIP

func (r *Resolver) LookupIP(ctx context.Context, network, host string) ([]IP, error)

LookupIP ищет хост для заданной сети с помощью локального резольвера. Возвращается фрагмент IP-адресов этого хоста типа, указанного network. network должен быть одним из “ip”, “ip4” или “ip6”.

func (*Resolver) LookupIPAddr

func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, error)

LookupIPAddr ищет хост с помощью локального резольвера. Возвращается фрагмент IPv4- и IPv6-адресов этого хоста.

func (*Resolver) LookupMX

func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error)

LookupMX возвращает DNS MX-записи для заданного доменного имени, отсортированные по предпочтению.

Возвращаемые имена почтовых серверов проверяются на правильность форматирования доменных имен в формате представления. Если в ответе содержатся недопустимые имена, эти записи отфильтровываются, и вместе с оставшимися результатами, если таковые имеются, возвращается ошибка.

func (*Resolver) LookupNS

func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*NS, error)

LookupNS возвращает NS-записи DNS для заданного доменного имени.

Возвращаемые имена серверов имен проверяются на правильность форматирования доменных имен в формате представления. Если ответ содержит недопустимые имена, эти записи отфильтровываются, и вместе с оставшимися результатами, если таковые имеются, возвращается ошибка.

func (*Resolver) LookupNetIP

func (r *Resolver) LookupNetIP(ctx context.Context, network, host string) ([]netip.Addr, error)

LookupNetIP ищет хост с помощью локального резольвера. Возвращается фрагмент IP-адресов этого хоста типа, указанного в network. Сеть должна быть одной из “ip”, “ip4” или “ip6”.

func (*Resolver) LookupPort

func (r *Resolver) LookupPort(ctx context.Context, network, service string) (port int, err error)

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

Сеть должна быть одной из “tcp”, “tcp4”, “tcp6”, “udp”, “udp4”, “udp6” или “ip”.

func (*Resolver) LookupSRV

func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error)

LookupSRV пытается разрешить SRV-запрос данного сервиса, протокола и доменного имени. Протоколом является “tcp” или “udp”. Возвращаемые записи сортируются по приоритету и рандомизируются по весу в пределах приоритета.

LookupSRV строит DNS-имя для поиска в соответствии с RFC 2782. То есть, он ищет _service._proto.name. Для удобства сервисов, публикующих SRV-записи под нестандартными именами, если service и proto являются пустыми строками, LookupSRV ищет имя напрямую.

Возвращаемые имена сервисов проверяются на правильность форматирования доменных имен в формате представления. Если ответ содержит недопустимые имена, эти записи отфильтровываются и возвращается ошибка вместе с оставшимися результатами, если таковые имеются.

func (*Resolver) LookupTXT

func (r *Resolver) LookupTXT(ctx context.Context, name string) ([]string, error)

LookupTXT возвращает записи DNS TXT для заданного доменного имени.

Если DNS TXT-запись содержит несколько строк, они объединяются в одну строку.

type SRV

type SRV struct {
	Target   string
	Port     uint16
	Priority uint16
	Weight   uint16
}

SRV представляет собой одну запись DNS SRV.

func LookupSRV

func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error)

LookupSRV пытается разрешить SRV-запрос для данного сервиса, протокола и доменного имени. Протоколом является “tcp” или “udp”. Возвращаемые записи сортируются по приоритету и рандомизируются по весу в пределах приоритета.

LookupSRV строит DNS-имя для поиска в соответствии с RFC 2782. То есть, он ищет _service._proto.name. Для удобства сервисов, публикующих SRV-записи под нестандартными именами, если service и proto являются пустыми строками, LookupSRV ищет имя напрямую.

Возвращаемые имена сервисов проверяются на правильность форматирования доменных имен в формате представления. Если ответ содержит недопустимые имена, эти записи отфильтровываются, и вместе с оставшимися результатами, если таковые имеются, возвращается ошибка.

type TCPAddr

type TCPAddr struct {
	IP IP
	Port int
	Zone string // Зона масштабируемой адресации IPv6
}

TCPAddr представляет адрес конечной точки TCP.

func ResolveTCPAddr

func ResolveTCPAddr(network, address string) (*TCPAddr, error)

ResolveTCPAddr возвращает адрес конечной точки TCP.

Сеть должна быть именем TCP-сети.

Если хост в параметре address не является литеральным IP-адресом или порт не является литеральным номером порта, ResolveTCPAddr преобразует адрес в адрес конечной точки TCP. В противном случае он разбирает адрес как пару из буквального IP-адреса и номера порта. В качестве параметра address может использоваться имя хоста, но это не рекомендуется, так как вернется не более одного из IP-адресов имени хоста.

Описание параметров сети и адреса см. в разделе func Dial.

func TCPAddrFromAddrPort

func TCPAddrFromAddrPort(addr netip.AddrPort) *TCPAddr

TCPAddrFromAddrPort возвращает addr как TCPAddr. Если addr.IsValid() равен false, то возвращаемый TCPAddr будет содержать нулевое поле IP, указывающее на неопределенный адрес, не зависящий от семейства адресов.

func (*TCPAddr) AddrPort

func (a *TCPAddr) AddrPort() netip.AddrPort

AddrPort возвращает TCPAddr a в виде netip.AddrPort.

Если a.Port не помещается в uint16, он тихо усекается.

Если a равно nil, возвращается нулевое значение.

func (*TCPAddr) Network

func (a *TCPAddr) Network() string

Network возвращает сетевое имя адреса, “tcp”.

func (*TCPAddr) String

func (a *TCPAddr) String() string

type TCPConn

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

TCPConn - это реализация интерфейса Conn для сетевых соединений TCP.

func DialTCP

func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPConn, error)

DialTCP действует как Dial для сетей TCP.

Сеть должна быть именем TCP-сети; подробности см. в func Dial.

Если laddr равен nil, автоматически выбирается локальный адрес. Если поле IP в raddr равно nil или является неопределенным IP-адресом, предполагается локальная система.

func (*TCPConn) Закрыть

func (c *TCPConn) Close() error

Close закрывает соединение.

func (*TCPConn) CloseRead

func (c *TCPConn) CloseRead() error

CloseRead закрывает TCP-соединение со стороны чтения. Большинство вызывающих должны просто использовать Close.

func (*TCPConn) CloseWrite

func (c *TCPConn) CloseWrite() error

CloseWrite закрывает пишущую сторону TCP-соединения. Большинству вызывающих следует просто использовать Close.

func (*TCPConn) File

func (c *TCPConn) File() (f *os.File, err error)

File возвращает копию базового файла os.File. Ответственность за закрытие f по завершении работы лежит на вызывающей стороне. Закрытие c не влияет на f, а закрытие f не влияет на c.

Дескриптор файла возвращаемого os.File отличается от дескриптора соединения. Попытка изменить свойства оригинала с помощью этого дубликата может привести к желаемому результату, а может и не привести.

func (*TCPConn) LocalAddr

func (c *TCPConn) LocalAddr() Addr

LocalAddr возвращает адрес локальной сети. Возвращаемый Addr является общим для всех вызовов LocalAddr, поэтому не изменяйте его.

func (*TCPConn) MultipathTCP

func (c *TCPConn) MultipathTCP() (bool, error)

MultipathTCP сообщает, использует ли текущее соединение MPTCP.

Если Multipath TCP не поддерживается хостом, другим пиром или намеренно/случайно отфильтровывается каким-либо устройством между ними, будет выполнен откат к TCP. Этот метод делает все возможное, чтобы проверить, используется ли MPTCP или нет.

В Linux больше условий проверяется на ядрах >= v5.16, что улучшает результаты.

func (*TCPConn) Read

func (c *TCPConn) Read(b []byte) (int, error)

Read реализует метод Conn Read.

func (*TCPConn) ReadFrom

func (c *TCPConn) ReadFrom(r io.Reader) (int64, error)

ReadFrom реализует метод io.ReaderFrom ReadFrom.

func (*TCPConn) RemoteAddr

func (c *TCPConn) RemoteAddr() Addr

RemoteAddr возвращает адрес удаленной сети. Возвращаемый Addr является общим для всех вызовов RemoteAddr, поэтому не изменяйте его.

func (*TCPConn) SetDeadline

func (c *TCPConn) SetDeadline(t time.Time) error

SetDeadline реализует метод Conn SetDeadline.

func (*TCPConn) SetKeepAlive

func (c *TCPConn) SetKeepAlive(keepalive bool) error

SetKeepAlive устанавливает, должна ли операционная система отправлять сообщения keep-alive на соединение.

func (*TCPConn) SetKeepAliveConfig

func (c *TCPConn) SetKeepAliveConfig(config KeepAliveConfig) error

SetKeepAliveConfig настраивает сообщения keep-alive, отправляемые операционной системой.

func (*TCPConn) SetKeepAlivePeriod

func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error

SetKeepAlivePeriod устанавливает время, в течение которого соединение должно простаивать, прежде чем TCP начнет посылать keepalive зонды.

Обратите внимание, что вызов этого метода на Windows до Windows 10 версии 1709 сбросит KeepAliveInterval на системное значение по умолчанию, которое обычно составляет 1 секунду.

func (*TCPConn) SetLinger

func (c *TCPConn) SetLinger(sec int) error

SetLinger задает поведение Close на соединении, которое все еще ожидает отправки или подтверждения данных.

Если sec < 0 (по умолчанию), операционная система завершает отправку данных в фоновом режиме.

Если sec == 0, операционная система отбрасывает все неотправленные или неподтвержденные данные.

Если sec > 0, данные отправляются в фоновом режиме, как и в случае sec < 0. В некоторых операционных системах, включая Linux, это может привести к блокировке Close до тех пор, пока все данные не будут отправлены или отброшены. В некоторых операционных системах по истечении sec все оставшиеся неотправленные данные могут быть отброшены.

func (*TCPConn) SetNoDelay

func (c *TCPConn) SetNoDelay(noDelay bool) error

SetNoDelay управляет тем, должна ли операционная система задерживать передачу пакетов в надежде отправить меньше пакетов (алгоритм Нагла). По умолчанию установлено значение true (без задержки), что означает, что данные отправляются как можно быстрее после записи.

func (*TCPConn) SetReadBuffer

func (c *TCPConn) SetReadBuffer(bytes int) error

SetReadBuffer устанавливает размер буфера приема операционной системы, связанного с соединением.

func (*TCPConn) SetReadDeadline

func (c *TCPConn) SetReadDeadline(t time.Time) error

SetReadDeadline реализует метод Conn SetReadDeadline.

func (*TCPConn) SetWriteBuffer

func (c *TCPConn) SetWriteBuffer(bytes int) error

SetWriteBuffer устанавливает размер буфера передачи операционной системы, связанного с соединением.

func (*TCPConn) SetWriteDeadline

func (c *TCPConn) SetWriteDeadline(t time.Time) error

SetWriteDeadline реализует метод Conn SetWriteDeadline.

func (*TCPConn) SyscallConn

func (c *TCPConn) SyscallConn() (syscall.RawConn, error)

SyscallConn возвращает необработанное сетевое соединение. Оно реализует интерфейс syscall.Conn.

func (*TCPConn) Write

func (c *TCPConn) Write(b []byte) (int, error)

Write реализует метод записи Conn.

func (*TCPConn) WriteTo

func (c *TCPConn) WriteTo(w io.Writer) (int64, error)

WriteTo реализует метод io.WriterTo WriteTo.

type TCPListener

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

TCPListener - это сетевой слушатель TCP. Клиенты обычно должны использовать переменные типа Listener, а не предполагать, что это TCP.

func ListenTCP

func ListenTCP(network string, laddr *TCPAddr) (*TCPListener, error)

ListenTCP действует как Listen для сетей TCP.

Сеть должна быть именем TCP-сети; подробности см. в func Dial.

Если поле IP в laddr равно nil или неопределенному IP-адресу, ListenTCP прослушивает все доступные одноадресные и одноадресные IP-адреса локальной системы. Если поле Port в laddr равно 0, номер порта выбирается автоматически.

func (*TCPListener) Accept

func (l *TCPListener) Accept() (Conn, error)

Accept реализует метод Accept в интерфейсе Listener; он ожидает следующего вызова и возвращает общий Conn.

func (*TCPListener) AcceptTCP

func (l *TCPListener) AcceptTCP() (*TCPConn, error)

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

func (*TCPListener) Addr

func (l *TCPListener) Addr() Addr

Addr возвращает сетевой адрес слушателя, *TCPAddr. Возвращаемый Addr является общим для всех вызовов Addr, поэтому не изменяйте его.

func (*TCPListener) Close

func (l *TCPListener) Close() error

Close прекращает прослушивание TCP-адреса. Уже принятые соединения не закрываются.

func (*TCPListener) File

func (l *TCPListener) File() (f *os.File, err error)

File возвращает копию базового файла os.File. Ответственность за закрытие f по завершении работы лежит на вызывающей стороне. Закрытие l не влияет на f, а закрытие f не влияет на l.

Файловый дескриптор возвращаемого os.File отличается от дескриптора соединения. Попытка изменить свойства оригинала с помощью этого дубликата может привести к желаемому результату, а может и не привести.

func (*TCPListener) SetDeadline

func (l *TCPListener) SetDeadline(t time.Time) error

SetDeadline устанавливает крайний срок, связанный со слушателем. Нулевое значение времени отключает дедлайн.

func (*TCPListener) SyscallConn

func (l *TCPListener) SyscallConn() (syscall.RawConn, error)

SyscallConn возвращает необработанное сетевое соединение. Оно реализует интерфейс syscall.Conn.

Возвращаемое RawConn поддерживает только вызов Control. Чтение и запись возвращают ошибку.

type UDPAddr

type UDPAddr struct {
	IP IP
	Порт int
	Zone string // Зона масштабируемой адресации IPv6
}

UDPAddr представляет адрес конечной точки UDP.

func ResolveUDPAddr

func ResolveUDPAddr(network, address string) (*UDPAddr, error)

ResolveUDPAddr возвращает адрес конечной точки UDP.

Сеть должна быть именем UDP-сети.

Если хост в параметре address не является литеральным IP-адресом или порт не является литеральным номером порта, ResolveUDPAddr преобразует адрес в адрес конечной точки UDP. В противном случае он разбирает адрес как пару из буквального IP-адреса и номера порта. В качестве параметра address может использоваться имя хоста, но это не рекомендуется, так как вернется не более одного из IP-адресов имени хоста.

Описание параметров сети и адреса см. в разделе func Dial.

func UDPAddrFromAddrPort

func UDPAddrFromAddrPort(addr netip.AddrPort) *UDPAddr

UDPAddrFromAddrPort возвращает addr как UDPAddr. Если addr.IsValid() равен false, то возвращаемый UDPAddr будет содержать нулевое поле IP, указывающее на неопределенный адрес, не зависящий от семейства адресов.

func (*UDPAddr) AddrPort

func (a *UDPAddr) AddrPort() netip.AddrPort

AddrPort возвращает UDPAddr a в виде netip.AddrPort.

Если a.Port не помещается в uint16, он тихо усекается.

Если a равно nil, возвращается нулевое значение.

func (*UDPAddr) Network

func (a *UDPAddr) Network() string

Network возвращает сетевое имя адреса, “udp”.

func (*UDPAddr) String

func (a *UDPAddr) String() string

type UDPConn

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

UDPConn - это реализация интерфейсов Conn и PacketConn для сетевых соединений UDP.

func DialUDP

func DialUDP(network string, laddr, raddr *UDPAddr) (*UDPConn, error)

DialUDP действует как Dial для сетей UDP.

Сеть должна быть именем UDP-сети; подробности см. в func Dial.

Если laddr равно nil, автоматически выбирается локальный адрес. Если поле IP в raddr равно nil или является неопределенным IP-адресом, предполагается локальная система.

func ListenMulticastUDP

func ListenMulticastUDP(network string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error)

ListenMulticastUDP действует подобно ListenPacket для UDP сетей, но принимает групповой адрес на определенном сетевом интерфейсе.

Сеть должна быть именем UDP-сети; подробности см. в func Dial.

ListenMulticastUDP прослушивает все доступные IP-адреса локальной системы, включая групповой, многоадресный IP-адрес. Если ifi равно nil, ListenMulticastUDP использует назначенный системой многоадресный интерфейс, хотя это не рекомендуется, поскольку назначение зависит от платформ и иногда может потребовать настройки маршрутизации. Если поле Port в gaddr равно 0, номер порта выбирается автоматически.

ListenMulticastUDP предназначен только для удобства простых, небольших приложений. Для общего назначения существуют пакеты golang.org/x/net/ipv4 и golang.org/x/net/ipv6.

Обратите внимание, что ListenMulticastUDP установит опцию сокета IP_MULTICAST_LOOP в 0 в IPPROTO_IP, чтобы отключить обратную петлю для многоадресных пакетов.

func ListenUDP

func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error)

ListenUDP действует как ListenPacket для сетей UDP.

Сеть должна быть именем UDP-сети; подробности см. в func Dial.

Если поле IP в laddr равно nil или неопределенному IP-адресу, ListenUDP прослушивает все доступные IP-адреса локальной системы, кроме IP-адресов многоадресной рассылки. Если поле Port в laddr равно 0, номер порта выбирается автоматически.

func (*UDPConn) Close

func (c *UDPConn) Close() error

Close закрывает соединение.

func (*UDPConn) File

func (c *UDPConn) File() (f *os.File, err error)

File возвращает копию базового файла os.File. Ответственность за закрытие f по завершении работы лежит на вызывающей стороне. Закрытие c не влияет на f, а закрытие f не влияет на c.

Дескриптор файла возвращаемого os.File отличается от дескриптора соединения. Попытка изменить свойства оригинала с помощью этого дубликата может привести к желаемому результату, а может и не привести.

func (*UDPConn) LocalAddr

func (c *UDPConn) LocalAddr() Addr

LocalAddr возвращает адрес локальной сети. Возвращаемый Addr является общим для всех вызовов LocalAddr, поэтому не изменяйте его.

func (*UDPConn) Read

func (c *UDPConn) Read(b []byte) (int, error)

Read реализует метод Conn Read.

func (*UDPConn) ReadFrom

func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error)

ReadFrom реализует метод PacketConn ReadFrom.

func (*UDPConn) ReadFromUDP

func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error)

ReadFromUDP действует как UDPConn.ReadFrom, но возвращает UDPAddr.

func (*UDPConn) ReadFromUDPAddrPort

func (c *UDPConn) ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error)

ReadFromUDPAddrPort действует аналогично ReadFrom, но возвращает netip.AddrPort.

Если c привязан к неопределенному адресу, возвращаемый адрес netip.AddrPort может быть IPv4-маппированным IPv6-адресом. Используйте netip.Addr.Unmap, чтобы получить адрес без префикса IPv6.

func (*UDPConn) ReadMsgUDP

func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error)

ReadMsgUDP считывает сообщение из c, копируя полезную нагрузку в b и связанные с ней внеполосные данные в oob. Возвращается количество байт, скопированных в b, количество байт, скопированных в oob, флаги, которые были установлены для сообщения, и адрес источника сообщения.

Пакеты golang.org/x/net/ipv4 и golang.org/x/net/ipv6 могут быть использованы для манипулирования опциями сокетов IP-уровня в oob.

func (*UDPConn) ReadMsgUDPAddrPort

func (c *UDPConn) ReadMsgUDPAddrPort(b, oob []byte) (n, oobn, flags int, addr netip.AddrPort, err error)

ReadMsgUDPAddrPort подобен UDPConn.ReadMsgUDP, но возвращает netip.AddrPort вместо UDPAddr.

func (*UDPConn) RemoteAddr

func (c *UDPConn) RemoteAddr() Addr

RemoteAddr возвращает адрес удаленной сети. Возвращаемый Addr является общим для всех вызовов RemoteAddr, поэтому не изменяйте его.

func (*UDPConn) SetDeadline

func (c *UDPConn) SetDeadline(t time.Time) error

SetDeadline реализует метод Conn SetDeadline.

func (*UDPConn) SetReadBuffer

func (c *UDPConn) SetReadBuffer(bytes int) error

SetReadBuffer устанавливает размер буфера приема операционной системы, связанного с соединением.

func (*UDPConn) SetReadDeadline

func (c *UDPConn) SetReadDeadline(t time.Time) error

SetReadDeadline реализует метод Conn SetReadDeadline.

func (*UDPConn) SetWriteBuffer

func (c *UDPConn) SetWriteBuffer(bytes int) error

SetWriteBuffer устанавливает размер буфера передачи операционной системы, связанного с соединением.

func (*UDPConn) SetWriteDeadline

func (c *UDPConn) SetWriteDeadline(t time.Time) error

SetWriteDeadline реализует метод Conn SetWriteDeadline.

func (*UDPConn) SyscallConn

func (c *UDPConn) SyscallConn() (syscall.RawConn, error)

SyscallConn возвращает необработанное сетевое соединение. Оно реализует интерфейс syscall.Conn.

func (*UDPConn) Write

func (c *UDPConn) Write(b []byte) (int, error)

Write реализует метод записи Conn.

func (*UDPConn) WriteMsgUDP

func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error)

WriteMsgUDP записывает сообщение на addr через c, если c не подключен, или на удаленный адрес c, если c подключен (в этом случае addr должен быть nil). Полезная нагрузка копируется из b, а связанные с ней внеполосные данные - из oob. Возвращает количество записанных байтов полезной нагрузки и внеполосных данных.

Пакеты golang.org/x/net/ipv4 и golang.org/x/net/ipv6 могут быть использованы для манипулирования опциями сокетов IP-уровня в oob.

func (*UDPConn) WriteMsgUDPAddrPort

func (c *UDPConn) WriteMsgUDPAddrPort(b, oob []byte, addr netip.AddrPort) (n, oobn int, err error)

WriteMsgUDPAddrPort подобен UDPConn.WriteMsgUDP, но принимает netip.AddrPort вместо UDPAddr.

func (*UDPConn) WriteTo

func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error)

WriteTo реализует метод PacketConn WriteTo.

Пример
package main

import (
	"log"
	"net"
)

func main() {
	// Unlike Dial, ListenPacket creates a connection without any
	// association with peers.
	conn, err := net.ListenPacket("udp", ":0")
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	dst, err := net.ResolveUDPAddr("udp", "192.0.2.1:2000")
	if err != nil {
		log.Fatal(err)
	}

	// The connection can write data to the desired address.
	_, err = conn.WriteTo([]byte("data"), dst)
	if err != nil {
		log.Fatal(err)
	}
}

func (*UDPConn) WriteToUDP

func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error)

WriteToUDP действует как UDPConn.WriteTo, но принимает UDPAddr.

func (*UDPConn) WriteToUDPAddrPort

func (c *UDPConn) WriteToUDPAddrPort(b []byte, addr netip.AddrPort) (int, error)

WriteToUDPAddrPort действует как UDPConn.WriteTo, но принимает netip.AddrPort.

type UnixAddr

type UnixAddr struct {
	строка имени
	Net string
}

UnixAddr представляет адрес конечной точки сокета домена Unix.

func ResolveUnixAddr

func ResolveUnixAddr(network, address string) (*UnixAddr, error)

ResolveUnixAddr возвращает адрес конечной точки сокета домена Unix.

Сеть должна быть именем сети Unix.

Описание параметров сети и адреса см. в разделе func Dial.

func (*UnixAddr) Network

func (a *UnixAddr) Network() string

Network возвращает сетевое имя адреса, “unix”, “unixgram” или “unixpacket”.

func (*UnixAddr) String

func (a *UnixAddr) String() string

type UnixConn

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

UnixConn - это реализация интерфейса Conn для соединений с сокетами домена Unix.

func DialUnix

func DialUnix(network string, laddr, raddr *UnixAddr) (*UnixConn, error)

DialUnix действует как Dial для сетей Unix.

Сеть должна быть именем сети Unix; подробности см. в func Dial.

Если laddr не равен nil, он используется в качестве локального адреса для соединения.

func ListenUnixgram

func ListenUnixgram(network string, laddr *UnixAddr) (*UnixConn, error)

ListenUnixgram действует как ListenPacket для сетей Unix.

Сеть должна быть “unixgram”.

func (*UnixConn) Закрыть

func (c *UnixConn) Close() error

Close закрывает соединение.

func (*UnixConn) CloseRead

func (c *UnixConn) CloseRead() error

CloseRead закрывает сторону чтения соединения с доменом Unix. Большинство вызывающих должны просто использовать Close.

func (*UnixConn) CloseWrite

func (c *UnixConn) CloseWrite() error

CloseWrite закрывает пишущую сторону соединения с доменом Unix. Большинство вызывающих должны просто использовать Close.

func (*UnixConn) File

func (c *UnixConn) File() (f *os.File, err error)

File возвращает копию базового файла os.File. Ответственность за закрытие f по завершении работы лежит на вызывающей стороне. Закрытие c не влияет на f, а закрытие f не влияет на c.

Дескриптор файла возвращаемого os.File отличается от дескриптора соединения. Попытка изменить свойства оригинала с помощью этого дубликата может привести к желаемому результату, а может и не привести.

func (*UnixConn) LocalAddr

func (c *UnixConn) LocalAddr() Addr

LocalAddr возвращает адрес локальной сети. Возвращаемый Addr является общим для всех вызовов LocalAddr, поэтому не изменяйте его.

func (*UnixConn) Read

func (c *UnixConn) Read(b []byte) (int, error)

Read реализует метод Conn Read.

func (*UnixConn) ReadFrom

func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error)

ReadFrom реализует метод PacketConn ReadFrom.

func (*UnixConn) ReadFromUnix

func (c *UnixConn) ReadFromUnix(b []byte) (int, *UnixAddr, error)

ReadFromUnix действует как UnixConn.ReadFrom, но возвращает UnixAddr.

func (*UnixConn) ReadMsgUnix

func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error)

ReadMsgUnix считывает сообщение из c, копируя полезную нагрузку в b и связанные с ней внеполосные данные в oob. Возвращается количество байт, скопированных в b, количество байт, скопированных в oob, флаги, которые были установлены для сообщения, и адрес источника сообщения.

Обратите внимание, что если len(b) == 0 и len(oob) > 0, эта функция все равно прочитает (и отбросит) 1 байт из соединения.

func (*UnixConn) RemoteAddr

func (c *UnixConn) RemoteAddr() Addr

RemoteAddr возвращает адрес удаленной сети. Возвращаемый Addr является общим для всех вызовов RemoteAddr, поэтому не изменяйте его.

func (*UnixConn) SetDeadline

func (c *UnixConn) SetDeadline(t time.Time) error

SetDeadline реализует метод Conn SetDeadline.

func (*UnixConn) SetReadBuffer

func (c *UnixConn) SetReadBuffer(bytes int) error

SetReadBuffer устанавливает размер буфера приема операционной системы, связанного с соединением.

func (*UnixConn) SetReadDeadline

func (c *UnixConn) SetReadDeadline(t time.Time) error

SetReadDeadline реализует метод Conn SetReadDeadline.

func (*UnixConn) SetWriteBuffer

func (c *UnixConn) SetWriteBuffer(bytes int) error

SetWriteBuffer устанавливает размер буфера передачи операционной системы, связанного с соединением.

func (*UnixConn) SetWriteDeadline

func (c *UnixConn) SetWriteDeadline(t time.Time) error

SetWriteDeadline реализует метод Conn SetWriteDeadline.

func (*UnixConn) SyscallConn

func (c *UnixConn) SyscallConn() (syscall.RawConn, error)

SyscallConn возвращает необработанное сетевое соединение. Оно реализует интерфейс syscall.Conn.

func (*UnixConn) Write

func (c *UnixConn) Write(b []byte) (int, error)

Write реализует метод Conn Write.

func (*UnixConn) WriteMsgUnix

func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error)

WriteMsgUnix записывает сообщение в addr через c, копируя полезную нагрузку из b и связанные с ней внеполосные данные из oob. Возвращается количество записанных байт полезной нагрузки и внеполосных данных.

Обратите внимание, что если len(b) == 0 и len(oob) > 0, эта функция все равно запишет 1 байт в соединение.

func (*UnixConn) WriteTo

func (c *UnixConn) WriteTo(b []byte, addr Addr) (int, error)

WriteTo реализует метод PacketConn WriteTo.

func (*UnixConn) WriteToUnix

func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (int, error)

WriteToUnix действует как UnixConn.WriteTo, но принимает UnixAddr.

type UnixListener

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

UnixListener - это слушатель сокетов домена Unix. Клиенты обычно должны использовать переменные типа Listener вместо того, чтобы предполагать сокеты домена Unix.

func ListenUnix

func ListenUnix(network string, laddr *UnixAddr) (*UnixListener, error)

ListenUnix действует как Listen для сетей Unix.

Сеть должна быть “unix” или “unixpacket”.

func (*UnixListener) Принять

func (l *UnixListener) Accept() (Conn, error)

Accept реализует метод Accept в интерфейсе Listener. Возвращаемые соединения будут иметь тип *UnixConn.

func (*UnixListener) AcceptUnix

func (l *UnixListener) AcceptUnix() (*UnixConn, error)

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

func (*UnixListener) Addr

func (l *UnixListener) Addr() Addr

Addr возвращает сетевой адрес слушателя. Возвращаемый Addr является общим для всех вызовов Addr, поэтому не изменяйте его.

func (*UnixListener) Close

func (l *UnixListener) Close() error

Close прекращает прослушивание Unix-адреса. Уже принятые соединения не закрываются.

func (*UnixListener) File

func (l *UnixListener) File() (f *os.File, err error)

File возвращает копию базового файла os.File. Ответственность за закрытие f по завершении работы лежит на вызывающей стороне. Закрытие l не влияет на f, а закрытие f не влияет на l.

Файловый дескриптор возвращаемого os.File отличается от дескриптора соединения. Попытки изменить свойства оригинала с помощью этого дубликата могут привести к желаемому результату, а могут и не привести.

func (*UnixListener) SetDeadline

func (l *UnixListener) SetDeadline(t time.Time) error

SetDeadline устанавливает крайний срок, связанный со слушателем. Нулевое значение времени отключает дедлайн.

func (*UnixListener) SetUnlinkOnClose

func (l *UnixListener) SetUnlinkOnClose(unlink bool)

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

Поведение по умолчанию заключается в том, что файл сокета отсоединяется только тогда, когда пакет net создал его. То есть, если слушатель и базовый файл сокета были созданы вызовом Listen или ListenUnix, то по умолчанию закрытие слушателя приведет к удалению файла сокета. Но если слушатель был создан вызовом FileListener для использования уже существующего файла сокета, то по умолчанию закрытие слушателя не приведет к удалению файла сокета.

func (*UnixListener) SyscallConn

func (l *UnixListener) SyscallConn() (syscall.RawConn, error)

SyscallConn возвращает необработанное сетевое соединение. Оно реализует интерфейс syscall.Conn.

Возвращаемое RawConn поддерживает только вызов Control. Чтение и запись возвращают ошибку.

type UnknownNetworkError

type UnknownNetworkError string

func (UnknownNetworkError) Error

func (e UnknownNetworkError) Error() string

func (UnknownNetworkError) Temporary

func (e UnknownNetworkError) Temporary() bool

func (UnknownNetworkError) Timeout

func (e UnknownNetworkError) Timeout() bool

Примечания

Ошибки

  • В JS и Windows функции FileConn, FileListener и FilePacketConn не реализованы.
  • В JS методы и функции, связанные с Interface, не реализованы.
  • В AIX, DragonFly BSD, NetBSD, OpenBSD, Plan 9 и Solaris метод MulticastAddrs интерфейса Interface не реализован.
  • На всех платформах POSIX чтение из сети “ip4” с помощью метода ReadFrom или ReadFromIP может не возвращать полный пакет IPv4, включая его заголовок, даже если есть свободное место. Это может произойти даже в тех случаях, когда Read или ReadMsgIP могут вернуть полный пакет. По этой причине рекомендуется не использовать эти методы, если важно получить полный пакет.
  • Рекомендации по совместимости Go 1 не позволяют нам изменить поведение этих методов; вместо них используйте Read или ReadMsgIP.
  • На JS и Plan 9 методы и функции, связанные с IPConn, не реализованы.
  • На Windows метод File интерфейса IPConn не реализован.
  • В DragonFly BSD и OpenBSD прослушивание сетей “tcp” и “udp” не прослушивает соединения IPv4 и IPv6. Это связано с тем, что трафик IPv4 не будет маршрутизироваться в сокет IPv6 — для поддержки обеих семейств адресов требуются два отдельных сокета. Подробности см. в inet6(4).
  • В Windows метод Write syscall.RawConn не интегрирован с сетевым опросником среды выполнения. Он не может ждать, пока соединение станет доступным для записи, и не учитывает deadli

3 - Пакет 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.

3.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-статуса. Для неизвестных кодов возвращает пустую строку.

3.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, не определены.

4 - Описание пакета для управления маршрутизацией github.com/julienschmidt/httprouter для GO

HttpRouter — это легкий высокопроизводительный маршрутизатор HTTP-запросов (также называемый мультиплексором или просто мультиплексором) для Go.

HttpRouter

HttpRouter — это легковесный высокопроизводительный маршрутизатор HTTP-запросов (также называемый мультиплексором или просто “mux”) для Go.

В отличие от стандартного мультиплексора пакета net/http в Go, этот роутер поддерживает:

  • Переменные в шаблонах маршрутов
  • Соответствие HTTP-методам запроса
  • Лучшую масштабируемость

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


Ключевые особенности

1. Только точные совпадения
В отличие от других роутеров (например, http.ServeMux), где URL может соответствовать нескольким шаблонам (с приоритетами типа “самое длинное совпадение” или “первый зарегистрированный — первый обработанный”), здесь запрос может соответствовать только одному маршруту или ни одному. Это исключает неожиданные совпадения, что полезно для SEO и UX.

2. Автоматическая обработка слэшей
Роутер автоматически перенаправляет при отсутствии или избытке trailing slash (косой черты в конце пути), если для нового пути есть обработчик. Можно отключить.

3. Коррекция пути
Дополнительные возможности:

  • Исправление регистра символов (например, для CAPTAIN CAPS LOCK)
  • Удаление избыточных элементов (../, //)
  • Case-insensitive поиск с редиректом

4. Параметры в путях
Динамические сегменты пути (например, /user/:id) извлекаются без ручного парсинга URL. Реализовано с минимальными накладными расходами.

5. Zero Garbage
Процесс сопоставления и диспетчеризации не создает мусора (zero bytes allocation). Единственные выделения памяти:

  • Создание slice для параметров пути
  • Создание контекста и объекта запроса (только в стандартном Handler API)
  • В 3-аргументном API при отсутствии параметров — аллокаций нет вообще.

6. Максимальная производительность
Реализация оптимизирована (см. бенчмарки). Используется радиксное дерево для эффективного сопоставления длинных путей.

7. Обработка паник
Можно установить PanicHandler для перехвата паник во время обработки запроса. Роутер восстановит работу и отправит клиенту ошибку.

8. Идеально для API

  • Поощряет построение RESTful API с иерархической структурой
  • Нативная поддержка OPTIONS-запросов
  • Автоматические ответы 405 Method Not Allowed
  • Возможность кастомизации NotFound и MethodNotAllowed обработчиков
  • Поддержка статических файлов

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

Используется радиксное дерево (trie) с компрессией для:

  • Эффективного хранения длинных путей
  • Быстрого поиска даже при тысячах маршрутов
  • Минимизации использования памяти

Возможности

Именованные параметры

Как видно из примеров, :name представляет собой именованный параметр. Его значения доступны через httprouter.Params — это срез (slice) параметров. Получить значение можно двумя способами:

  1. По индексу в срезе
  2. Через метод ByName(name): например, параметр :name извлекается вызовом ByName("name")

Важно:
При использовании стандартного http.Handler (через router.Handler или http.HandlerFunc) вместо 3-аргументного API HttpRouter, именованные параметры хранятся в контексте запроса (request.Context). Подробнее см. раздел «Почему это не работает с http.Handler?».

Особенности именованных параметров:

  • Соответствуют только одному сегменту пути
    Пример шаблона: /user/:user
Путь Совпадение
/user/gordon
/user/you
/user/gordon/profile
/user/

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

  • /user/new (статический)
  • /user/:user (параметр)

При этом маршрутизация для разных методов запроса (GET, POST и т.д.) обрабатывается независимо.


Параметры Catch-All (перехват всего)

Имеют формат *name и, как следует из названия, соответствуют любому пути. Всегда должны находиться в конце шаблона.

Пример шаблона: /src/*filepath

Путь Совпадение
/src/
/src/somefile.go
/src/subdir/somefile.go

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

  • Перехватывают все оставшиеся сегменты пути, включая слэши
  • Полезны для реализации «обработчиков-прокси» (например, статических файлов в подкаталогах)

Как это работает?

Роутер использует древовидную структуру, активно использующую общие префиксы — по сути, это компактное префиксное дерево (радиксное дерево). Узлы с общим префиксом имеют общего родителя. Вот пример структуры дерева для GET-запросов:

Приоритет   Путь             Обработчик
9          \                *<1>
3          ├s               nil
2          |├earch\         *<2>
1          |└upport\        *<3>
2          ├blog\           *<4>
1          |    └:post      nil
1          |\     *<5>
2          ├about-us\       *<6>
1          |        └team\  *<7>
1          └contact\        *<8>

Здесь каждый *<num> представляет адрес обработчика (указатель на функцию). При прохождении пути от корня до листа формируется полный маршрут, например \blog\:post\, где :post — это параметр-заполнитель. В отличие от хэш-таблиц, дерево позволяет работать с динамическими параметрами, поскольку сопоставление происходит по шаблонам, а не через сравнение хэшей. Бенчмарки подтверждают эффективность этого подхода.

Оптимизации структуры:

  1. Иерархичность URL:
    Ограниченный набор символов в путях URL создает множество общих префиксов, что позволяет декомпозировать задачу маршрутизации на меньшие подзадачи.
  2. Раздельные деревья для методов:
    Для каждого HTTP-метода (GET, POST и т.д.) строится отдельное дерево. Это:
    • Экономит память (не требует хранения map[метод]->обработчик в каждом узле).
    • Сокращает пространство поиска до актуального метода.
  3. Приоритизация узлов:
    Дочерние узлы сортируются по приоритету — количеству обработчиков в поддеревьях. Это дает:
    • Быстрый доступ к популярным маршрутам.
    • Приоритетную обработку длинных путей (с максимальной «стоимостью»).

Визуализация приоритетов:

├------------
├---------
├-----
├----
├--
├--
└-

Почему это не работает с http.Handler?

Работает! Роутер сам реализует интерфейс http.Handler и предоставляет адаптеры для интеграции стандартных http.Handler и http.HandlerFunc в качестве httprouter.Handle.

Доступ к параметрам:

Для http.Handler именованные параметры доступны через контекст запроса:

func Hello(w http.ResponseWriter, r *http.Request) {
    params := httprouter.ParamsFromContext(r.Context()) 
    fmt.Fprintf(w, "hello, %s!\n", params.ByName("name"))
}

Альтернативный вариант:

params := r.Context().Value(httprouter.ParamsKey)

Автоматические OPTIONS-ответы и CORS

Для кастомизации автоматических ответов на OPTIONS-запросы (например, для поддержки CORS preflight или добавления заголовков) используйте обработчик Router.GlobalOPTIONS:

router.GlobalOPTIONS = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    // Если это CORS preflight запрос
    if r.Header.Get("Access-Control-Request-Method") != "" {
        header := w.Header()
        // Разрешаем методы из заголовка Allow
        header.Set("Access-Control-Allow-Methods", r.Header.Get("Allow")) 
        // Открываем доступ для всех доменов
        header.Set("Access-Control-Allow-Origin", "*")  
    }
    // Возвращаем статус 204 No Content
    w.WriteHeader(http.StatusNoContent)  
})

Где найти Middleware X?

HttpRouter — это исключительно высокопроизводительный роутер с минималистичным функционалом. Поскольку он реализует интерфейс http.Handler, вы можете:

  1. Цеплять любые совместимые middleware перед роутером (например, из библиотеки Gorilla).
  2. Создавать собственные middleware — это достаточно просто.
  3. Использовать фреймворки на основе HttpRouter.

Мультидомены и поддомены

Пример реализации маршрутизации для разных доменов/поддоменов:

// HostSwitch - карта для хранения обработчиков по доменам
type HostSwitch map[string]http.Handler

// Реализуем интерфейс http.Handler
func (hs HostSwitch) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    // Ищем обработчик для текущего хоста
    if handler := hs[r.Host]; handler != nil {
        handler.ServeHTTP(w, r)
    } else {
        http.Error(w, "Forbidden", http.StatusForbidden) // Или редирект
    }
}

func main() {
    // Инициализация роутера
    router := httprouter.New()
    router.GET("/", Index)
    router.GET("/hello/:name", Hello)

    // Настройка HostSwitch
    hs := make(HostSwitch)
    hs["example.com:12345"] = router  // Для основного домена
    hs["api.example.com:12345"] = anotherRouter  // Для поддомена

    // Запуск сервера
    log.Fatal(http.ListenAndServe(":12345", hs))
}

Ключевые моменты:

  • Каждый домен/поддомен может иметь собственный роутер
  • Порт указывается вместе с доменом (example.com:12345)
  • Для необрабатываемых доменов возвращается 403 Forbidden (можно заменить на редирект)

Базовая аутентификация (Basic Auth)

Пример реализации HTTP Basic Authentication (RFC 2617) для обработчиков:

package main

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

	"github.com/julienschmidt/httprouter"
)

// BasicAuth - middleware для проверки учетных данных
func BasicAuth(h httprouter.Handle, requiredUser, requiredPassword string) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		// Получаем учетные данные из заголовка
		user, password, hasAuth := r.BasicAuth()

		if hasAuth && user == requiredUser && password == requiredPassword {
			// Если аутентификация успешна - передаем запрос обработчику
			h(w, r, ps)
		} else {
			// Иначе запрашиваем аутентификацию
			w.Header().Set("WWW-Authenticate", "Basic realm=Restricted")
			http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
		}
	}
}

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	fmt.Fprint(w, "Открытая зона!\n")
}

func Protected(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	fmt.Fprint(w, "Защищенная зона!\n")
}

func main() {
	user := "gordon"
	pass := "secret!"

	router := httprouter.New()
	router.GET("/", Index)
	router.GET("/protected/", BasicAuth(Protected, user, pass))

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

Цепочка обработчиков через NotFound

Примечание: Для корректной работы может потребоваться отключить Router.HandleMethodNotAllowed.

Вы можете использовать другой http.Handler (например, дополнительный роутер) для обработки запросов, которые не были найдены основным роутером:

router.NotFound = anotherRouter

Обслуживание статических файлов

Обработчик NotFound можно использовать для раздачи статических файлов из корневого пути /:

// Раздаем файлы из директории ./public
router.NotFound = http.FileServer(http.Dir("public"))

Однако такой подход нарушает строгие правила маршрутизации. Рекомендуется:

  1. Использовать выделенные подпути:
    router.ServeFiles("/static/*filepath", http.Dir("public"))
    
  2. Или явно задавать маршруты:
    router.GET("/files/*filepath", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
        http.ServeFile(w, r, path.Join("public", ps.ByName("filepath")))
    })
    

Веб-фреймворки на основе HttpRouter

Если HttpRouter кажется вам слишком минималистичным, рассмотрите эти высокоуровневые сторонние фреймворки, построенные на его основе:

Популярные решения

  1. Gin
    API в стиле Martini с значительно лучшей производительностью.
    Особенности: Middleware-цепочки, JSON-валидация, маршрутизация без рефлексии.

  2. Ace (устаревший, но исторически значимый)
    Один из первых быстрых фреймворков для Go.
    Преемник: Перешел в Gin.

  3. api2go
    Полноценная реализация JSON API с поддержкой JSON:API спецификации.
    Использование: Создание RESTful API с CRUD-операциями.

Для специфичных задач

  1. Goat
    Минималистичный REST API сервер.
    Философия: “Меньше кода — больше производительности”.

  2. Hitch
    Интегрирует HttpRouter с контекстом и middleware.
    Ключевая особенность: Простота связывания компонентов.

  3. Kami
    Работает через x/net/context.
    Для чего: Создание масштабируемых приложений с пробросом контекста.

  4. Siesta
    Композиция HTTP-обработчиков с поддержкой контекста.
    Паттерн: “Middleware как сервисы”.

Специализированные

  1. Medeina
    Вдохновлен Ruby-фреймворками Roda и Cuba.
    Подход: Древовидная маршрутизация.

  2. pbgo
    Мини-фреймворк для RPC/REST на основе Protobuf.
    Сценарии: Микросервисы с gRPC-like API.

  3. xmux
    Форк HttpRouter с поддержкой net/context.
    Отличие: Наследует производительность с расширенным API.

Для продакшена

  1. Hikaru
    Поддержка standalone-режима и Google App Engine.
    Плюсы: Кроссплатформенность.

  2. River
    Упрощенный REST-сервер для быстрого прототипирования.
    Фишка: Нулевая настройка для базовых сценариев.

  3. httpway
    Добавляет middleware-цепочки и graceful shutdown.
    Особенность: Совместимость с native HTTP-пакетами.


Как выбрать?

  • Для API: Gin, api2go, pbgo
  • Микросервисы: Siesta, xmux
  • Минимализм: Goat, River
  • Унаследованные проекты: Ace (переход на Gin)

Использование

Это всего лишь краткое введение, подробности смотрите в GoDoc. Давайте начнем с простого примера:

package main

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

    "github.com/julienschmidt/httprouter"
)

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    fmt.Fprint(w, "Welcome!\n")
}

func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
}

func main() {
    router := httprouter.New()
    router.GET("/", Index)
    router.GET("/hello/:name", Hello)

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

Принцип работы маршрутизации

Роутер сопоставляет входящие запросы по HTTP-методу и пути. Если для комбинации метод-путь зарегистрирован обработчик, запрос передается соответствующей функции. Для стандартных методов существуют сокращенные функции регистрации:

router.GET("/path", handler)    // GET
router.POST("/path", handler)   // POST 
router.PUT("/path", handler)    // PUT
router.PATCH("/path", handler)  // PATCH
router.DELETE("/path", handler) // DELETE

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

router.Handle("OPTIONS", "/path", handler)

Типы параметров пути

Синтаксис Тип
:name Именованный параметр
*name Catch-all параметр

1. Именованные параметры

Динамические сегменты пути. Соответствуют любому значению до следующего / или конца пути.

Шаблон:

/blog/:category/:post

Примеры соответствия:

Запрос Совпадение Параметры
/blog/go/request-routers category="go", post="request-routers"
/blog/go/request-routers/ ❌ (редирект) -
/blog/go/ -
/blog/go/request-routers/comments -

2. Catch-all параметры

Соответствуют любой части пути до конца, включая /. Всегда должны быть последним элементом.

Шаблон:

/files/*filepath

Примеры соответствия:

Запрос Совпадение Параметры
/files/ filepath="/"
/files/LICENSE filepath="/LICENSE"
/files/templates/article.html filepath="/templates/article.html"
/files ❌ (редирект) -

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

Параметры хранятся в срезе структур Param (ключ-значение) и передаются обработчику третьим аргументом:

func Handler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    // Получение значения по имени
    user := ps.ByName("user") // для :user или *user

    // Получение по индексу (с доступом к имени параметра)
    param := ps[2]
    key   := param.Key   // имя 3-го параметра
    value := param.Value // значение 3-го параметра
}

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

  • Доступ к параметрам за O(1) по имени (использует внутреннюю оптимизацию)
  • Индексный доступ полезен при обработке неизвестных параметров
  • Параметры автоматически URL-decoded

Важные нюансы

  1. Редиректы:

    • Для путей с / в конце роутер автоматически делает редирект на каноничную версию
    • Можно отключить через router.RedirectTrailingSlash = false
  2. Кодировка:

    // Пример значения с спецсимволами
    // Запрос: /search/%D1%82%D0%B5%D1%81%D1%82
    query := ps.ByName("query") // автоматически декодируется в "тест"
    
  3. Производительность:

    • Параметры не аллоцируют память при отсутствии в пути
    • Используется slice pooling для повторного использования структур Param

Переменные

var ParamsKey = paramsKey{}

ParamsKey — это ключ контекста запроса, под которым хранятся параметры URL.


Функции

CleanPath

func CleanPath(p string) string

CleanPath — это URL-версия функции path.Clean. Она возвращает канонизированный путь, удаляя элементы . и ...

Правила обработки (применяются итеративно до полной обработки):

  1. Слэши
    Заменяет множественные слэши на один: ////

  2. Текущая директория (.)
    Удаляет элементы .:
    /././path/path

  3. Родительская директория (..)
    Удаляет комбинации ../ с предыдущим не-.. элементом:
    /a/b/../c/a/c
    /a/b/../../c/c

  4. Корневые ..
    Заменяет /.. в начале пути на /:
    /../a/a

  5. Пустой результат
    Если после обработки путь пуст, возвращает /:
    `` → /

Примеры:

CleanPath("//foo///bar")   // "/foo/bar"
CleanPath("/./foo/../bar") // "/bar"
CleanPath("/../")          // "/"
CleanPath("")              // "/"

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

  • Не выполняет URL-декодирование (работает с уже декодированным путем)
  • Сохраняет регистр символов
  • Полезен для нормализации путей перед маршрутизацией

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

  1. Использование в роутере:
    HttpRouter автоматически применяет CleanPath к входящим запросам перед сопоставлением маршрутов.

  2. Безопасность:
    Защищает от path traversal атак:

    // Запрос "/secret/../../etc/passwd" будет преобразован в "/etc/passwd",
    // но роутер обработает его только если есть явный маршрут
    
  3. Производительность:
    Реализация использует zero-allocation алгоритм для минимизации нагрузк

Типы

type Handle

type Handle func(http.ResponseWriter, *http.Request, Params)

Handle — функция, которая может быть зарегистрирована для обработки HTTP-запросов. Аналог http.HandlerFunc, но с третьим параметром для значений параметров URL.


type Param (добавлено в v1.1.0)

type Param struct {
    Key   string // Ключ параметра
    Value string // Значение параметра
}

Param представляет отдельный параметр URL, состоящий из ключа и значения.


type Params (добавлено в v1.1.0)

type Params []Param

Params — это срез параметров Param, возвращаемый роутером. Срез упорядочен: первый параметр URL соответствует первому элементу среза. Безопасен для доступа по индексу.

Методы:

  1. ParamsFromContext (добавлено в v1.2.0)
func ParamsFromContext(ctx context.Context) Params

Извлекает параметры URL из контекста запроса. Возвращает nil, если параметров нет.

  1. ByName (добавлено в v1.1.0)
func (ps Params) ByName(name string) string

Возвращает значение первого параметра с указанным ключом. Если параметр не найден, возвращает пустую строку.


type Router

type Router struct {
    // Автоматический редирект при несовпадении пути, 
    // но наличии обработчика для пути с/без завершающего слэша.
    // Пример: /foo/ → /foo (код 301 для GET, 307 для других методов)
    RedirectTrailingSlash bool

    // Автокоррекция пути при отсутствии обработчика:
    // 1. Удаляет избыточные элементы (../, //)
    // 2. Поиск без учета регистра
    // 3. Редирект на исправленный путь (301/307)
    RedirectFixedPath bool

    // Проверка допустимых методов при неудачной маршрутизации.
    // Если включено, отправляет 405 Method Not Allowed с заголовком Allow.
    HandleMethodNotAllowed bool

    // Автоматическая обработка OPTIONS-запросов.
    // Пользовательские обработчики OPTIONS имеют приоритет.
    HandleOPTIONS bool

    // Глобальный обработчик для автоматических OPTIONS-запросов.
    // Вызывается только если HandleOPTIONS=true и нет специфичного обработчика.
    GlobalOPTIONS http.Handler

    // Обработчик для ненайденных маршрутов (по умолчанию — http.NotFound).
    NotFound http.Handler

    // Обработчик для недопустимых методов (код 405).
    // По умолчанию — http.Error с StatusMethodNotAllowed.
    MethodNotAllowed http.Handler

    // Обработчик паник (код 500).
    // Предотвращает аварийное завершение сервера.
    PanicHandler func(http.ResponseWriter, *http.Request, interface{})

    // содержит скрытые или неэкспортируемые поля
}

Router реализует интерфейс http.Handler и предоставляет конфигурируемую систему маршрутизации.


Ключевые особенности

  1. Гибкость обработчиков:

    • Handle поддерживает параметры через Params
    • Совместимость со стандартными http.Handler/http.HandlerFunc
  2. Безопасность:

    • ParamsFromContext для безопасного доступа к параметрам из middleware
    • PanicHandler для обработки критических ошибок
  3. Производительность:

    • Срезы Params избегают аллокаций памяти
    • Прямой доступ к параметрам по индексу (O(1))

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

router.GET("/user/:id", func(w http.ResponseWriter, r *http.Request, ps Params) {
    id := ps.ByName("id") // или ps[0].Value
})

Методы типа Router

func New() *Router

func New() *Router

Создает и возвращает новый инициализированный роутер. Автокоррекция путей (включая обработку trailing slashes) включена по умолчанию.


Методы-сокращения для HTTP-методов

Метод Описание
DELETE(path string, handle Handle) Сокращение для router.Handle(http.MethodDelete, path, handle)
GET(path string, handle Handle) Сокращение для GET-запросов
HEAD(path string, handle Handle) (v1.1.0+) Сокращение для HEAD-запросов
OPTIONS(path string, handle Handle) (v1.1.0+) Сокращение для OPTIONS-запросов
PATCH(path string, handle Handle) Сокращение для PATCH-запросов
POST(path string, handle Handle) Сокращение для POST-запросов
PUT(path string, handle Handle) Сокращение для PUT-запросов
func (r *Router) DELETE(path string, handle Handle)
func (r *Router) GET(path string, handle Handle)

Пример:

router := httprouter.New()
router.GET("/users", listUsers)
router.POST("/users", createUser)

func (*Router) Handle(method, path string, handle Handle)

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

router.Handle("PROPFIND", "/resource", handleResource)

func (*Router) Handler(method, path string, handler http.Handler)

Адаптер для использования стандартного http.Handler. Параметры доступны через контекст:

router.Handler("GET", "/user/:id", customHandler)
// В обработчике:
params := httprouter.ParamsFromContext(r.Context())

func (*Router) HandlerFunc(method, path string, handler http.HandlerFunc)

Адаптер для http.HandlerFunc:

router.HandlerFunc("GET", "/", indexHandler)

func (*Router) Lookup(method, path string) (Handle, Params, bool)

Ручной поиск обработчика для комбинации метод+путь. Возвращает:

  • Обработчик
  • Параметры пути
  • Флаг необходимости редиректа (добавить/убрать trailing slash)

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

if handle, ps, _ := router.Lookup(r.Method, r.URL.Path); handle != nil {
    // Кастомная обработка
}

func (*Router) ServeFiles(path string, root http.FileSystem)

Обслуживает статические файлы из указанной файловой системы. Путь должен содержать /*filepath в конце:

// Доступ к /var/www/file.txt по URL /src/file.txt
router.ServeFiles("/src/*filepath", http.Dir("/var/www"))

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

  • Использует стандартный http.FileServer
  • Для 404 ошибок применяется http.NotFound, а не роутерский NotFound-обработчик

func (*Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

Позволяет роутеру удовлетворять интерфейсу http.Handler:

http.ListenAndServe(":8080", router)

Особенности использования

  1. Порядок регистрации:
    Нет приоритета “первый зарегистрированный — первый обработанный”. Каждый путь+метод соответствует ровно одному обработчику.

  2. Производительность:
    Все методы регистрации используют единую оптимизированную логику:

    // Эти вызовы эквивалентны по производительности
    router.GET("/path", handler)
    router.Handle("GET", "/path", handler)
    
  3. Безопасность:
    ServeFiles автоматически защищает от directory traversal атак:

    // Запрос `/src/../../../etc/passwd` будет отклонен