在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
package pingo import ( "bufio" "bytes" "flag" "fmt" "io" "math/rand" "net" "net/rpc" "os" "path" "path/filepath" "reflect" "strings" "time" )
// Register a new object this plugin exports. The object must be // an exported symbol and obey all rules an object in the standard // "rpc" module has to obey. //注册的一个对象作为可以导出对象。这个对象必须符合RPC规则
// - exported method of exported type // - two arguments, both of exported type // - the second argument is a pointer // - one return value, of type error // Register will panic if called after Run. //如果在运行中 注册对象 就会报错
func Register(obj interface{}) { if defaultServer.running { panic("Do not call Register after Run") } defaultServer.register(obj)//注册可导出的对象 }
// Run will start all the necessary steps to make the plugin available. //调用Run函数是必须的来保证插件的可用性
func Run() error { if !flag.Parsed() {//判断参数是否解析 flag.Parse()//解析当前参数 } return defaultServer.run() }
// Internal object for plugin control type PingoRpc struct{} // Default constructor for interal object. Do not call manually. func NewPingoRpc() *PingoRpc { return &PingoRpc{} }
// Internal RPC call to shut down a plugin. Do not call manually. func (s *PingoRpc) Exit(status int, unused *int) error { os.Exit(status) return nil }
type config struct { proto string addr string prefix string unixdir string }
func makeConfig() *config { c := &config{} flag.StringVar(&c.proto, "pingo:proto", "unix", "Protocol to use: unix or tcp") flag.StringVar(&c.unixdir, "pingo:unixdir", "", "Alternative directory for unix socket") flag.StringVar(&c.prefix, "pingo:prefix", "pingo", "Prefix to output lines") return c }
type rpcServer struct { *rpc.Server secret string objs []string conf *config running bool }
func newRpcServer() *rpcServer { rand.Seed(time.Now().UTC().UnixNano()) r := &rpcServer{ Server: rpc.NewServer(), secret: randstr(64), objs: make([]string, 0), conf: makeConfig(), // conf remains fixed after this point } r.register(&PingoRpc{}) return r }
var defaultServer = newRpcServer() type bufReadWriteCloser struct { *bufio.Reader r io.ReadWriteCloser }
func newBufReadWriteCloser(r io.ReadWriteCloser) *bufReadWriteCloser { return &bufReadWriteCloser{Reader: bufio.NewReader(r), r: r} }
func (b *bufReadWriteCloser) Write(data []byte) (int, error) { return b.r.Write(data) }
func (b *bufReadWriteCloser) Close() error { return b.r.Close() }
func readHeaders(brwc *bufReadWriteCloser) ([]byte, error) { var buf bytes.Buffer var headerEnd bool for { b, err := brwc.ReadByte() if err != nil { return []byte(""), err } buf.WriteByte(b) if b == '\n' { if headerEnd { break } headerEnd = true } else { headerEnd = false } } return buf.Bytes(), nil }
func parseHeaders(brwc *bufReadWriteCloser, m map[string]string) error { headers, err := readHeaders(brwc) if err != nil { return err } r := bytes.NewReader(headers) scanner := bufio.NewScanner(r) for scanner.Scan() { parts := strings.SplitN(scanner.Text(), ": ", 2) if parts[0] == "" { continue } m[parts[0]] = parts[1] } return nil }
func (r *rpcServer) authConn(token string) bool { if token != "" && token == r.secret { return true } return false }
func (r *rpcServer) serveConn(conn io.ReadWriteCloser, h meta) { bconn := newBufReadWriteCloser(conn) defer bconn.Close() headers := make(map[string]string) if err := parseHeaders(bconn, headers); err != nil { h.output("error", err.Error()) return } if r.authConn(headers["Auth-Token"]) |
请发表评论