broker.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package coap
  2. import "net"
  3. type Broker struct {
  4. m map[string]muxEntry
  5. Mgr *Manager
  6. }
  7. type muxEntry struct {
  8. h Handler
  9. pattern string
  10. }
  11. func NewBroker() *Broker {
  12. mgr := NewManager()
  13. return &Broker{
  14. Mgr: mgr,
  15. m: make(map[string]muxEntry),
  16. }
  17. }
  18. func pathMatch(pattern string, path string) bool {
  19. if len(pattern) == 0 {
  20. return false
  21. }
  22. n := len(pattern)
  23. if pattern[n-1] != '/' {
  24. return pattern == path
  25. }
  26. return len(path) >= n && path[0:n] == pattern
  27. }
  28. func (b *Broker) match(path string) (h Handler, pattern string) {
  29. var n = 0
  30. for k, v := range b.m {
  31. if !pathMatch(k, path) {
  32. continue
  33. }
  34. if h == nil || len(k) > n {
  35. n = len(k)
  36. h = v.h
  37. pattern = v.pattern
  38. }
  39. }
  40. return
  41. }
  42. func notFoundHandler(l *net.UDPConn, a *net.UDPAddr, m Message) Message {
  43. if m.IsConfirmable() {
  44. return &BaseMessage{
  45. Type: ACK,
  46. Code: NotFound,
  47. }
  48. }
  49. return nil
  50. }
  51. func (b *Broker) ServeCOAP(l *net.UDPConn, a *net.UDPAddr, m Message) Message {
  52. h, _ := b.match(m.PathString())
  53. if h == nil {
  54. h, _ = funcHandler(notFoundHandler), ""
  55. }
  56. return h.ServeCOAP(l, a, m)
  57. }
  58. func (b *Broker) Handle(pattern string, handler Handler) {
  59. for pattern != "" && pattern[0] == '/' {
  60. pattern = pattern[1:]
  61. }
  62. if pattern == "" {
  63. panic("http: invalid pattern " + pattern)
  64. }
  65. if handler == nil {
  66. panic("http: nil handler")
  67. }
  68. b.m[pattern] = muxEntry{h: handler, pattern: pattern}
  69. }
  70. // HandleFunc configures a handler for the given path.
  71. func (b *Broker) HandleFunc(pattern string,
  72. f func(l *net.UDPConn, a *net.UDPAddr, m Message) Message) {
  73. b.Handle(pattern, b.Mgr.FuncHandler(f))
  74. }