Exemple #1
0
func EvaluateEmail(t *Templater, baseName string, context interface{}) (*Email, error) {
	email := &Email{}

	headerBytes, err := t.Evaluate(baseName+".hdr", context)
	if err != nil {
		return nil, fmt.Errorf("%s.hdr: %s", baseName, err)
	}

	r := textproto.NewReader(bufio.NewReader(bytes.NewReader(headerBytes)))
	email.Header, err = r.ReadMIMEHeader()
	if err != nil {
		return nil, fmt.Errorf("%s.hdr: %s", baseName, err)
	}

	if email.Text, err = t.Evaluate(baseName+".txt", context); err != nil {
		return nil, fmt.Errorf("%s.txt: %s", baseName, err)
	}

	if email.HTML, err = t.Evaluate(baseName+".html", context); err != nil {
		return nil, fmt.Errorf("%s.html: %s", baseName, err)
	}

	if sf, ok := context.(staticFiles); ok {
		attachments := sf.Attachments()
		email.Attachments = make([]Attachment, 0, len(attachments))
		for _, attachment := range attachments {
			email.Attachments = append(email.Attachments, attachment)
		}
		sort.Sort(attachmentList(email.Attachments))
	}

	return email, nil
}
Exemple #2
0
func downloadDict(url string) {
	log.Println("Getting dict", path.Base(url))
	resp, err := http.Get(url)
	if err != nil {
		log.Println("Error getting dict:", err)
		return
	}
	f, err := os.Create(path.Join("dicts", path.Base(url)))
	if err != nil {
		log.Println(err)
		return
	}
	defer f.Close()

	buffered := bufio.NewReader(resp.Body)
	tr := textproto.NewReader(buffered)
	sdchHeader, err := tr.ReadMIMEHeader()
	if err != nil {
		log.Println(err)
		return
	}
	pretty.Println("Decoded sdch header:", sdchHeader)

	_, err = io.Copy(f, buffered)
	if err != nil {
		log.Println(err)
		return
	}
	dictName = path.Base(url)
	log.Println("Got dict", dictName)
}
Exemple #3
0
func (b *body) readTrailer() error {
	// The common case, since nobody uses trailers.
	buf, _ := b.r.Peek(2)
	if bytes.Equal(buf, singleCRLF) {
		b.r.ReadByte()
		b.r.ReadByte()
		return nil
	}

	// Make sure there's a header terminator coming up, to prevent
	// a DoS with an unbounded size Trailer.  It's not easy to
	// slip in a LimitReader here, as textproto.NewReader requires
	// a concrete *bufio.Reader.  Also, we can't get all the way
	// back up to our conn's LimitedReader that *might* be backing
	// this bufio.Reader.  Instead, a hack: we iteratively Peek up
	// to the bufio.Reader's max size, looking for a double CRLF.
	// This limits the trailer to the underlying buffer size, typically 4kB.
	if !seeUpcomingDoubleCRLF(b.r) {
		return errors.New("http: suspiciously long trailer after chunked body")
	}

	hdr, err := textproto.NewReader(b.r).ReadMIMEHeader()
	if err != nil {
		return err
	}
	switch rr := b.hdr.(type) {
	case *Request:
		rr.Trailer = Header(hdr)
	case *Response:
		rr.Trailer = Header(hdr)
	}
	return nil
}
Exemple #4
0
// ProcessResponse adds any returned header data to the response header and sends the rest
// to the response body.
func ProcessResponse(stdout io.Reader, w http.ResponseWriter, r *http.Request) error {
	bufReader := bufio.NewReader(stdout)
	mimeReader := textproto.NewReader(bufReader)
	hdr, err := mimeReader.ReadMIMEHeader()
	if err != nil {
		// We got nothing! Assume there is an error. Should be more robust.
		return err
	}
	if err == nil {
		for k, vals := range hdr {
			for _, v := range vals {
				w.Header().Add(k, v)
			}
		}
	}
	statusCode := http.StatusOK
	if status := hdr.Get("Status"); status != "" {
		delete(w.Header(), "Status")
		// Parse the status code
		var code int
		if n, _ := fmt.Sscanf(status, "%d", &code); n == 1 {
			statusCode = int(code)
		}
	}
	// Are there other fields we need to rewrite? Probably!
	w.WriteHeader(statusCode)
	io.Copy(w, bufReader)
	return nil
}
Exemple #5
0
func (b *Board) ReadLeds() (colors []color.Color, err error) {
	err = b.Write(0x3, make([]byte, 0))
	if err != nil {
		return
	}
	reader := textproto.NewReader(bufio.NewReader(b.ser))
	line, err := reader.ReadLineBytes()
	if err != nil {
		return
	}

	type LedsMessage struct {
		Leds []string
	}
	var ret LedsMessage
	err = json.Unmarshal(line, &ret)
	if err != nil {
		return
	}

	colors = make([]color.Color, len(ret.Leds))
	for i, c := range ret.Leds {
		r, g, b := hex.HexToRGB(hex.Hex(c))
		colors[i] = color.RGBA{r, g, b, 0}
	}

	return colors, nil
}
Exemple #6
0
// muxConnection takes an inbound connection reads MIME headers from it and
// then attempts to set up a connection to the service specified by the
// Zen-Service header. If the Zen-Service header is missing or the requested
// service is not running (listening) on the local host and error message
// is sent to the requestor and its connection is closed. Otherwise data is
// proxied between the requestor and the local service.
func (mux TCPMux) MuxConnection(conn net.Conn) {
	rdr := textproto.NewReader(bufio.NewReader(conn))
	hdr, err := rdr.ReadMIMEHeader()
	if err != nil {
		sendMuxError(conn, "MuxConnection", "textproto.ReadMIMEHeader", "bad request (no headers)", err)
		conn.Close()
		return
	}

	zs, ok := hdr["Zen-Service"]
	if ok == false {
		sendMuxError(conn, "MuxConnection", "MIMEHeader", "bad request (no Zen-Service header)", err)
		conn.Close()
		return
	}

	port, err := strconv.Atoi(strings.Split(zs[0], "/")[1])
	if err != nil {
		sendMuxError(conn, "MuxConnection", "Zen-Service Header", "bad Zen-Service spec", err)
		conn.Close()
		return
	}

	svc, err := net.Dial("tcp4", fmt.Sprintf("172.17.42.1:%d", port))
	if err != nil {
		sendMuxError(conn, "MuxConnection", "net.Dial", "cannot connect to service", err)
		conn.Close()
		return
	}

	go io.Copy(conn, svc)
	go io.Copy(svc, conn)
}
Exemple #7
0
func main() {
	mcon := CreateConnection()
	sock, err := mcon.Connect()

	if err != nil {
		fmt.Printf("Error connecting to the server")
	}

	mcon.Start(sock)

	reader := bufio.NewReader(sock)
	tp := textproto.NewReader(reader)
	// The input system is really ugly and cumbersome
	// I use holder as fix, but should be rewritten
	input := ""
	holder := ""
	for input != "/quit" {
		line, err := tp.ReadLine()
		if err != nil {
			break // break loop on errors
		}
		fmt.Printf("%s\n", line)

		fmt.Scanf("%s", &input)
		if input != "" && input != holder {
			mcon.SendMessage(sock, input)
			holder = input
		}
	}

	return
}
Exemple #8
0
func main() {
	conn, err := net.Dial("tcp", os.Args[1])
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("connect ok")

	reader := textproto.NewReader(bufio.NewReader(conn))
	for _, s := range os.Args[2:] {
		fmt.Println("send", s)
		_, e := conn.Write([]byte(s + "\r\n"))
		if nil != e {
			fmt.Println(e)
			break
		}

		if "exit" == s {
			break
		}
		ln, e := reader.ReadLine()
		if nil != e {
			fmt.Println(e)
			break
		}
		fmt.Println("recv", ln)
	}
	fmt.Println("disconnect")
}
Exemple #9
0
// QueryForFilePattern searches through all installed files, matching them against
// pattern and returns the list of package names containing a file matching patterns.
//
// Returns an error if globbing /var/lib/dpkg/info/*.list fails.
func (self Dpkg) QueryForFilePattern(pattern string) ([]string, error) {
	result := []string{}

	info := filepath.Join(self.runtimeDir, "info")

	entries, err := filepath.Glob(filepath.Join(info, "*.list"))
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Failed to glob *.list from %s [%s]", info, err))
	}

	for _, entry := range entries {
		if f, err := os.Open(entry); err != nil {
			continue
		} else {
			tpr := textproto.NewReader(bufio.NewReader(f))

			for line, err := tpr.ReadLine(); err == nil; line, err = tpr.ReadLine() {
				if matched, _ := filepath.Match(pattern, line); matched {
					if matches := extractPnRegexp.FindStringSubmatch(entry); len(matches) > 0 {
						result = append(result, matches[smIdxPn])
						// We have to break the inner loop as we want to avoid
						// adding the same package over and over again.
						break
					}
				}
			}
		}
	}

	return result, nil
}
Exemple #10
0
// ParseMIME reads a MIME document from the provided reader and parses it into
// tree of MIMEPart objects.
func ParseMIME(reader *bufio.Reader) (MIMEPart, error) {
	tr := textproto.NewReader(reader)
	header, err := tr.ReadMIMEHeader()
	if err != nil {
		return nil, err
	}
	ctype := header.Get("Content-Type")
	mediatype, params, err := mime.ParseMediaType(ctype)
	if err != nil {
		return nil, err
	}
	root := &memMIMEPart{header: header, contentType: mediatype}

	if strings.HasPrefix(mediatype, "multipart/") {
		boundary := params["boundary"]
		err = parseParts(root, reader, boundary)
		if err != nil {
			return nil, err
		}
	} else {
		// Content is text or data, decode it
		content, err := decodeSection(header.Get("Content-Transfer-Encoding"), ctype, mediatype, reader)
		if err != nil {
			return nil, err
		}
		root.content = content
	}

	return root, nil
}
Exemple #11
0
func (c *client) Serve() {
	go func() {
		reader := textproto.NewReader(bufio.NewReader(c.conn))
		for {
			m, err := reader.ReadLineBytes()
			if err != nil {
				c.stopChan <- err
				return
			}
			c.notifyChan <- append(m, '\n')
		}
	}()

	for {
		select {
		case <-c.stopChan:
			c.exitChan <- c
			c.conn.Close()
			return
		case m := <-c.broadcastChan:
			if _, err := c.conn.Write(m); err != nil {
				c.exitChan <- c
			}
		}
	}
}
Exemple #12
0
func main() {
	if len(os.Args) < 2 {
		fmt.Printf("Usage: %s <script file>\n", os.Args[0])
		return
	}
	namehash_hash := md5.New()
	io.WriteString(namehash_hash, os.Args[1])
	namehash := hex.EncodeToString(namehash_hash.Sum())
	tempfile := temp_dir() + "/" + namehash

	readpipe, writepipe, _ := os.Pipe()
	stdfiles := [](*os.File){readpipe, os.Stdout, os.Stderr}

	syscall.Umask(0077)
	srcfile, err := os.Open(os.Args[1], os.O_RDONLY, 0)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	srcinfo, _ := srcfile.Stat()
	outfile, err := os.Open(tempfile+".ld", os.O_RDONLY, 0)
	var outinfo (*os.FileInfo)
	if err == nil {
		outinfo, _ = outfile.Stat()
		outfile.Close()
	}

	if err != nil || outinfo.Mtime_ns < srcinfo.Mtime_ns {
		//fmt.Printf("Compiling...")
		cpid, cerr := os.ForkExec(GOBIN+"8g", []string{GOBIN + "8g", "-o", tempfile + ".cd", "/dev/stdin"}, nil, "", stdfiles)

		src := textproto.NewReader(bufio.NewReader(srcfile))
		firstline := true
		for {
			s, err := src.ReadLine()
			if err != nil {
				break
			}
			if (len(s) > 0) && (s[0] == '#') && firstline {
				continue
			}
			firstline = false
			writepipe.WriteString(s + "\n")
		}
		writepipe.Close()
		srcfile.Close()

		stage_check(cpid, cerr, "compile")

		lpid, err := os.ForkExec(GOBIN+"8l", []string{GOBIN + "8l", "-o", tempfile + ".ld", tempfile + ".cd"}, nil, "", stdfiles)
		stage_check(lpid, err, "link")
		os.Chmod(tempfile+".ld", 0700)
		//fmt.Println("done.")
	} else {
		//fmt.Println("Running cached.")
	}
	err = os.Exec(tempfile+".ld", os.Args[1:], nil)
	fmt.Println(err)
	os.Exit(1)
}
// NewConn returns a new Conn using conn for I/O.
func NewConn(conn io.ReadWriteCloser) *Conn {
	return &Conn{
		Reader: Reader{R: textproto.NewReader(bufio.NewReader(conn))},
		Writer: Writer{W: bufio.NewWriter(conn)},
		conn:   conn,
	}
}
Exemple #14
0
func NewTextConn(conn net.Conn) *TextConn {
	return &TextConn{
		conn:   conn,
		reader: textproto.NewReader(bufio.NewReader(conn)),
		writer: bufio.NewWriter(conn),
	}
}
Exemple #15
0
func ReadRequest(b *bufio.Reader) (req *http.Request, err error) {
	tp := textproto.NewReader(b)
	var s string
	if s, err = tp.ReadLine(); err != nil {
		return nil, err
	}
	defer func() {
		if err == io.EOF {
			err = io.ErrUnexpectedEOF
		}
	}()

	var f []string
	// TODO a split that only allows N values?
	if f = strings.SplitN(s, " ", 3); len(f) < 3 {
		return nil, &badStringError{"malformed request line", s}
	}
	if f[1] != "*" {
		return nil, &badStringError{"bad URL request", f[1]}
	}
	req = &http.Request{
		Method: f[0],
	}
	var ok bool
	if req.ProtoMajor, req.ProtoMinor, ok = http.ParseHTTPVersion(strings.TrimSpace(f[2])); !ok {
		return nil, &badStringError{"malformed HTTP version", f[2]}
	}

	mimeHeader, err := tp.ReadMIMEHeader()
	if err != nil {
		return nil, err
	}
	req.Header = http.Header(mimeHeader)
	return
}
Exemple #16
0
func (bot *Bot) Connect() {
	conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", bot.server, bot.port))
	if err != nil {
		log.Fatal("Could not connect to server: ", err)
	}
	fmt.Printf("Connected to server %s:%d (%s)\n", bot.server, bot.port, conn.RemoteAddr())
	bot.coutput = make(chan string)
	bot.cinput = make(chan string)
	bot.conn = conn
	reader := bufio.NewReader(bot.conn)
	tp := textproto.NewReader(reader)

	go bot.outputHandler()
	go bot.inputHandler()

	bot.SendCommand("USER " + bot.user + " 8 * :" + bot.nick)
	bot.SendCommand("NICK " + bot.nick)

	for {
		line, err := tp.ReadLine()
		if err != nil {
			log.Fatal(err)
			break
		}
		bot.cinput <- line
	}

}
Exemple #17
0
func TestManualDate(t *testing.T) {
	msgTime := time.Now().Add(-30 * time.Minute)

	m := &Message{}
	m.SetFrom("Doman Sender <*****@*****.**>")
	m.AddTo("First person <*****@*****.**>")

	m.Headers = mail.Header{}
	m.Headers["Date"] = []string{msgTime.Format(time.RFC822)}
	m.Body = "Test message"

	b, err := m.Bytes()
	expectNoError(err)

	t.Logf("Bytes: \n%s", b)

	byteReader := bytes.NewReader(b)
	bufReader := bufio.NewReader(byteReader)
	headerReader := textproto.NewReader(bufReader)
	header, err := headerReader.ReadMIMEHeader()
	expectNoError(err)

	dates, ok := header["Date"]
	Expect(ok).To(BeTrue(), "Date header not found")
	Expect(dates).NotTo(BeEmpty(), "Date header is empty")
	Expect(dates).To(HaveLen(1), "More than one Date header found")

	parsedTime, err := time.Parse(time.RFC822, dates[0])

	Expect(parsedTime.Equal(msgTime.Truncate(time.Minute))).To(BeTrue(), "Time in Date header is not what we specified")
}
Exemple #18
0
// Request returns a HTTP Response with Header and Body
// from fcgi responder
func (this *FCGIClient) Request(p map[string]string, req io.Reader) (resp *http.Response, err error) {

	r, err := this.Do(p, req)
	if err != nil {
		return
	}

	rb := bufio.NewReader(r)
	tp := textproto.NewReader(rb)
	resp = new(http.Response)

	// Parse the response headers.
	mimeHeader, err := tp.ReadMIMEHeader()
	if err != nil {
		return
	}
	resp.Header = http.Header(mimeHeader)

	// TODO: fixTransferEncoding ?
	resp.TransferEncoding = resp.Header["Transfer-Encoding"]
	resp.ContentLength, _ = strconv.ParseInt(resp.Header.Get("Content-Length"), 10, 64)

	if chunked(resp.TransferEncoding) {
		resp.Body = ioutil.NopCloser(httputil.NewChunkedReader(rb))
	} else {
		resp.Body = ioutil.NopCloser(rb)
	}

	return
}
Exemple #19
0
//NewSocketClient creats a SocketClient
func NewSocketClient(address string, option string) (*SocketClient, error) {
	var err error
	scc := new(SocketClient)
	scc.address = address

	scc.connection, err = net.Dial("tcp", address)
	if err != nil {
		return nil, err
	}
	//     defer scc.connection.Close()

	r := bufio.NewReader(scc.connection)
	scc.tp = textproto.NewReader(r)

	fmt.Fprintf(scc.connection, option)
	for {
		line, _ := scc.tp.ReadLine()
		if strings.Index(line, "OK") != -1 {
			break
		}
	}

	scc.mutex = new(sync.Mutex)
	return scc, err
}
Exemple #20
0
func TestAutoDate(t *testing.T) {
	startTime := time.Now()
	m := &Message{}
	m.SetFrom("Doman Sender <*****@*****.**>")
	m.AddTo("First person <*****@*****.**>")

	m.Body = "Test message"

	b, err := m.Bytes()
	expectNoError(err)

	t.Logf("Bytes: \n%s", b)

	byteReader := bytes.NewReader(b)
	bufReader := bufio.NewReader(byteReader)
	headerReader := textproto.NewReader(bufReader)
	header, err := headerReader.ReadMIMEHeader()
	expectNoError(err)

	dates, ok := header["Date"]
	Expect(ok).To(BeTrue(), "Date header not found")
	Expect(dates).NotTo(BeEmpty(), "Date header is empty")
	Expect(dates).To(HaveLen(1), "More than one Date header found")

	parsedTime, err := time.Parse(time.RFC822, dates[0])

	t.Logf("%v", parsedTime)

	Expect(parsedTime.Before(time.Now().Add(1*time.Minute))).To(BeTrue(), "Time in Date header is too low")
	Expect(parsedTime.After(startTime.Add(-1*time.Minute))).To(BeTrue(), "Time in Date header is too high")
}
Exemple #21
0
func NewBot(bot Bot) {
	var resp []string

	bot.Conn = Connect(bot.Server + ":" + bot.Port)

	reader := bufio.NewReader(bot.Conn)
	bot.Tp = textproto.NewReader(reader)

	Send(&bot, "NICK "+bot.Nick)
	resp = Send(&bot, "USER "+bot.Nick+" 1 1 1:"+bot.Nick)

	for resp[1] != "001" {
		resp = Read(&bot)
	}
	resp = Send(&bot, "JOIN "+bot.Channel)

	for bot.Err == nil {
		resp = Parse(&bot, resp)
		if len(resp) > 2 && GetNick(resp[0]) == bot.Nick && resp[1] == "QUIT" {
			return
		} else if resp == nil {
			resp = Read(&bot)
		}
	}
	if bot.Err != io.EOF {
		panic(bot.Err)
	} else if bot.Err == io.EOF {
		//WTF?
		go NewBot(bot)
	}
}
Exemple #22
0
func parseEmail(data []byte) *templates.Email {
	r := bufio.NewReader(bytes.NewReader(data))
	hr := textproto.NewReader(r)
	h, err := hr.ReadMIMEHeader()
	So(err, ShouldBeNil)

	So(h.Get("Mime-Version"), ShouldEqual, "1.0")
	ctype := h.Get("Content-Type")
	So(ctype, ShouldStartWith, "multipart/alternative;")
	So(ctype, ShouldEndWith, `"`)
	idx := strings.Index(ctype, `boundary="`)
	So(idx, ShouldBeGreaterThan, -1)
	mpr := multipart.NewReader(r, ctype[idx+len(`boundary="`):len(ctype)-1])

	part, err := mpr.NextPart()
	So(err, ShouldBeNil)
	So(part.Header.Get("Content-Type"), ShouldEqual, `text/plain; charset="utf-8"; format="fixed"`)
	text, err := ioutil.ReadAll(part)
	So(err, ShouldBeNil)

	part, err = mpr.NextPart()
	So(err, ShouldBeNil)
	So(part.Header.Get("Content-Type"), ShouldEqual, `text/html; charset="utf-8"`)
	html, err := ioutil.ReadAll(part)
	So(err, ShouldBeNil)

	email := &templates.Email{
		Header:      h,
		Text:        text,
		HTML:        html,
		Attachments: []templates.Attachment{},
	}

	for {
		part, err = mpr.NextPart()
		if err == io.EOF {
			break
		}
		So(err, ShouldBeNil)

		contentID := part.Header.Get("Content-ID")
		disposition := part.Header.Get("Content-Disposition")
		idx = strings.Index(disposition, `filename="`)
		So(idx, ShouldBeGreaterThan, -1)
		filename := disposition[idx+len(`filename="`):]
		idx = strings.IndexRune(filename, '"')
		So(idx, ShouldBeGreaterThan, -1)
		filename = filename[:idx]
		content, err := ioutil.ReadAll(part)
		So(err, ShouldBeNil)

		email.Attachments = append(email.Attachments, templates.Attachment{
			Name:      filename,
			ContentID: contentID,
			Content:   content,
		})
	}

	return email
}
Exemple #23
0
func launchClient() {
	conn, err := net.Dial("tcp", serverURL+":"+serverPORT)
	if err != nil {
		errorMessage("error", "Unable to connect irc server: "+err.Error())
		return
	}

	fmt.Fprintf(conn, "PASS %s\r\n", token)
	fmt.Fprintf(conn, "NICK %s\r\n", nick)
	fmt.Fprintf(conn, "JOIN %s\r\n", channel)
	defer conn.Close()

	reader := bufio.NewReader(conn)
	tp := textproto.NewReader(reader)
	for {
		line, err := tp.ReadLine()
		if err != nil {
			errorMessage("error", "Unable to get message: "+err.Error())
			return
		}
		outputMessage("debug", line)

		if strings.Contains(line, "PRIVMSG "+channel+" :") {
			items := strings.Split(line, "PRIVMSG "+channel+" :")
			outputMessage("message", items[1])
		}

		if strings.Contains(line, "PING ") {
			pongdata := strings.Split(line, "PING ")
			fmt.Fprintf(conn, "PONG %s\r\n", pongdata[1])
		}
	}
}
Exemple #24
0
func (i *HttpOutput) isResponse(data []byte) bool {
	buf := bytes.NewBuffer(data)
	reader := bufio.NewReader(buf)
	tp := textproto.NewReader(reader)

	firstLine, _ := tp.ReadLine()
	return strings.HasPrefix(strings.TrimSpace(firstLine), "HTTP/")
}
Exemple #25
0
func newTextprotoReader(br *bufio.Reader) *textproto.Reader {
	if v := textprotoReaderPool.Get(); v != nil {
		tr := v.(*textproto.Reader)
		tr.R = br
		return tr
	}
	return textproto.NewReader(br)
}
Exemple #26
0
// bytesToHeader converts the provided bytes into a translations header.
func bytesToHeader(header []byte) textproto.MIMEHeader {
	reader := bufio.NewReader(bytes.NewReader(header))
	h, err := textproto.NewReader(reader).ReadMIMEHeader()
	if err == io.EOF {
		return h
	}
	return textproto.MIMEHeader{}
}
Exemple #27
0
func NewConnection(conn net.Conn) Connection {
	lr := &io.LimitedReader{R: conn, N: math.MaxInt64}
	return &NetConnection{
		conn:   conn,
		lr:     lr,
		reader: textproto.NewReader(bufio.NewReader(lr)),
	}
}
Exemple #28
0
func (c *client) ReadMessage() (*message, error) {
	rd := textproto.NewReader(c.rw)
	line, err := rd.ReadLine()
	if err != nil {
		return nil, err
	}
	return ParseLine(line)
}
Exemple #29
0
func (bp *Part) populateHeaders() os.Error {
	r := textproto.NewReader(bp.mr.bufReader)
	header, err := r.ReadMIMEHeader()
	if err == nil {
		bp.Header = header
	}
	return err
}
func newHandler(s *server, conn net.Conn) *handler {
	return &handler{
		server: s,
		conn:   conn,
		reader: textproto.NewReader(bufio.NewReader(conn)),
		writer: textproto.NewWriter(bufio.NewWriter(conn)),
	}
}