request.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // This file is subject to a 1-clause BSD license.
  2. // Its contents can be found in the enclosed LICENSE file.
  3. package main
  4. import (
  5. "bytes"
  6. "notabug.org/mouz/bot/irc"
  7. )
  8. var (
  9. bNameSplitter = []byte{'!'}
  10. bSpace = []byte{' '}
  11. bPING = []byte("PING")
  12. bERROR = []byte("ERROR")
  13. bQUIT = []byte("QUIT")
  14. )
  15. // parseRequest reads the given message payload and parses it into the
  16. // specified request structure. Returns false if the payload is not a valid
  17. // protocol message.
  18. func parseRequest(r *irc.Request, data []byte) bool {
  19. fields := bytes.Fields(data)
  20. if len(fields) == 0 {
  21. return false
  22. }
  23. // We may be dealing with utility messages like ERROR or PING.
  24. switch {
  25. case bytes.Index(data, bQUIT) > -1:
  26. return false
  27. case bytes.HasPrefix(data, bPING):
  28. r.Type = "PING"
  29. r.Data = string(fields[1][1:])
  30. r.SenderMask = ""
  31. r.SenderName = ""
  32. r.Target = ""
  33. return true
  34. case bytes.HasPrefix(data, bERROR):
  35. r.Type = "ERROR"
  36. r.Data = string(fields[1][1:])
  37. r.SenderMask = ""
  38. r.SenderName = ""
  39. r.Target = ""
  40. return true
  41. }
  42. // Strip leading ':' characters from all fields, except the actual
  43. // message contents.
  44. for i := 0; i < 4 && i < len(fields); i++ {
  45. if fields[i][0] == ':' {
  46. fields[i] = fields[i][1:]
  47. }
  48. }
  49. idx := bytes.Index(fields[0], bNameSplitter)
  50. if idx > -1 {
  51. r.SenderName = string(fields[0][:idx])
  52. r.SenderMask = string(fields[0][idx+1:])
  53. } else {
  54. r.SenderName = string(fields[0])
  55. r.SenderMask = r.SenderName
  56. }
  57. r.Type = string(fields[1])
  58. r.Target = string(fields[2])
  59. if len(fields) > 3 {
  60. r.Data = string(bytes.Join(fields[3:], bSpace))
  61. } else {
  62. r.Data = ""
  63. }
  64. return true
  65. }