package funker import ( "encoding/json" "fmt" "io/ioutil" "net" "reflect" ) // Handle a Funker function. func Handle(handler interface{}) error { handlerValue := reflect.ValueOf(handler) handlerType := handlerValue.Type() if handlerType.Kind() != reflect.Func || handlerType.NumIn() != 1 || handlerType.NumOut() != 1 { return fmt.Errorf("Handler must be a function with a single parameter and single return value.") } argsValue := reflect.New(handlerType.In(0)) listener, err := net.Listen("tcp", ":9999") if err != nil { return err } conn, err := listener.Accept() if err != nil { return err } // We close listener, because we only allow single request. // Note that TCP "backlog" cannot be used for that purpose. // http://www.perlmonks.org/?node_id=940662 if err = listener.Close(); err != nil { return err } argsJSON, err := ioutil.ReadAll(conn) if err != nil { return err } err = json.Unmarshal(argsJSON, argsValue.Interface()) if err != nil { return err } ret := handlerValue.Call([]reflect.Value{argsValue.Elem()})[0].Interface() retJSON, err := json.Marshal(ret) if err != nil { return err } if _, err = conn.Write(retJSON); err != nil { return err } return conn.Close() }