github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/net/textproto/reader.go (about)

     1  // Copyright 2010 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package textproto
     6  
     7  import (
     8  	"github.com/shogo82148/std/bufio"
     9  	"github.com/shogo82148/std/io"
    10  )
    11  
    12  // Readerは、テキストプロトコルネットワーク接続からリクエストまたはレスポンスを読み取るための便利なメソッドを実装します。
    13  type Reader struct {
    14  	R   *bufio.Reader
    15  	dot *dotReader
    16  	buf []byte
    17  }
    18  
    19  // NewReaderはrから読み取りを行う新しい [Reader] を返します。
    20  //
    21  // サービス拒否攻撃を避けるために、提供された [bufio.Reader] は
    22  // [io.LimitReader] または同様のReaderから読み取るようになっている必要があります。
    23  func NewReader(r *bufio.Reader) *Reader
    24  
    25  // ReadLineはrから1行だけ読み取り、返された文字列から最後の\nまたは\r\nを省略します。
    26  func (r *Reader) ReadLine() (string, error)
    27  
    28  // ReadLineBytesは、文字列の代わりに[]byteを返す [Reader.ReadLine] と同様の機能です。
    29  func (r *Reader) ReadLineBytes() ([]byte, error)
    30  
    31  // ReadContinuedLineは、rから可能性がある継続行を読み取ります。
    32  // 最後の余分なASCII空白は省略されます。
    33  // 最初の行以降の行は、スペースまたはタブ文字で始まる場合には、
    34  // 継続行と見なされます。返されるデータでは、
    35  // 継続行は前の行とスペース1つのみで区切られます:
    36  // 改行と先頭の空白は削除されます。
    37  //
    38  // 例えば、次の入力を考えてみてください:
    39  //
    40  //	Line 1
    41  //	  continued...
    42  //	Line 2
    43  //
    44  // ReadContinuedLineの最初の呼び出しは「Line 1 continued...」を返し、
    45  // 2番目の呼び出しは「Line 2」を返します。
    46  //
    47  // 空行は継続されません。
    48  func (r *Reader) ReadContinuedLine() (string, error)
    49  
    50  // ReadContinuedLineBytesは、[Reader.ReadContinuedLine] と同様ですが、
    51  // 文字列ではなく[]byteを返します。
    52  func (r *Reader) ReadContinuedLineBytes() ([]byte, error)
    53  
    54  // ReadCodeLineは、下記の形式の応答コード行を読み取ります:
    55  //
    56  //	code message
    57  //
    58  // ここで、codeは3桁のステータスコードであり、messageは行の残りの部分に拡張されます。
    59  // このような行の例は次の通りです:
    60  //
    61  //	220 plan9.bell-labs.com ESMTP
    62  //
    63  // もしステータスのプレフィックスがexpectCodeの数字と一致しない場合、ReadCodeLineはerrを&Error{code, message}に設定して返します。
    64  // 例えば、expectCodeが31である場合、ステータスが[310,319]の範囲にない場合はエラーが返されます。
    65  //
    66  // もし応答が複数行の場合、ReadCodeLineはエラーを返します。
    67  //
    68  // expectCodeが0以下の場合、ステータスコードのチェックは無効になります。
    69  func (r *Reader) ReadCodeLine(expectCode int) (code int, message string, err error)
    70  
    71  // ReadResponseは以下の形式の複数行のレスポンスを読み込みます:
    72  //
    73  //	code-message 行1
    74  //	code-message 行2
    75  //	...
    76  //	code message 行n
    77  //
    78  // ここで、codeは3桁のステータスコードです。最初の行はcodeとハイフンで始まります。
    79  // レスポンスは、同じcodeの後にスペースが続く行で終了します。
    80  // メッセージ中の各行は改行(\n)で区切られます。
    81  //
    82  // 別の形式のレスポンスの詳細については、RFC 959(https://www.ietf.org/rfc/rfc959.txt)の
    83  // 36ページを参照してください:
    84  //
    85  //	code-message 行1
    86  //	message 行2
    87  //	...
    88  //	code message 行n
    89  //
    90  // ステータスのプレフィックスがexpectCodeの数字と一致しない場合、
    91  // ReadResponseはerrを設定した&Error{code, message}として返されます。
    92  // たとえば、expectCodeが31の場合、ステータスが[310、319]の範囲内でない場合、エラーが返されます。
    93  //
    94  // expectCode <= 0の場合、ステータスコードのチェックは無効になります。
    95  func (r *Reader) ReadResponse(expectCode int) (code int, message string, err error)
    96  
    97  // DotReaderは、rから読み込まれたドットエンコードされたブロックのデコードされたテキストを使用して、
    98  // Readsを満たす新しい [Reader] を返します。
    99  // 返されたReaderは、次にrのメソッドが呼び出されるまでの間のみ有効です。
   100  //
   101  // ドットエンコーディングは、SMTPなどのテキストプロトコルで使用される一般的なフレーミングです。
   102  // データは、各行が"\r\n"で終わるシーケンスです。シーケンス自体は、単独のドット「.」の行で終了します:".\r\n"。
   103  // ドットで始まる行は、シーケンスの終わりのように見えないように追加のドットでエスケープされます。
   104  //
   105  // ReaderのReadメソッドによって返されるデコードされた形式は、"\r\n"の行末をよりシンプルな"\n"に書き換え、
   106  // 先頭のドットエスケープを削除し、シーケンスの終了行を消費(および破棄)した後にエラー [io.EOF] で停止します。
   107  func (r *Reader) DotReader() io.Reader
   108  
   109  // ReadDotBytesはドットエンコーディングを読み込み、デコードされたデータを返します。
   110  //
   111  // ドットエンコーディングの詳細については、[Reader.DotReader] メソッドのドキュメントを参照してください。
   112  func (r *Reader) ReadDotBytes() ([]byte, error)
   113  
   114  // ReadDotLines関数はドットエンコーディングを読み取り、各行から最後の\r\nまたは\nを省いたデコードされたスライスを返します。
   115  //
   116  // dot-encodingの詳細については [Reader.DotReader] メソッドのドキュメントを参照してください。
   117  func (r *Reader) ReadDotLines() ([]string, error)
   118  
   119  // ReadMIMEHeaderはrからMIME形式のヘッダーを読み取ります。
   120  // ヘッダーは、連続したキー:値行のシーケンスで、
   121  // 空行で終わる可能性があります。
   122  // 返されるマップmは、[CanonicalMIMEHeaderKey](key)をキーとし、
   123  // 入力で遭遇した順に値のシーケンスをマッピングします。
   124  //
   125  // 例えば、以下のような入力を考えてください:
   126  //
   127  //	My-Key: Value 1
   128  //	Long-Key: Even
   129  //	       Longer Value
   130  //	My-Key: Value 2
   131  //
   132  // この入力が与えられた場合、ReadMIMEHeaderは以下のマップを返します:
   133  //
   134  //	map[string][]string{
   135  //		"My-Key": {"Value 1", "Value 2"},
   136  //		"Long-Key": {"Even Longer Value"},
   137  //	}
   138  func (r *Reader) ReadMIMEHeader() (MIMEHeader, error)
   139  
   140  // CanonicalMIMEHeaderKeyは、MIMEヘッダーキーsの正準形を返します。正準化は、
   141  // 最初の文字とハイフンの後に続くすべての文字を大文字に変換し、
   142  // 残りの文字は小文字に変換します。たとえば、
   143  // "accept-encoding"の正規キーは"Accept-Encoding"です。
   144  // MIMEヘッダーキーはASCIIのみとします。
   145  // sにスペースや無効なヘッダーフィールドバイトが含まれている場合、
   146  // 変更せずに返されます。
   147  func CanonicalMIMEHeaderKey(s string) string