handle.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package funker
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "net"
  7. "reflect"
  8. )
  9. // Handle a Funker function.
  10. func Handle(handler interface{}) error {
  11. handlerValue := reflect.ValueOf(handler)
  12. handlerType := handlerValue.Type()
  13. if handlerType.Kind() != reflect.Func || handlerType.NumIn() != 1 || handlerType.NumOut() != 1 {
  14. return fmt.Errorf("Handler must be a function with a single parameter and single return value.")
  15. }
  16. argsValue := reflect.New(handlerType.In(0))
  17. listener, err := net.Listen("tcp", ":9999")
  18. if err != nil {
  19. return err
  20. }
  21. conn, err := listener.Accept()
  22. if err != nil {
  23. return err
  24. }
  25. // We close listener, because we only allow single request.
  26. // Note that TCP "backlog" cannot be used for that purpose.
  27. // http://www.perlmonks.org/?node_id=940662
  28. if err = listener.Close(); err != nil {
  29. return err
  30. }
  31. argsJSON, err := ioutil.ReadAll(conn)
  32. if err != nil {
  33. return err
  34. }
  35. err = json.Unmarshal(argsJSON, argsValue.Interface())
  36. if err != nil {
  37. return err
  38. }
  39. ret := handlerValue.Call([]reflect.Value{argsValue.Elem()})[0].Interface()
  40. retJSON, err := json.Marshal(ret)
  41. if err != nil {
  42. return err
  43. }
  44. if _, err = conn.Write(retJSON); err != nil {
  45. return err
  46. }
  47. return conn.Close()
  48. }