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.
17 // BUG(rsc): To let callers manage exposure to denial of service
18 // attacks, Reader should allow them to set and reset a limit on
19 // the number of bytes read from the connection.
21 // A Reader implements convenience methods for reading requests
22 // or responses from a text protocol network connection.
28 // NewReader returns a new Reader reading from r.
29 func NewReader(r *bufio.Reader) *Reader {
33 // ReadLine reads a single line from r,
34 // eliding the final \n or \r\n from the returned string.
35 func (r *Reader) ReadLine() (string, os.Error) {
36 line, err := r.readLineSlice()
37 return string(line), err
40 // ReadLineBytes is like ReadLine but returns a []byte instead of a string.
41 func (r *Reader) ReadLineBytes() ([]byte, os.Error) {
42 line, err := r.readLineSlice()
44 buf := make([]byte, len(line))
51 func (r *Reader) readLineSlice() ([]byte, os.Error) {
53 line, _, err := r.R.ReadLine()
57 // ReadContinuedLine reads a possibly continued line from r,
58 // eliding the final trailing ASCII white space.
59 // Lines after the first are considered continuations if they
60 // begin with a space or tab character. In the returned data,
61 // continuation lines are separated from the previous line
62 // only by a single space: the newline and leading white space
65 // For example, consider this input:
71 // The first call to ReadContinuedLine will return "Line 1 continued..."
72 // and the second will return "Line 2".
74 // A line consisting of only white space is never continued.
76 func (r *Reader) ReadContinuedLine() (string, os.Error) {
77 line, err := r.readContinuedLineSlice()
78 return string(line), err
81 // trim returns s with leading and trailing spaces and tabs removed.
82 // It does not assume Unicode or UTF-8.
83 func trim(s []byte) []byte {
85 for i < len(s) && (s[i] == ' ' || s[i] == '\t') {
89 for n > i && (s[n-1] == ' ' || s[n-1] == '\t') {
95 // ReadContinuedLineBytes is like ReadContinuedLine but
96 // returns a []byte instead of a string.
97 func (r *Reader) ReadContinuedLineBytes() ([]byte, os.Error) {
98 line, err := r.readContinuedLineSlice()
100 buf := make([]byte, len(line))
107 func (r *Reader) readContinuedLineSlice() ([]byte, os.Error) {
108 // Read the first line.
109 line, err := r.readLineSlice()
113 if len(line) == 0 { // blank line - no continuation
119 if r.R.Buffered() < 1 {
120 // ReadByte will flush the buffer; make a copy of the slice.
122 line = append([]byte(nil), line...)
125 // Look for a continuation line.
126 c, err := r.R.ReadByte()
128 // Delay err until we read the byte next time.
131 if c != ' ' && c != '\t' {
132 // Not a continuation.
138 // The next readLineSlice will invalidate the previous one.
139 line = append(make([]byte, 0, len(line)*2), line...)
142 // Read continuation lines.
144 // Consume leading spaces; one already gone.
146 c, err = r.R.ReadByte()
150 if c != ' ' && c != '\t' {
156 cont, err = r.readLineSlice()
158 line = append(line, ' ')
159 line = append(line, cont...)
164 // Check for leading space on next line.
165 if c, err = r.R.ReadByte(); err != nil {
168 if c != ' ' && c != '\t' {
174 // Delay error until next call.
181 func (r *Reader) readCodeLine(expectCode int) (code int, continued bool, message string, err os.Error) {
182 line, err := r.ReadLine()
186 return parseCodeLine(line, expectCode)
189 func parseCodeLine(line string, expectCode int) (code int, continued bool, message string, err os.Error) {
190 if len(line) < 4 || line[3] != ' ' && line[3] != '-' {
191 err = ProtocolError("short response: " + line)
194 continued = line[3] == '-'
195 code, err = strconv.Atoi(line[0:3])
196 if err != nil || code < 100 {
197 err = ProtocolError("invalid response code: " + line)
201 if 1 <= expectCode && expectCode < 10 && code/100 != expectCode ||
202 10 <= expectCode && expectCode < 100 && code/10 != expectCode ||
203 100 <= expectCode && expectCode < 1000 && code != expectCode {
204 err = &Error{code, message}
209 // ReadCodeLine reads a response code line of the form
211 // where code is a 3-digit status code and the message
212 // extends to the rest of the line. An example of such a line is:
213 // 220 plan9.bell-labs.com ESMTP
215 // If the prefix of the status does not match the digits in expectCode,
216 // ReadCodeLine returns with err set to &Error{code, message}.
217 // For example, if expectCode is 31, an error will be returned if
218 // the status is not in the range [310,319].
220 // If the response is multi-line, ReadCodeLine returns an error.
222 // An expectCode <= 0 disables the check of the status code.
224 func (r *Reader) ReadCodeLine(expectCode int) (code int, message string, err os.Error) {
225 code, continued, message, err := r.readCodeLine(expectCode)
226 if err == nil && continued {
227 err = ProtocolError("unexpected multi-line response: " + message)
232 // ReadResponse reads a multi-line response of the form:
234 // code-message line 1
235 // code-message line 2
237 // code message line n
239 // where code is a 3-digit status code. The first line starts with the
240 // code and a hyphen. The response is terminated by a line that starts
241 // with the same code followed by a space. Each line in message is
242 // separated by a newline (\n).
244 // See page 36 of RFC 959 (http://www.ietf.org/rfc/rfc959.txt) for
247 // If the prefix of the status does not match the digits in expectCode,
248 // ReadResponse returns with err set to &Error{code, message}.
249 // For example, if expectCode is 31, an error will be returned if
250 // the status is not in the range [310,319].
252 // An expectCode <= 0 disables the check of the status code.
254 func (r *Reader) ReadResponse(expectCode int) (code int, message string, err os.Error) {
255 code, continued, message, err := r.readCodeLine(expectCode)
256 for err == nil && continued {
257 line, err := r.ReadLine()
263 var moreMessage string
264 code2, continued, moreMessage, err = parseCodeLine(line, expectCode)
265 if err != nil || code2 != code {
266 message += "\n" + strings.TrimRight(line, "\r\n")
270 message += "\n" + moreMessage
275 // DotReader returns a new Reader that satisfies Reads using the
276 // decoded text of a dot-encoded block read from r.
277 // The returned Reader is only valid until the next call
280 // Dot encoding is a common framing used for data blocks
281 // in text protocols such as SMTP. The data consists of a sequence
282 // of lines, each of which ends in "\r\n". The sequence itself
283 // ends at a line containing just a dot: ".\r\n". Lines beginning
284 // with a dot are escaped with an additional dot to avoid
285 // looking like the end of the sequence.
287 // The decoded form returned by the Reader's Read method
288 // rewrites the "\r\n" line endings into the simpler "\n",
289 // removes leading dot escapes if present, and stops with error os.EOF
290 // after consuming (and discarding) the end-of-sequence line.
291 func (r *Reader) DotReader() io.Reader {
293 r.dot = &dotReader{r: r}
297 type dotReader struct {
302 // Read satisfies reads by decoding dot-encoded data read from d.r.
303 func (d *dotReader) Read(b []byte) (n int, err os.Error) {
304 // Run data through a simple state machine to
305 // elide leading dots, rewrite trailing \r\n into \n,
306 // and detect ending .\r\n line.
308 stateBeginLine = iota // beginning of line; initial state; must be zero
309 stateDot // read . at beginning of line
310 stateDotCR // read .\r at beginning of line
311 stateCR // read \r (possibly at end of line)
312 stateData // reading data in middle of line
313 stateEOF // reached .\r\n end marker line
316 for n < len(b) && d.state != stateEOF {
318 c, err = br.ReadByte()
321 err = io.ErrUnexpectedEOF
353 // Not part of .\r\n.
354 // Consume leading dot and emit saved \r.
361 d.state = stateBeginLine
364 // Not part of \r\n. Emit saved \r
375 d.state = stateBeginLine
381 if err == nil && d.state == stateEOF {
384 if err != nil && d.r.dot == d {
390 // closeDot drains the current DotReader if any,
391 // making sure that it reads until the ending dot line.
392 func (r *Reader) closeDot() {
396 buf := make([]byte, 128)
398 // When Read reaches EOF or an error,
399 // it will set r.dot == nil.
404 // ReadDotBytes reads a dot-encoding and returns the decoded data.
406 // See the documentation for the DotReader method for details about dot-encoding.
407 func (r *Reader) ReadDotBytes() ([]byte, os.Error) {
408 return ioutil.ReadAll(r.DotReader())
411 // ReadDotLines reads a dot-encoding and returns a slice
412 // containing the decoded lines, with the final \r\n or \n elided from each.
414 // See the documentation for the DotReader method for details about dot-encoding.
415 func (r *Reader) ReadDotLines() ([]string, os.Error) {
416 // We could use ReadDotBytes and then Split it,
417 // but reading a line at a time avoids needing a
418 // large contiguous block of memory and is simpler.
423 line, err = r.ReadLine()
426 err = io.ErrUnexpectedEOF
431 // Dot by itself marks end; otherwise cut one dot.
432 if len(line) > 0 && line[0] == '.' {
443 // ReadMIMEHeader reads a MIME-style header from r.
444 // The header is a sequence of possibly continued Key: Value lines
445 // ending in a blank line.
446 // The returned map m maps CanonicalMIMEHeaderKey(key) to a
447 // sequence of values in the same order encountered in the input.
449 // For example, consider this input:
456 // Given that input, ReadMIMEHeader returns the map:
458 // map[string][]string{
459 // "My-Key": {"Value 1", "Value 2"},
460 // "Long-Key": {"Even Longer Value"},
463 func (r *Reader) ReadMIMEHeader() (MIMEHeader, os.Error) {
464 m := make(MIMEHeader)
466 kv, err := r.readContinuedLineSlice()
471 // Key ends at first colon; must not have spaces.
472 i := bytes.IndexByte(kv, ':')
473 if i < 0 || bytes.IndexByte(kv[0:i], ' ') >= 0 {
474 return m, ProtocolError("malformed MIME header line: " + string(kv))
476 key := CanonicalMIMEHeaderKey(string(kv[0:i]))
478 // Skip initial spaces in value.
480 for i < len(kv) && (kv[i] == ' ' || kv[i] == '\t') {
483 value := string(kv[i:])
485 m[key] = append(m[key], value)
494 // CanonicalMIMEHeaderKey returns the canonical format of the
495 // MIME header key s. The canonicalization converts the first
496 // letter and any letter following a hyphen to upper case;
497 // the rest are converted to lowercase. For example, the
498 // canonical key for "accept-encoding" is "Accept-Encoding".
499 func CanonicalMIMEHeaderKey(s string) string {
500 // Quick check for canonical encoding.
502 for i := 0; i < len(s); i++ {
504 if needUpper && 'a' <= c && c <= 'z' {
507 if !needUpper && 'A' <= c && c <= 'Z' {
515 // Canonicalize: first letter upper case
516 // and upper case after each dash.
517 // (Host, User-Agent, If-Modified-Since).
518 // MIME headers are ASCII only, so no Unicode issues.
521 for i, v := range a {
522 if upper && 'a' <= v && v <= 'z' {
525 if !upper && 'A' <= v && v <= 'Z' {