# package textproto
`import "net/textproto"`
textproto實現了對基于文本的請求/回復協議的一般性支持,包括HTTP、NNTP和SMTP。
本包提供:
錯誤,代表服務端回復的錯誤碼。Pipeline,以管理客戶端中的管道化的請求/回復。Reader,讀取數值回復碼行,鍵值對形式的頭域,一個作為后續行先導的空行,以及以只有一個"."的一行為結尾的整個文本塊。Writer,寫入點編碼的文本。Conn,對Reader、Writer和Pipline的易用的包裝,用于單個網絡連接。
## Index
* [type ProtocolError](#ProtocolError)
* [func (p ProtocolError) Error() string](#ProtocolError.Error)
* [type Error](#Error)
* [func (e \*Error) Error() string](#Error.Error)
* [func CanonicalMIMEHeaderKey(s string) string](#CanonicalMIMEHeaderKey)
* [func TrimBytes(b []byte) []byte](#TrimBytes)
* [func TrimString(s string) string](#TrimString)
* [type MIMEHeader](#MIMEHeader)
* [func (h MIMEHeader) Get(key string) string](#MIMEHeader.Get)
* [func (h MIMEHeader) Set(key, value string)](#MIMEHeader.Set)
* [func (h MIMEHeader) Add(key, value string)](#MIMEHeader.Add)
* [func (h MIMEHeader) Del(key string)](#MIMEHeader.Del)
* [type Reader](#Reader)
* [func NewReader(r \*bufio.Reader) \*Reader](#NewReader)
* [func (r \*Reader) DotReader() io.Reader](#Reader.DotReader)
* [func (r \*Reader) ReadLine() (string, error)](#Reader.ReadLine)
* [func (r \*Reader) ReadLineBytes() ([]byte, error)](#Reader.ReadLineBytes)
* [func (r \*Reader) ReadContinuedLine() (string, error)](#Reader.ReadContinuedLine)
* [func (r \*Reader) ReadContinuedLineBytes() ([]byte, error)](#Reader.ReadContinuedLineBytes)
* [func (r \*Reader) ReadDotBytes() ([]byte, error)](#Reader.ReadDotBytes)
* [func (r \*Reader) ReadDotLines() ([]string, error)](#Reader.ReadDotLines)
* [func (r \*Reader) ReadCodeLine(expectCode int) (code int, message string, err error)](#Reader.ReadCodeLine)
* [func (r \*Reader) ReadResponse(expectCode int) (code int, message string, err error)](#Reader.ReadResponse)
* [func (r \*Reader) ReadMIMEHeader() (MIMEHeader, error)](#Reader.ReadMIMEHeader)
* [type Writer](#Writer)
* [func NewWriter(w \*bufio.Writer) \*Writer](#NewWriter)
* [func (w \*Writer) DotWriter() io.WriteCloser](#Writer.DotWriter)
* [func (w \*Writer) PrintfLine(format string, args ...interface{}) error](#Writer.PrintfLine)
* [type Pipeline](#Pipeline)
* [func (p \*Pipeline) Next() uint](#Pipeline.Next)
* [func (p \*Pipeline) StartRequest(id uint)](#Pipeline.StartRequest)
* [func (p \*Pipeline) StartResponse(id uint)](#Pipeline.StartResponse)
* [func (p \*Pipeline) EndRequest(id uint)](#Pipeline.EndRequest)
* [func (p \*Pipeline) EndResponse(id uint)](#Pipeline.EndResponse)
* [type Conn](#Conn)
* [func NewConn(conn io.ReadWriteCloser) \*Conn](#NewConn)
* [func Dial(network, addr string) (\*Conn, error)](#Dial)
* [func (c \*Conn) Cmd(format string, args ...interface{}) (id uint, err error)](#Conn.Cmd)
* [func (c \*Conn) Close() error](#Conn.Close)
## type [ProtocolError](https://github.com/golang/go/blob/master/src/net/textproto/textproto.go#L47 "View Source")
```
type ProtocolError string
```
ProtocolError描述一個違反協議的錯誤,如不合法的回復或者掛起的連接。
### func (ProtocolError) [Error](https://github.com/golang/go/blob/master/src/net/textproto/textproto.go#L49 "View Source")
```
func (p ProtocolError) Error() string
```
## type [Error](https://github.com/golang/go/blob/master/src/net/textproto/textproto.go#L36 "View Source")
```
type Error struct {
Code int
Msg string
}
```
Error代表一個服務端返回的數值狀態碼/錯誤碼。
### func (\*Error) [Error](https://github.com/golang/go/blob/master/src/net/textproto/textproto.go#L41 "View Source")
```
func (e *Error) Error() string
```
## func [CanonicalMIMEHeaderKey](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L543 "View Source")
```
func CanonicalMIMEHeaderKey(s string) string
```
返回一個MIME頭的鍵的規范格式。該標準會將首字母和所有"-"之后的字符改為大寫,其余字母改為小寫。舉個例子,"accept-encoding"作為鍵的標準格式是"Accept-Encoding"。MIME頭的鍵必須是ASCII碼構成。
## func [TrimBytes](https://github.com/golang/go/blob/master/src/net/textproto/textproto.go#L137 "View Source")
```
func TrimBytes(b []byte) []byte
```
去掉b前后的ASCII碼空白(不去Unicode空白)
## func [TrimString](https://github.com/golang/go/blob/master/src/net/textproto/textproto.go#L126 "View Source")
```
func TrimString(s string) string
```
去掉s前后的ASCII碼空白(不去Unicode空白)
## type [MIMEHeader](https://github.com/golang/go/blob/master/src/net/textproto/header.go#L9 "View Source")
```
type MIMEHeader map[string][]string
```
MIMEHeader代表一個MIME頭,將鍵映射為值的集合。
### func (MIMEHeader) [Get](https://github.com/golang/go/blob/master/src/net/textproto/header.go#L29 "View Source")
```
func (h MIMEHeader) Get(key string) string
```
Get方法返回鍵對應的值集的第一個值。如果鍵沒有關聯值,返回""。如要獲得鍵對應的值集直接用map。
### func (MIMEHeader) [Set](https://github.com/golang/go/blob/master/src/net/textproto/header.go#L21 "View Source")
```
func (h MIMEHeader) Set(key, value string)
```
Set方法將鍵對應的值集設置為只含有value一個值。沒有就新建,有則刪掉原有的值。
### func (MIMEHeader) [Add](https://github.com/golang/go/blob/master/src/net/textproto/header.go#L13 "View Source")
```
func (h MIMEHeader) Add(key, value string)
```
Add方法向h中添加鍵值對,它會把新的值添加到鍵對應的值的集合里。
### func (MIMEHeader) [Del](https://github.com/golang/go/blob/master/src/net/textproto/header.go#L41 "View Source")
```
func (h MIMEHeader) Del(key string)
```
Del方法刪除鍵對應的值集。
## type [Reader](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L22 "View Source")
```
type Reader struct {
R *bufio.Reader
// 內含隱藏或非導出字段
}
```
Reader實現了從一個文本協議網絡連接中方便的讀取請求/回復的方法。
### func [NewReader](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L29 "View Source")
```
func NewReader(r *bufio.Reader) *Reader
```
NewReader返回一個從r讀取數據的Reader。
### func (\*Reader) [DotReader](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L286 "View Source")
```
func (r *Reader) DotReader() io.Reader
```
DotReader方法返回一個io.Reader,該接口自動解碼r中讀取的點編碼塊。注意該接口僅在下一次調用r的方法之前才有效。點編碼是文本協議如SMTP用于文本塊的通用框架。數據包含多個行,每行以"\r\n"結尾。數據本身以一個只含有一個點的一行".\r\n"來結尾。以點起始的行會添加額外的點,來避免看起來像是文本的結尾。
返回接口的Read方法會將行尾的"\r\n"修改為"\n",去掉起頭的轉義點,并在底層讀取到(并拋棄掉)表示文本結尾的行時停止解碼并返回io.EOF錯誤。
### func (\*Reader) [ReadLine](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L35 "View Source")
```
func (r *Reader) ReadLine() (string, error)
```
ReadLine方法從r讀取單行,去掉最后的\r\n或\n。
### func (\*Reader) [ReadLineBytes](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L41 "View Source")
```
func (r *Reader) ReadLineBytes() ([]byte, error)
```
ReadLineBytes類似ReadLine但返回[]byte切片。
### func (\*Reader) [ReadContinuedLine](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L90 "View Source")
```
func (r *Reader) ReadContinuedLine() (string, error)
```
ReadContinuedLine從r中讀取可能有后續的行,會將該行尾段的ASCII空白剔除,并將該行后面所有以空格或者tab起始的行視為其后續,后續部分會剔除行頭部的空白,所有這些行包括第一行以單個空格連接起來返回。
舉例如下:
```
Line 1
continued...
Line 2
```
第一次調用ReadContinuedLine會返回"Line 1 continued...",第二次會返回"Line 2"
只有空格的行不被視為有后續的行。
### func (\*Reader) [ReadContinuedLineBytes](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L111 "View Source")
```
func (r *Reader) ReadContinuedLineBytes() ([]byte, error)
```
ReadContinuedLineBytes類似ReadContinuedLine但返回[]byte切片。
### func (\*Reader) [ReadDotBytes](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L402 "View Source")
```
func (r *Reader) ReadDotBytes() ([]byte, error)
```
ReadDotBytes讀取點編碼文本返回解碼后的數據,點編碼詳見DotReader方法。
### func (\*Reader) [ReadDotLines](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L410 "View Source")
```
func (r *Reader) ReadDotLines() ([]string, error)
```
ReadDotLines方法讀取一個點編碼文本塊并返回一個包含解碼后各行的切片,各行最后的\r\n或\n去掉。
### func (\*Reader) [ReadCodeLine](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L219 "View Source")
```
func (r *Reader) ReadCodeLine(expectCode int) (code int, message string, err error)
```
方法讀取回復的狀態碼行,格式如下:
```
code message
```
狀態碼是3位數字,message進一步描述狀態,例如:
```
220 plan9.bell-labs.com ESMTP
```
如果狀態碼字符串的前綴不匹配expectCode,方法返回錯誤&Error{code, message}。例如expectCode是31,則如果狀態碼不在區間[310, 319]內就會返回錯誤。如果回復是多行的則會返回錯誤。
如果expectCode <= 0,將不會檢查狀態碼。
### func (\*Reader) [ReadResponse](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L249 "View Source")
```
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是三位數的狀態碼。第一行以code和連字符開始,最后以同code后跟空格的行結束。返回值message每行以\n分隔。細節參見[RFC 959](http://tools.ietf.org/html/rfc959)([http://www.ietf.org/rfc/rfc959.txt](http://www.ietf.org/rfc/rfc959.txt))第36頁。
如果狀態碼字符串的前綴不匹配expectCode,方法返回時err設為&Error{code, message}。例如expectCode是31,則如果狀態碼不在區間[310, 319]內就會返回錯誤。如果回復是多行的則會返回錯誤。
如果expectCode <= 0,將不會檢查狀態碼。
### func (\*Reader) [ReadMIMEHeader](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L458 "View Source")
```
func (r *Reader) ReadMIMEHeader() (MIMEHeader, error)
```
ReadMIMEHeader從r讀取MIME風格的頭域。該頭域包含一系列可能有后續的鍵值行,以空行結束。返回的map映射CanonicalMIMEHeaderKey(key)到值的序列(順序與輸入相同)。
舉例如下:
```
My-Key: Value 1
Long-Key: Even
Longer Value
My-Key: Value 2
```
對此輸入,ReadMIMEHeader返回:
```
map[string][]string{
"My-Key": {"Value 1", "Value 2"},
"Long-Key": {"Even Longer Value"},
}
```
## type [Writer](https://github.com/golang/go/blob/master/src/net/textproto/writer.go#L15 "View Source")
```
type Writer struct {
W *bufio.Writer
// 內含隱藏或非導出字段
}
```
Writer實現了方便的方法在一個文本協議網絡連接中寫入請求/回復。
### func [NewWriter](https://github.com/golang/go/blob/master/src/net/textproto/writer.go#L21 "View Source")
```
func NewWriter(w *bufio.Writer) *Writer
```
NewWriter函數返回一個底層寫入w的Writer。
### func (\*Writer) [DotWriter](https://github.com/golang/go/blob/master/src/net/textproto/writer.go#L43 "View Source")
```
func (w *Writer) DotWriter() io.WriteCloser
```
DotWriter方法返回一個io.WriteCloser,用于將點編碼文本寫入w。返回的接口會在必要時添加轉義點,將行尾的\n替換為\r\n,并在關閉時添加最后的.\r\n行。調用者必須在下一次調用w的方法前關閉該接口。點編碼文本格式參見Reader.DotReader方法。
### func (\*Writer) [PrintfLine](https://github.com/golang/go/blob/master/src/net/textproto/writer.go#L29 "View Source")
```
func (w *Writer) PrintfLine(format string, args ...interface{}) error
```
PrintfLine方法將格式化的輸出寫入底層并在最后寫入\r\n。
## type [Pipeline](https://github.com/golang/go/blob/master/src/net/textproto/pipeline.go#L28 "View Source")
```
type Pipeline struct {
// 內含隱藏或非導出字段
}
```
Pipeline管理管道化的有序請求/回復序列。
為了使用Pipeline管理一個連接的多個客戶端,每個客戶端應像下面一樣運行:
```
id := p.Next() // 獲取一個數字id
p.StartRequest(id) // 等待輪到該id發送請求
?send request?
p.EndRequest(id) // 通知Pipeline請求發送完畢
p.StartResponse(id) // 等待該id讀取回復
?read response?
p.EndResponse(id) // 通知Pipeline回復已經讀取
```
一個管道化的服務器可以使用相同的調用來保證回復并行的生成并以正確的順序寫入。
### func (\*Pipeline) [Next](https://github.com/golang/go/blob/master/src/net/textproto/pipeline.go#L36 "View Source")
```
func (p *Pipeline) Next() uint
```
返回下一對request/response的id。
### func (\*Pipeline) [StartRequest](https://github.com/golang/go/blob/master/src/net/textproto/pipeline.go#L46 "View Source")
```
func (p *Pipeline) StartRequest(id uint)
```
阻塞程序,直到輪到給定id來發送(讀取)request。
### func (\*Pipeline) [StartResponse](https://github.com/golang/go/blob/master/src/net/textproto/pipeline.go#L58 "View Source")
```
func (p *Pipeline) StartResponse(id uint)
```
阻塞程序,直到輪到給定id來讀取(發送)response。
### func (\*Pipeline) [EndRequest](https://github.com/golang/go/blob/master/src/net/textproto/pipeline.go#L52 "View Source")
```
func (p *Pipeline) EndRequest(id uint)
```
通知p,給定id的request的操作已經結束了。
### func (\*Pipeline) [EndResponse](https://github.com/golang/go/blob/master/src/net/textproto/pipeline.go#L64 "View Source")
```
func (p *Pipeline) EndResponse(id uint)
```
通知p,給定id的response的操作已經結束了。
## type [Conn](https://github.com/golang/go/blob/master/src/net/textproto/textproto.go#L58 "View Source")
```
type Conn struct {
Reader
Writer
Pipeline
// 內含隱藏或非導出字段
}
```
Conn代表一個文本網絡協議的連接。它包含一個Reader和一個Writer來管理讀寫,一個Pipeline來對連接中并行的請求進行排序。匿名嵌入的類型字段是Conn可以調用它們的方法。
### func [NewConn](https://github.com/golang/go/blob/master/src/net/textproto/textproto.go#L66 "View Source")
```
func NewConn(conn io.ReadWriteCloser) *Conn
```
NewConn函數返回以I/O為底層的Conn。
### func [Dial](https://github.com/golang/go/blob/master/src/net/textproto/textproto.go#L81 "View Source")
```
func Dial(network, addr string) (*Conn, error)
```
Dial函數使用net.Dial在給定網絡上和給定地址建立網絡連接,并返回用于該連接的Conn。
### func (\*Conn) [Cmd](https://github.com/golang/go/blob/master/src/net/textproto/textproto.go#L114 "View Source")
```
func (c *Conn) Cmd(format string, args ...interface{}) (id uint, err error)
```
Cmd方法用于在管道中等待輪到它執行,并發送命令。命令文本是用給定的format字符串和參數格式化生成的。并會在最后添加上\r\n。Cmd函數返回該命令的Pipeline id,用于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)
```
### func (\*Conn) [Close](https://github.com/golang/go/blob/master/src/net/textproto/textproto.go#L75 "View Source")
```
func (c *Conn) Close() error
```
Close方法關閉連接。
## Bugs
[?](https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L16 "View Source")為了讓調用者處理拒絕服務攻擊,Reader接口應該允許他們設置和重設從連接讀取的字節數。
- 庫
- package achive
- package tar
- package zip
- package bufio
- package builtin
- package bytes
- package compress
- package bzip2
- package flate
- package gzip
- package lzw
- package zlib
- package container
- package heap
- package list
- package ring
- package crypto
- package aes
- package cipher
- package des
- package dsa
- package ecdsa
- package elliptic
- package hmac
- package md5
- package rand
- package rc4
- package rsa
- package sha1
- package sha256
- package sha512
- package subtle
- package tls
- package x509
- package pkix
- package database
- package sql
- package driver
- package encoding
- package ascii85
- package asn1
- package base32
- package base64
- package binary
- package csv
- package gob
- package hex
- package json
- package pem
- package xml
- package errors
- package expvar
- package flag
- package fmt
- package go
- package doc
- package format
- package parser
- package printer
- package hash
- package adler32
- package crc32
- package crc64
- package fnv
- package html
- package template
- package image
- package color
- package palette
- package draw
- package gif
- package jpeg
- package png
- package index
- package suffixarray
- package io
- package ioutil
- package log
- package syslog
- package math
- package big
- package cmplx
- package rand
- package mime
- package multipart
- package net
- package http
- package cgi
- package cookiejar
- package fcgi
- package httptest
- package httputil
- package pprof
- package mail
- package rpc
- package jsonrpc
- package smtp
- package textproto
- package url
- package os
- package exec
- package signal
- package user
- package path
- package filepath
- package reflect
- package regexp
- package runtime
- package cgo
- package debug
- package pprof
- package race
- package sort
- package strconv
- package strings
- package sync
- package atomic
- package text
- package scanner
- package tabwriter
- package template
- package time
- package unicode
- package utf16
- package utf8
- package unsafe