http_ctl.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "log"
  6. "net/http"
  7. "os"
  8. "time"
  9. fractal "git.lattuga.net/blallo/gotools/formatting"
  10. "git.lattuga.net/boyska/circolog"
  11. "github.com/gorilla/mux"
  12. )
  13. func setupHTTPCtl(hub circolog.Hub, verbose, debug bool) *mux.Router {
  14. m := mux.NewRouter()
  15. m.HandleFunc("/pause/toggle", togglePause(hub, verbose, debug)).Methods("POST")
  16. m.HandleFunc("/filter", setFilter(hub, verbose, debug)).Methods("POST")
  17. m.HandleFunc("/status", getStatus(hub, verbose, debug)).Methods("GET")
  18. m.HandleFunc("/logs/clear", clearQueue(hub, verbose)).Methods("POST")
  19. m.HandleFunc("/help", printHelp(verbose)).Methods("GET")
  20. m.HandleFunc("/echo", echo(verbose)).Methods("GET")
  21. return m
  22. }
  23. func getStatus(hub circolog.Hub, verbose, debug bool) http.HandlerFunc {
  24. return func(w http.ResponseWriter, r *http.Request) {
  25. response := make(chan circolog.CommandResponse)
  26. hub.Commands <- circolog.HubFullCommand{
  27. Command: circolog.CommandStatus,
  28. Response: response,
  29. }
  30. resp := <-response
  31. w.Header().Set("content-type", "application/json")
  32. enc := json.NewEncoder(w)
  33. enc.Encode(map[string]interface{}{"status": resp.Value})
  34. }
  35. }
  36. func togglePause(hub circolog.Hub, verbose, debug bool) http.HandlerFunc {
  37. return func(w http.ResponseWriter, r *http.Request) {
  38. if verbose {
  39. log.Printf("[%s] %s - toggled pause", r.Method, r.RemoteAddr)
  40. }
  41. r.ParseForm()
  42. waitTimePar := r.FormValue("waitTime")
  43. var waitTime time.Duration
  44. var err error
  45. if waitTimePar != "" {
  46. waitTime, err = time.ParseDuration(waitTimePar)
  47. if err != nil {
  48. w.WriteHeader(400)
  49. fmt.Fprintln(w, "waitTime not understood:", waitTimePar)
  50. return
  51. }
  52. }
  53. if debug {
  54. fmt.Println("[DEBUG] waitTime:", waitTime)
  55. }
  56. response := make(chan circolog.CommandResponse)
  57. hub.Commands <- circolog.HubFullCommand{
  58. Command: circolog.CommandPauseToggle,
  59. Response: response,
  60. Parameters: map[string]interface{}{"waitTime": waitTime},
  61. }
  62. resp := <-response
  63. active := resp.Value.(bool)
  64. w.Header().Set("content-type", "application/json")
  65. enc := json.NewEncoder(w)
  66. enc.Encode(map[string]interface{}{"paused": !active})
  67. }
  68. }
  69. func setFilter(hub circolog.Hub, verbose, debug bool) http.HandlerFunc {
  70. return func(w http.ResponseWriter, r *http.Request) {
  71. r.ParseForm()
  72. where := r.FormValue("where")
  73. response := make(chan circolog.CommandResponse)
  74. hub.Commands <- circolog.HubFullCommand{
  75. Command: circolog.CommandNewFilter,
  76. Response: response,
  77. Parameters: map[string]interface{}{"where": where},
  78. }
  79. resp := <-response
  80. if !resp.Value.(map[string]interface{})["success"].(bool) {
  81. w.WriteHeader(400)
  82. }
  83. w.Header().Set("content-type", "application/json")
  84. enc := json.NewEncoder(w)
  85. enc.Encode(resp.Value)
  86. }
  87. }
  88. func clearQueue(hub circolog.Hub, verbose bool) http.HandlerFunc {
  89. return func(w http.ResponseWriter, r *http.Request) {
  90. if verbose {
  91. log.Printf("[%s] %s - cleared queue", r.Method, r.RemoteAddr)
  92. }
  93. response := make(chan circolog.CommandResponse)
  94. hub.Commands <- circolog.HubFullCommand{Command: circolog.CommandClear, Response: response}
  95. resp := <-response
  96. success := resp.Value.(bool)
  97. w.Header().Set("content-type", "application/json")
  98. enc := json.NewEncoder(w)
  99. enc.Encode(map[string]interface{}{"success": success})
  100. }
  101. }
  102. func printHelp(verbose bool) http.HandlerFunc {
  103. return func(w http.ResponseWriter, r *http.Request) {
  104. if verbose {
  105. log.Printf("[%s] %s - asked for help", r.Method, r.RemoteAddr)
  106. }
  107. w.Header().Set("content-type", "application/json")
  108. enc := json.NewEncoder(w)
  109. var pathsWithDocs = map[string]string{
  110. "/pause/toggle": "Toggle the server from pause state (not listening)",
  111. "/logs/clear": "Wipe the buffer from all the messages",
  112. "/status": "Get info on the status of the server",
  113. "/help": "This help",
  114. "/echo": "Answers to heartbeat",
  115. }
  116. fractal.EncodeJSON(pathsWithDocs, enc)
  117. if verbose {
  118. errEnc := json.NewEncoder(os.Stderr)
  119. fractal.EncodeJSON(pathsWithDocs, errEnc)
  120. }
  121. }
  122. }
  123. func echo(verbose bool) http.HandlerFunc {
  124. return func(w http.ResponseWriter, r *http.Request) {
  125. log.Println("Echo")
  126. if verbose {
  127. log.Printf("[%s] %s - asked for echo", r.Method, r.RemoteAddr)
  128. }
  129. w.Header().Set("content-type", "text/plain")
  130. fmt.Fprintln(w, "I am on!")
  131. }
  132. }