src/pkg/net/textproto/textproto.go - The Go Programming Language

Golang

Source file src/pkg/net/textproto/textproto.go

     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 implements generic support for text-based request/response
     6	// protocols in the style of HTTP, NNTP, and SMTP.
     7	//
     8	// The package provides:
     9	//
    10	// Error, which represents a numeric error response from
    11	// a server.
    12	//
    13	// Pipeline, to manage pipelined requests and responses
    14	// in a client.
    15	//
    16	// Reader, to read numeric response code lines,
    17	// key: value headers, lines wrapped with leading spaces
    18	// on continuation lines, and whole text blocks ending
    19	// with a dot on a line by itself.
    20	//
    21	// Writer, to write dot-encoded text blocks.
    22	//
    23	// Conn, a convenient packaging of Reader, Writer, and Pipeline for use
    24	// with a single network connection.
    25	//
    26	package textproto
    27	
    28	import (
    29		"bufio"
    30		"fmt"
    31		"io"
    32		"net"
    33	)
    34	
    35	// An Error represents a numeric error response from a server.
    36	type Error struct {
    37		Code int
    38		Msg  string
    39	}
    40	
    41	func (e *Error) Error() string {
    42		return fmt.Sprintf("%03d %s", e.Code, e.Msg)
    43	}
    44	
    45	// A ProtocolError describes a protocol violation such
    46	// as an invalid response or a hung-up connection.
    47	type ProtocolError string
    48	
    49	func (p ProtocolError) Error() string {
    50		return string(p)
    51	}
    52	
    53	// A Conn represents a textual network protocol connection.
    54	// It consists of a Reader and Writer to manage I/O
    55	// and a Pipeline to sequence concurrent requests on the connection.
    56	// These embedded types carry methods with them;
    57	// see the documentation of those types for details.
    58	type Conn struct {
    59		Reader
    60		Writer
    61		Pipeline
    62		conn io.ReadWriteCloser
    63	}
    64	
    65	// NewConn returns a new Conn using conn for I/O.
    66	func NewConn(conn io.ReadWriteCloser) *Conn {
    67		return &Conn{
    68			Reader: Reader{R: bufio.NewReader(conn)},
    69			Writer: Writer{W: bufio.NewWriter(conn)},
    70			conn:   conn,
    71		}
    72	}
    73	
    74	// Close closes the connection.
    75	func (c *Conn) Close() error {
    76		return c.conn.Close()
    77	}
    78	
    79	// Dial connects to the given address on the given network using net.Dial
    80	// and then returns a new Conn for the connection.
    81	func Dial(network, addr string) (*Conn, error) {
    82		c, err := net.Dial(network, addr)
    83		if err != nil {
    84			return nil, err
    85		}
    86		return NewConn(c), nil
    87	}
    88	
    89	// Cmd is a convenience method that sends a command after
    90	// waiting its turn in the pipeline.  The command text is the
    91	// result of formatting format with args and appending \r\n.
    92	// Cmd returns the id of the command, for use with StartResponse and EndResponse.
    93	//
    94	// For example, a client might run a HELP command that returns a dot-body
    95	// by using:
    96	//
    97	//	id, err := c.Cmd("HELP")
    98	//	if err != nil {
    99	//		return nil, err
   100	//	}
   101	//
   102	//	c.StartResponse(id)
   103	//	defer c.EndResponse(id)
   104	//
   105	//	if _, _, err = c.ReadCodeLine(110); err != nil {
   106	//		return nil, err
   107	//	}
   108	//	text, err := c.ReadDotAll()
   109	//	if err != nil {
   110	//		return nil, err
   111	//	}
   112	//	return c.ReadCodeLine(250)
   113	//
   114	func (c *Conn) Cmd(format string, args ...interface{}) (id uint, err error) {
   115		id = c.Next()
   116		c.StartRequest(id)
   117		err = c.PrintfLine(format, args...)
   118		c.EndRequest(id)
   119		if err != nil {
   120			return 0, err
   121		}
   122		return id, nil
   123	}