Changeset 275 in code for trunk


Ignore:
Timestamp:
Apr 29, 2020, 5:34:38 PM (5 years ago)
Author:
contact
Message:

Add downstream support for cap-notify

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/downstream.go

    r268 r275  
    5050        Params:  []string{"*", "Invalid username or password"},
    5151}}
     52
     53// permanentDownstreamCaps is the list of always-supported downstream
     54// capabilities.
     55var permanentDownstreamCaps = map[string]string{
     56        "batch": "",
     57        "cap-notify": "",
     58        "echo-message": "",
     59        "message-tags": "",
     60        "sasl": "PLAIN",
     61        "server-time": "",
     62}
    5263
    5364type downstreamConn struct {
     
    6980        negociatingCaps bool
    7081        capVersion      int
     82        supportedCaps   map[string]string
    7183        caps            map[string]bool
    7284
     
    7991                conn: *newConn(srv, netConn, logger),
    8092                id:   id,
     93                supportedCaps: make(map[string]string),
    8194                caps: make(map[string]bool),
    8295        }
     
    8497        if host, _, err := net.SplitHostPort(dc.hostname); err == nil {
    8598                dc.hostname = host
     99        }
     100        for k, v := range permanentDownstreamCaps {
     101                dc.supportedCaps[k] = v
    86102        }
    87103        return dc
     
    440456                }
    441457
    442                 caps := []string{"message-tags", "server-time", "echo-message", "batch"}
    443 
    444                 if dc.capVersion >= 302 {
    445                         caps = append(caps, "sasl=PLAIN")
    446                 } else {
    447                         caps = append(caps, "sasl")
     458                caps := make([]string, 0, len(dc.supportedCaps))
     459                for k, v := range dc.supportedCaps {
     460                        if dc.capVersion >= 302 && v != "" {
     461                                caps = append(caps, k + "=" + v)
     462                        } else {
     463                                caps = append(caps, k)
     464                        }
    448465                }
    449466
     
    454471                        Params:  []string{replyTo, "LS", strings.Join(caps, " ")},
    455472                })
     473
     474                if dc.capVersion >= 302 {
     475                        // CAP version 302 implicitly enables cap-notify
     476                        dc.caps["cap-notify"] = true
     477                }
    456478
    457479                if !dc.registered {
     
    478500                }
    479501
     502                // TODO: atomically ack/nak the whole capability set
    480503                caps := strings.Fields(args[0])
    481504                ack := true
     
    487510                        }
    488511
    489                         enabled := dc.caps[name]
    490                         if enable == enabled {
     512                        if enable == dc.caps[name] {
    491513                                continue
    492514                        }
    493515
    494                         switch name {
    495                         case "sasl", "message-tags", "server-time", "echo-message", "batch":
    496                                 dc.caps[name] = enable
    497                         default:
     516                        _, ok := dc.supportedCaps[name]
     517                        if !ok {
    498518                                ack = false
    499                         }
     519                                break
     520                        }
     521
     522                        if name == "cap-notify" && dc.capVersion >= 302 && !enable {
     523                                // cap-notify cannot be disabled with CAP version 302
     524                                ack = false
     525                                break
     526                        }
     527
     528                        dc.caps[name] = enable
    500529                }
    501530
     
    518547        }
    519548        return nil
     549}
     550
     551func (dc *downstreamConn) setSupportedCap(name, value string) {
     552        prevValue, hasPrev := dc.supportedCaps[name]
     553        changed := !hasPrev || prevValue != value
     554        dc.supportedCaps[name] = value
     555
     556        if !dc.caps["cap-notify"] || !changed {
     557                return
     558        }
     559
     560        replyTo := dc.nick
     561        if !dc.registered {
     562                replyTo = "*"
     563        }
     564
     565        cap := name
     566        if value != "" && dc.capVersion >= 302 {
     567                cap = name + "=" + value
     568        }
     569
     570        dc.SendMessage(&irc.Message{
     571                Prefix:  dc.srv.prefix(),
     572                Command: "CAP",
     573                Params:  []string{replyTo, "NEW", cap},
     574        })
     575}
     576
     577func (dc *downstreamConn) unsetSupportedCap(name string) {
     578        _, hasPrev := dc.supportedCaps[name]
     579        delete(dc.supportedCaps, name)
     580        delete(dc.caps, name)
     581
     582        if !dc.caps["cap-notify"] || !hasPrev {
     583                return
     584        }
     585
     586        replyTo := dc.nick
     587        if !dc.registered {
     588                replyTo = "*"
     589        }
     590
     591        dc.SendMessage(&irc.Message{
     592                Prefix:  dc.srv.prefix(),
     593                Command: "CAP",
     594                Params:  []string{replyTo, "DEL", name},
     595        })
    520596}
    521597
Note: See TracChangeset for help on using the changeset viewer.