Changeset 108 in code for trunk


Ignore:
Timestamp:
Mar 16, 2020, 2:05:24 PM (5 years ago)
Author:
contact
Message:

Add CAP support for downstream connections

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/downstream.go

    r107 r108  
    66        "io"
    77        "net"
     8        "strconv"
    89        "strings"
    910        "sync"
     
    7273        network     *network // can be nil
    7374
     75        negociatingCaps bool
     76        capVersion      int
     77        caps            map[string]bool
     78
    7479        lock        sync.Mutex
    7580        ourMessages map[*irc.Message]struct{}
     
    8590                ringMessages: make(chan ringMessage),
    8691                closed:       make(chan struct{}),
     92                caps:         make(map[string]bool),
    8793                ourMessages:  make(map[*irc.Message]struct{}),
    8894        }
     
    329335                        return err
    330336                }
     337        case "CAP":
     338                var subCmd string
     339                if err := parseMessageParams(msg, &subCmd); err != nil {
     340                        return err
     341                }
     342                subCmd = strings.ToUpper(subCmd)
     343                if err := dc.handleCapCommand(subCmd, msg.Params[1:]); err != nil {
     344                        return err
     345                }
    331346        default:
    332347                dc.logger.Printf("unhandled message: %v", msg)
    333348                return newUnknownCommandError(msg.Command)
    334349        }
    335         if dc.rawUsername != "" && dc.nick != "" {
     350        if dc.rawUsername != "" && dc.nick != "" && !dc.negociatingCaps {
    336351                return dc.register()
     352        }
     353        return nil
     354}
     355
     356func (dc *downstreamConn) handleCapCommand(cmd string, args []string) error {
     357        replyTo := dc.nick
     358        if !dc.registered {
     359                replyTo = "*"
     360        }
     361
     362        switch cmd {
     363        case "LS":
     364                if len(args) > 0 {
     365                        var err error
     366                        if dc.capVersion, err = strconv.Atoi(args[0]); err != nil {
     367                                return err
     368                        }
     369                }
     370
     371                var caps []string
     372                /*if dc.capVersion >= 302 {
     373                        caps = append(caps, "sasl=PLAIN")
     374                } else {
     375                        caps = append(caps, "sasl")
     376                }*/
     377
     378                // TODO: multi-line replies
     379                dc.SendMessage(&irc.Message{
     380                        Prefix:  dc.srv.prefix(),
     381                        Command: "CAP",
     382                        Params:  []string{replyTo, "LS", strings.Join(caps, " ")},
     383                })
     384
     385                if !dc.registered {
     386                        dc.negociatingCaps = true
     387                }
     388        case "LIST":
     389                var caps []string
     390                for name := range dc.caps {
     391                        caps = append(caps, name)
     392                }
     393
     394                // TODO: multi-line replies
     395                dc.SendMessage(&irc.Message{
     396                        Prefix:  dc.srv.prefix(),
     397                        Command: "CAP",
     398                        Params:  []string{replyTo, "LIST", strings.Join(caps, " ")},
     399                })
     400        case "REQ":
     401                if len(args) == 0 {
     402                        return ircError{&irc.Message{
     403                                Command: err_invalidcapcmd,
     404                                Params:  []string{replyTo, cmd, "Missing argument in CAP REQ command"},
     405                        }}
     406                }
     407
     408                caps := strings.Fields(args[0])
     409                ack := true
     410                for _, name := range caps {
     411                        name = strings.ToLower(name)
     412                        enable := !strings.HasPrefix(name, "-")
     413                        if !enable {
     414                                name = strings.TrimPrefix(name, "-")
     415                        }
     416
     417                        enabled := dc.caps[name]
     418                        if enable == enabled {
     419                                continue
     420                        }
     421
     422                        switch name {
     423                        /*case "sasl":
     424                                dc.caps[name] = enable*/
     425                        default:
     426                                ack = false
     427                        }
     428                }
     429
     430                reply := "NAK"
     431                if ack {
     432                        reply = "ACK"
     433                }
     434                dc.SendMessage(&irc.Message{
     435                        Prefix:  dc.srv.prefix(),
     436                        Command: "CAP",
     437                        Params:  []string{replyTo, reply, args[0]},
     438                })
     439        case "END":
     440                dc.negociatingCaps = false
     441        default:
     442                return ircError{&irc.Message{
     443                        Command: err_invalidcapcmd,
     444                        Params:  []string{replyTo, cmd, "Unknown CAP command"},
     445                }}
    337446        }
    338447        return nil
  • trunk/irc.go

    r98 r108  
    99
    1010const (
    11         rpl_statsping    = "246"
    12         rpl_localusers   = "265"
    13         rpl_globalusers  = "266"
    14         rpl_topicwhotime = "333"
    15         rpl_loggedin     = "900"
    16         rpl_loggedout    = "901"
    17         err_nicklocked   = "902"
    18         rpl_saslsuccess  = "903"
    19         err_saslfail     = "904"
    20         err_sasltoolong  = "905"
    21         err_saslaborted  = "906"
    22         err_saslalready  = "907"
    23         rpl_saslmechs    = "908"
     11        rpl_statsping     = "246"
     12        rpl_localusers    = "265"
     13        rpl_globalusers   = "266"
     14        rpl_topicwhotime  = "333"
     15        err_invalidcapcmd = "410"
     16        rpl_loggedin      = "900"
     17        rpl_loggedout     = "901"
     18        err_nicklocked    = "902"
     19        rpl_saslsuccess   = "903"
     20        err_saslfail      = "904"
     21        err_sasltoolong   = "905"
     22        err_saslaborted   = "906"
     23        err_saslalready   = "907"
     24        rpl_saslmechs     = "908"
    2425)
    2526
Note: See TracChangeset for help on using the changeset viewer.