in mux.go [180:210]
func (m *mux) getConnHandler(conn net.Conn, buf *bytes.Buffer) (connHandlerFunc, error) {
rbuf := io.TeeReader(conn, buf)
framer := http2.NewFramer(conn, rbuf)
framer.SetReuseFrames()
// Client expects SETTINGS first, so send empty initial settings.
// The real server will send a new one with the real settings.
//
// When replaying frames to the real server, we'll need to suppress
// the ACK for this frame, which the server won't know about.
if err := framer.WriteSettings(); err != nil {
return nil, err
}
// Read client preface. We don't bother verifying it here, as it will
// be verified later by the real http2.Server.
var preface [len(http2.ClientPreface)]byte
if _, err := io.ReadFull(rbuf, preface[:]); err != nil {
return nil, err
}
contentType, err := m.getContentType(framer, buf)
if err != nil {
return nil, err
}
connHandler := m.handleHTTP
if contentType == grpcContentType {
connHandler = m.handleGRPC
}
return connHandler, nil
}