blob: 89878994dc999445eef14b8365f0becc0760ce8d [file] [log] [blame]
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()
}