dashboard.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package dashboard
  2. import (
  3. "html/template"
  4. "math/rand"
  5. "net/http"
  6. "time"
  7. log "github.com/Sirupsen/logrus"
  8. _ "github.com/flashmob/go-guerrilla/dashboard/statik"
  9. "github.com/gorilla/mux"
  10. "github.com/gorilla/websocket"
  11. "github.com/rakyll/statik/fs"
  12. )
  13. const (
  14. dashboard = "index.html"
  15. dashboardPath = "dashboard/html/index.html"
  16. sessionTimeout = time.Hour * 24 // TODO replace with config
  17. )
  18. var (
  19. // Cache of HTML templates
  20. templates = template.Must(template.ParseFiles(dashboardPath))
  21. config *Config
  22. sessions map[string]*session
  23. )
  24. var upgrader = websocket.Upgrader{
  25. ReadBufferSize: 1024,
  26. WriteBufferSize: 1024,
  27. }
  28. type Config struct {
  29. ListenInterface string
  30. }
  31. func Run(c *Config) {
  32. statikFS, _ := fs.New()
  33. config = c
  34. sessions = map[string]*session{}
  35. r := mux.NewRouter()
  36. r.HandleFunc("/ws", webSocketHandler)
  37. r.PathPrefix("/").Handler(http.FileServer(statikFS))
  38. rand.Seed(time.Now().UnixNano())
  39. go dataListener(tickInterval)
  40. http.ListenAndServe(c.ListenInterface, r)
  41. }
  42. func indexHandler(w http.ResponseWriter, r *http.Request) {
  43. c, err := r.Cookie("SID")
  44. _, sidExists := sessions[c.Value]
  45. if err != nil || !sidExists {
  46. // No SID cookie
  47. startSession(w, r)
  48. }
  49. w.WriteHeader(http.StatusOK)
  50. templates.ExecuteTemplate(w, dashboard, nil)
  51. }
  52. func webSocketHandler(w http.ResponseWriter, r *http.Request) {
  53. log.Info("dashboard:112")
  54. cookie, err := r.Cookie("SID")
  55. if err != nil {
  56. // TODO error
  57. w.WriteHeader(http.StatusInternalServerError)
  58. }
  59. sess, sidExists := sessions[cookie.Value]
  60. if !sidExists {
  61. // No SID cookie
  62. sess = startSession(w, r)
  63. }
  64. conn, err := upgrader.Upgrade(w, r, nil)
  65. if err != nil {
  66. w.WriteHeader(http.StatusInternalServerError)
  67. // TODO Internal error
  68. return
  69. }
  70. sess.ws = conn
  71. c := make(chan *dataFrame)
  72. sess.send = c
  73. // TODO send store contents at connection time
  74. store.subscribe(sess.id, c)
  75. go sess.receive()
  76. go sess.transmit()
  77. }
  78. func startSession(w http.ResponseWriter, r *http.Request) *session {
  79. sessionID := newSessionID()
  80. cookie := &http.Cookie{
  81. Name: "SID",
  82. Value: sessionID,
  83. Path: "/",
  84. // Secure: true, // TODO re-add this when TLS is set up
  85. }
  86. sess := &session{
  87. id: sessionID,
  88. }
  89. http.SetCookie(w, cookie)
  90. sessions[sessionID] = sess
  91. return sess
  92. }
  93. func getSession(r *http.Request) *session {
  94. c, err := r.Cookie("SID")
  95. if err != nil {
  96. return nil
  97. }
  98. sid := c.Value
  99. sess, ok := sessions[sid]
  100. if !ok {
  101. return nil
  102. }
  103. return sess
  104. }