func (h *Handshake) readRawMessage() ([]byte, error) {
	lenBytes := make([]byte, 4)
	_, err := io.ReadFull(h.rw, lenBytes)
	if err != nil {
		return nil, err
	}
	length := int(binary.BigEndian.Uint32(lenBytes))
	res := make([]byte, length)
	_, err = io.ReadFull(h.rw, res[4:])  
	if err != nil {
		return nil, err
	}
	copy(res[:4], lenBytes)
	return res, nil
}
readRawMessage reads un-typed message in the connection. The message is
comprised of an Int32 body-length (N), inclusive of the length itself
followed by N-bytes of the actual body.
package protocol
import (
	"encoding/binary"
	"fmt"
	"io"
)
func NewHandshake(rw io.ReadWriter) *Handshake {
	return &Handshake{rw: rw}
}
type Handshake struct {
	rw     io.ReadWriter
	passed bool
}
func (h *Handshake) Write(m Message) error {
	_, err := h.rw.Write(m)
	return err
}
func (h *Handshake) Read() (Message, error) {
	if h.passed {
		return h.readTypedMessage()
	}
	return h.readRawMessage()
}
func (h *Handshake) Init() (res Message, err error) {
	if h.passed {
		err = fmt.Errorf("handshake already passed")
		return
	}
	res, err = h.Read()
	if err != nil {
		return nil, err
	}
	if res.IsCancel() {
		return res, nil
	}
	if res.IsTLSRequest() {
		_, err = h.rw.Write(TLSResponse(false))
		if err != nil {
			return nil, err
		}
		res, err = h.Read()
		if err != nil {
			return nil, err
		}
	}
	v, err := res.StartupVersion()
	if err != nil {
		return nil, err
	}
	if v != "3.0" {
		return nil, fmt.Errorf("unsupported protocol version %s", v)
	}
	h.passed = true
	return res, nil
}
func (h *Handshake) readTypedMessage() (Message, error) {
	msgType := Message(make([]byte, 1))
	_, err := h.rw.Read(msgType)
	if err != nil {
		return nil, err
	}
	body, err := h.readRawMessage()
	if err != nil {
		return nil, err
	}
	return append(msgType, body...), nil
}