You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

capability.go 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright (c) 2012-2014 Jeremy Latt
  2. // Copyright (c) 2016- Daniel Oaks <daniel@danieloaks.net>
  3. // released under the MIT license
  4. package irc
  5. import (
  6. "strings"
  7. )
  8. type CapSubCommand string
  9. const (
  10. CAP_LS CapSubCommand = "LS"
  11. CAP_LIST CapSubCommand = "LIST"
  12. CAP_REQ CapSubCommand = "REQ"
  13. CAP_ACK CapSubCommand = "ACK"
  14. CAP_NAK CapSubCommand = "NAK"
  15. CAP_END CapSubCommand = "END"
  16. )
  17. // Capabilities are optional features a client may request from a server.
  18. type Capability string
  19. const (
  20. MultiPrefix Capability = "multi-prefix"
  21. SASL Capability = "sasl"
  22. )
  23. var (
  24. SupportedCapabilities = CapabilitySet{
  25. MultiPrefix: true,
  26. }
  27. )
  28. func (capability Capability) String() string {
  29. return string(capability)
  30. }
  31. // CapModifiers are indicators showing the state of a capability after a REQ or
  32. // ACK.
  33. type CapModifier rune
  34. const (
  35. Ack CapModifier = '~'
  36. Disable CapModifier = '-'
  37. Sticky CapModifier = '='
  38. )
  39. func (mod CapModifier) String() string {
  40. return string(mod)
  41. }
  42. type CapState uint
  43. const (
  44. CapNone CapState = iota
  45. CapNegotiating CapState = iota
  46. CapNegotiated CapState = iota
  47. )
  48. type CapabilitySet map[Capability]bool
  49. func (set CapabilitySet) String() string {
  50. strs := make([]string, len(set))
  51. index := 0
  52. for capability := range set {
  53. strs[index] = string(capability)
  54. index += 1
  55. }
  56. return strings.Join(strs, " ")
  57. }
  58. func (set CapabilitySet) DisableString() string {
  59. parts := make([]string, len(set))
  60. index := 0
  61. for capability := range set {
  62. parts[index] = Disable.String() + capability.String()
  63. index += 1
  64. }
  65. return strings.Join(parts, " ")
  66. }
  67. func (msg *CapCommand) HandleRegServer(server *Server) {
  68. client := msg.Client()
  69. switch msg.subCommand {
  70. case CAP_LS:
  71. client.capState = CapNegotiating
  72. client.Reply(RplCap(client, CAP_LS, SupportedCapabilities))
  73. case CAP_LIST:
  74. client.Reply(RplCap(client, CAP_LIST, client.capabilities))
  75. case CAP_REQ:
  76. for capability := range msg.capabilities {
  77. if !SupportedCapabilities[capability] {
  78. client.Reply(RplCap(client, CAP_NAK, msg.capabilities))
  79. return
  80. }
  81. }
  82. for capability := range msg.capabilities {
  83. client.capabilities[capability] = true
  84. }
  85. client.Reply(RplCap(client, CAP_ACK, msg.capabilities))
  86. case CAP_END:
  87. client.capState = CapNegotiated
  88. server.tryRegister(client)
  89. default:
  90. client.ErrInvalidCapCmd(msg.subCommand)
  91. }
  92. }
  93. func (msg *CapCommand) HandleServer(server *Server) {
  94. client := msg.Client()
  95. switch msg.subCommand {
  96. case CAP_LS:
  97. client.Reply(RplCap(client, CAP_LS, SupportedCapabilities))
  98. case CAP_LIST:
  99. client.Reply(RplCap(client, CAP_LIST, client.capabilities))
  100. case CAP_REQ:
  101. for capability := range msg.capabilities {
  102. if !SupportedCapabilities[capability] {
  103. client.Reply(RplCap(client, CAP_NAK, msg.capabilities))
  104. return
  105. }
  106. }
  107. for capability := range msg.capabilities {
  108. client.capabilities[capability] = true
  109. }
  110. client.Reply(RplCap(client, CAP_ACK, msg.capabilities))
  111. case CAP_END:
  112. // no-op after registration performed
  113. return
  114. default:
  115. client.ErrInvalidCapCmd(msg.subCommand)
  116. }
  117. }