notify.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package nsqadmin
  2. import (
  3. "encoding/base64"
  4. "net/http"
  5. "net/url"
  6. "os"
  7. "strings"
  8. "time"
  9. )
  10. type AdminAction struct {
  11. Action string `json:"action"`
  12. Topic string `json:"topic"`
  13. Channel string `json:"channel,omitempty"`
  14. Node string `json:"node,omitempty"`
  15. Timestamp int64 `json:"timestamp"`
  16. User string `json:"user,omitempty"`
  17. RemoteIP string `json:"remote_ip"`
  18. UserAgent string `json:"user_agent"`
  19. URL string `json:"url"` // The URL of the HTTP request that triggered this action
  20. Via string `json:"via"` // the Hostname of the nsqadmin performing this action
  21. }
  22. func basicAuthUser(req *http.Request) string {
  23. s := strings.SplitN(req.Header.Get("Authorization"), " ", 2)
  24. if len(s) != 2 || s[0] != "Basic" {
  25. return ""
  26. }
  27. b, err := base64.StdEncoding.DecodeString(s[1])
  28. if err != nil {
  29. return ""
  30. }
  31. pair := strings.SplitN(string(b), ":", 2)
  32. if len(pair) != 2 {
  33. return ""
  34. }
  35. return pair[0]
  36. }
  37. func (s *httpServer) notifyAdminAction(action, topic, channel, node string, req *http.Request) {
  38. if s.nsqadmin.getOpts().NotificationHTTPEndpoint == "" {
  39. return
  40. }
  41. via, _ := os.Hostname()
  42. u := url.URL{
  43. Scheme: "http",
  44. Host: req.Host,
  45. Path: req.URL.Path,
  46. RawQuery: req.URL.RawQuery,
  47. }
  48. if req.TLS != nil || req.Header.Get("X-Scheme") == "https" {
  49. u.Scheme = "https"
  50. }
  51. a := &AdminAction{
  52. Action: action,
  53. Topic: topic,
  54. Channel: channel,
  55. Node: node,
  56. Timestamp: time.Now().Unix(),
  57. User: basicAuthUser(req),
  58. RemoteIP: req.RemoteAddr,
  59. UserAgent: req.UserAgent(),
  60. URL: u.String(),
  61. Via: via,
  62. }
  63. // Perform all work in a new goroutine so this never blocks
  64. go func() { s.nsqadmin.notifications <- a }()
  65. }