Пакет textproto
Обзор
Пакет textproto реализует общую поддержку текстовых протоколов запросов и ответов в стиле HTTP, NNTP и SMTP.
Этот пакет обеспечивает использование набора символов HTTP/1.1, определённого в RFC 9112, для ключей и значений заголовков.
Пакет предоставляет:
Error, представляющий числовой ответ об ошибке от сервера.
Pipeline для управления конвейерными запросами и ответами клиента.
Reader для чтения строк с числовыми кодами ответа, заголовков вида «ключ: значение», строк с продолжением, начинающихся с пробелов, и целых текстовых блоков, заканчивающихся точкой в отдельной строке.
Writer для записи текстовых блоков с точечным кодированием.
Conn — удобная обёртка над Reader, Writer и Pipeline для работы с одним сетевым соединением.
Указатель
Файлы пакета
header.go pipeline.go reader.go textproto.go writer.go
func CanonicalMIMEHeaderKey
func CanonicalMIMEHeaderKey(s string) string
CanonicalMIMEHeaderKey возвращает каноническую форму ключа заголовка MIME s. Канонизация переводит в верхний регистр первую букву и любую букву после дефиса; остальные буквы переводятся в нижний регистр. Например, канонический ключ для "accept-encoding" — "Accept-Encoding". Предполагается, что ключи заголовков MIME состоят только из ASCII-символов. Если s содержит пробел или недопустимые байты поля заголовка, как определено в RFC 9112, он возвращается без изменений.
func TrimBytes 1.1
func TrimBytes(b []byte) []byte
TrimBytes возвращает b без начальных и конечных пробелов ASCII.
func TrimString 1.1
func TrimString(s string) string
TrimString возвращает s без начальных и конечных пробелов ASCII.
type Conn
Conn представляет соединение текстового сетевого протокола. Он состоит из Reader и Writer для управления вводом-выводом и Pipeline для упорядочивания параллельных запросов в соединении. Эти встроенные типы предоставляют свои методы; подробности см. в документации к этим типам.
type Conn struct {
Reader
Writer
Pipeline
// contains filtered or unexported fields
}
func Dial
func Dial(network, addr string) (*Conn, error)
Dial подключается к указанному адресу в указанной сети с помощью net.Dial, а затем возвращает новый Conn для этого соединения.
func NewConn
func NewConn(conn io.ReadWriteCloser) *Conn
NewConn возвращает новый Conn, использующий conn для ввода-вывода.
func (*Conn) Close
func (c *Conn) Close() error
Close закрывает соединение.
func (*Conn) Cmd
func (c *Conn) Cmd(format string, args ...any) (id uint, err error)
Cmd — это вспомогательный метод, который отправляет команду, дождавшись своей очереди в конвейере. Текст команды формируется форматированием format с помощью args и добавлением \r\n. Cmd возвращает идентификатор команды, который используется с StartResponse и EndResponse.
Например, клиент может выполнить команду HELP, возвращающую тело с точечным кодированием, следующим образом:
id, err := c.Cmd("HELP")
if err != nil {
return nil, err
}
c.StartResponse(id)
defer c.EndResponse(id)
if _, _, err = c.ReadCodeLine(110); err != nil {
return nil, err
}
text, err := c.ReadDotBytes()
if err != nil {
return nil, err
}
return c.ReadCodeLine(250)
type Error
Error представляет числовой ответ об ошибке от сервера.
type Error struct {
Code int
Msg string
}
func (*Error) Error
func (e *Error) Error() string
type MIMEHeader
MIMEHeader представляет заголовок в стиле MIME — отображение ключей в наборы значений.
type MIMEHeader map[string][]string
func (MIMEHeader) Add
func (h MIMEHeader) Add(key, value string)
Add добавляет пару ключ-значение в заголовок. Новое значение добавляется к уже имеющимся значениям, связанным с ключом.
func (MIMEHeader) Del
func (h MIMEHeader) Del(key string)
Del удаляет значения, связанные с ключом.
func (MIMEHeader) Get
func (h MIMEHeader) Get(key string) string
Get возвращает первое значение, связанное с указанным ключом. Регистр не учитывается; для канонизации переданного ключа используется CanonicalMIMEHeaderKey. Если с ключом не связано ни одного значения, Get возвращает "". Чтобы использовать неканонические ключи, обращайтесь к map напрямую.
func (MIMEHeader) Set
func (h MIMEHeader) Set(key, value string)
Set устанавливает для записей заголовка, связанных с ключом, единственное значение value. Он заменяет все существующие значения, связанные с ключом.
func (MIMEHeader) Values 1.14
func (h MIMEHeader) Values(key string) []string
Values возвращает все значения, связанные с указанным ключом. Регистр не учитывается; для канонизации переданного ключа используется CanonicalMIMEHeaderKey. Чтобы использовать неканонические ключи, обращайтесь к map напрямую. Возвращаемый срез не является копией.
type Pipeline
Pipeline управляет упорядоченной последовательностью запросов и ответов, передаваемых конвейером.
Чтобы использовать Pipeline p для управления несколькими клиентами в одном соединении, каждый клиент должен выполнять:
id := p.Next() // take a number p.StartRequest(id) // wait for turn to send request «send request» p.EndRequest(id) // notify Pipeline that request is sent p.StartResponse(id) // wait for turn to read response «read response» p.EndResponse(id) // notify Pipeline that response is read
Сервер, использующий конвейерную обработку, может применять те же вызовы, чтобы гарантировать запись параллельно вычисленных ответов в правильном порядке.
type Pipeline struct {
// contains filtered or unexported fields
}
func (*Pipeline) EndRequest
func (p *Pipeline) EndRequest(id uint)
EndRequest сообщает p, что запрос с указанным идентификатором отправлен (или, если это сервер, получен).
func (*Pipeline) EndResponse
func (p *Pipeline) EndResponse(id uint)
EndResponse сообщает p, что ответ с указанным идентификатором получен (или, если это сервер, отправлен).
func (*Pipeline) Next
func (p *Pipeline) Next() uint
Next возвращает следующий идентификатор для пары запрос/ответ.
func (*Pipeline) StartRequest
func (p *Pipeline) StartRequest(id uint)
StartRequest блокируется до момента отправки запроса с указанным идентификатором (или, если это сервер, его получения).
func (*Pipeline) StartResponse
func (p *Pipeline) StartResponse(id uint)
StartResponse блокируется до момента получения запроса с указанным идентификатором (или, если это сервер, его отправки).
type ProtocolError
ProtocolError описывает нарушение протокола, например недопустимый ответ или разорванное соединение.
type ProtocolError string
func (ProtocolError) Error
func (p ProtocolError) Error() string
type Reader
Reader предоставляет вспомогательные методы для чтения запросов или ответов из сетевого соединения, использующего текстовый протокол.
type Reader struct {
R *bufio.Reader
// contains filtered or unexported fields
}
func NewReader
func NewReader(r *bufio.Reader) *Reader
NewReader возвращает новый Reader, читающий из r.
Чтобы избежать атак типа «отказ в обслуживании», предоставленный bufio.Reader должен читать из io.LimitReader или аналогичного Reader, ограничивающего размер ответов.
func (*Reader) DotReader
func (r *Reader) DotReader() io.Reader
DotReader возвращает новый Reader, удовлетворяющий запросы Read декодированным текстом блока с точечным кодированием, прочитанного из r. Возвращённый Reader действителен только до следующего вызова метода для r.
Точечное кодирование — распространённый способ кадрирования блоков данных в текстовых протоколах, например SMTP. Данные состоят из последовательности строк, каждая из которых заканчивается на "\r\n". Последовательность завершается строкой, содержащей только точку: ".\r\n". Строки, начинающиеся с точки, экранируются дополнительной точкой, чтобы их нельзя было принять за конец последовательности.
Декодированная форма, возвращаемая методом Read объекта Reader, заменяет окончания строк "\r\n" на более простой "\n", удаляет начальные точки экранирования, если они есть, и возвращает ошибку io.EOF после чтения (и отбрасывания) строки, завершающей последовательность.
func (*Reader) ReadCodeLine
func (r *Reader) ReadCodeLine(expectCode int) (code int, message string, err error)
ReadCodeLine читает строку кода ответа следующего вида:
code message
где code — трёхзначный код состояния, а message занимает оставшуюся часть строки. Пример такой строки:
220 plan9.bell-labs.com ESMTP
Если префикс кода состояния не совпадает с цифрами в expectCode, ReadCodeLine возвращает err, установленную в &Error{code, message}. Например, если expectCode равен 31, ошибка будет возвращена, если код состояния не находится в диапазоне [310,319].
Если ответ многострочный, ReadCodeLine возвращает ошибку.
Значение expectCode <= 0 отключает проверку кода состояния.
func (*Reader) ReadContinuedLine
func (r *Reader) ReadContinuedLine() (string, error)
ReadContinuedLine читает из r строку, возможно состоящую из нескольких строк, удаляя конечные пробельные символы ASCII. Строки после первой считаются продолжениями, если начинаются с пробела или символа табуляции. В возвращаемых данных строки продолжения отделены от предыдущей строки только одним пробелом: символ новой строки и начальные пробельные символы удаляются.
Например, рассмотрим следующий ввод:
Line 1 continued... Line 2
Первый вызов ReadContinuedLine вернёт "Line 1 continued...", а второй — "Line 2".
Пустые строки никогда не считаются продолжениями.
func (*Reader) ReadContinuedLineBytes
func (r *Reader) ReadContinuedLineBytes() ([]byte, error)
ReadContinuedLineBytes похож на Reader.ReadContinuedLine, но возвращает []byte вместо строки.
func (*Reader) ReadDotBytes
func (r *Reader) ReadDotBytes() ([]byte, error)
ReadDotBytes читает данные с точечным кодированием и возвращает декодированные данные.
Подробное описание точечного кодирования см. в документации к методу Reader.DotReader.
func (*Reader) ReadDotLines
func (r *Reader) ReadDotLines() ([]string, error)
ReadDotLines читает данные с точечным кодированием и возвращает срез декодированных строк, удаляя из каждой конечные \r\n или \n.
Подробное описание точечного кодирования см. в документации к методу Reader.DotReader.
func (*Reader) ReadLine
func (r *Reader) ReadLine() (string, error)
ReadLine читает одну строку из r, удаляя из возвращаемой строки конечный \n или \r\n.
func (*Reader) ReadLineBytes
func (r *Reader) ReadLineBytes() ([]byte, error)
ReadLineBytes похож на Reader.ReadLine, но возвращает []byte вместо строки.
func (*Reader) ReadMIMEHeader
func (r *Reader) ReadMIMEHeader() (MIMEHeader, error)
ReadMIMEHeader читает из r заголовок в стиле MIME. Заголовок представляет собой последовательность строк вида «Ключ: Значение», возможно с продолжениями, заканчивающуюся пустой строкой. Возвращаемая map m сопоставляет CanonicalMIMEHeaderKey(key) с последовательностью значений в том же порядке, в котором они встретились во входных данных.
Например, рассмотрим следующий ввод:
My-Key: Value 1
Long-Key: Even
Longer Value
My-Key: Value 2
Для этого ввода ReadMIMEHeader возвращает map:
map[string][]string{
"My-Key": {"Value 1", "Value 2"},
"Long-Key": {"Even Longer Value"},
}
func (*Reader) ReadResponse
func (r *Reader) ReadResponse(expectCode int) (code int, message string, err error)
ReadResponse читает многострочный ответ следующего вида:
code-message line 1 code-message line 2 ... code message line n
где code — трёхзначный код состояния. Первая строка начинается с кода и дефиса. Ответ завершается строкой, начинающейся с того же кода, за которым следует пробел. Строки в message разделяются символом новой строки (\n).
Подробное описание другого допустимого формата ответа см. на странице 36 RFC 959 (https://www.ietf.org/rfc/rfc959.txt):
code-message line 1 message line 2 ... code message line n
Если префикс статуса не совпадает с цифрами в expectCode, ReadResponse возвращает значение err, равное &Error{code, message}. Например, если expectCode равен 31, ошибка будет возвращена, если статус не находится в диапазоне [310,319].
Значение expectCode <= 0 отключает проверку кода статуса.
type Writer
Writer реализует вспомогательные методы для записи запросов или ответов в сетевое соединение с текстовым протоколом.
type Writer struct {
W *bufio.Writer
// contains filtered or unexported fields
}
func NewWriter
func NewWriter(w *bufio.Writer) *Writer
NewWriter возвращает новый Writer, выполняющий запись в w.
func (*Writer) DotWriter
func (w *Writer) DotWriter() io.WriteCloser
DotWriter возвращает записывающий объект, который можно использовать для записи в w данных с точечным кодированием. Он добавляет ведущие точки, когда это необходимо, преобразует окончания строк \n в \r\n и добавляет завершающую строку .\r\n при закрытии DotWriter. Вызывающий код должен закрыть DotWriter перед следующим вызовом метода для w.
Подробнее о точечном кодировании см. в документации метода Reader.DotReader.
func (*Writer) PrintfLine
func (w *Writer) PrintfLine(format string, args ...any) error
PrintfLine записывает отформатированный вывод, за которым следует \r\n.
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/net/textproto/