Forward all labeled errors and unknown messages to their downstream

This adds support for forwarding all errors and unknown messages labeled
with a specific downstream to that downstream.

Provided that the upstream supports labeled-response, users will now be
able to receive an error only on their client when making a command that
returns an error, as well as receiving any reply unknown to soju.
This commit is contained in:
delthas 2020-05-19 17:33:44 +02:00 committed by Simon Ser
parent f13a9c9d86
commit cdef46d0da
No known key found for this signature in database
GPG key ID: 0FDE7BE0E88F5E48

View file

@ -1182,25 +1182,6 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
Params: []string{dc.nick, dc.marshalEntity(uc.network, nick), dc.marshalEntity(uc.network, channel)},
})
})
case irc.ERR_UNKNOWNCOMMAND, irc.RPL_TRYAGAIN:
var command, reason string
if err := parseMessageParams(msg, nil, &command, &reason); err != nil {
return err
}
if command == "LIST" {
ok := uc.endPendingLISTs(false)
if !ok {
return fmt.Errorf("unexpected response for LIST: %q: no matching pending LIST", msg.Command)
}
uc.forEachDownstreamByID(downstreamID, func(dc *downstreamConn) {
dc.SendMessage(&irc.Message{
Prefix: uc.srv.prefix(),
Command: msg.Command,
Params: []string{dc.nick, "LIST", reason},
})
})
}
case irc.RPL_AWAY:
var nick, reason string
if err := parseMessageParams(msg, nil, &nick, &reason); err != nil {
@ -1271,6 +1252,28 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
Params: []string{dc.nick, upstreamChannel, trailing},
})
})
case irc.ERR_UNKNOWNCOMMAND, irc.RPL_TRYAGAIN:
var command, reason string
if err := parseMessageParams(msg, nil, &command, &reason); err != nil {
return err
}
if command == "LIST" {
ok := uc.endPendingLISTs(false)
if !ok {
return fmt.Errorf("unexpected response for LIST: %q: no matching pending LIST", msg.Command)
}
}
if downstreamID != 0 {
uc.forEachDownstreamByID(downstreamID, func(dc *downstreamConn) {
dc.SendMessage(&irc.Message{
Prefix: uc.srv.prefix(),
Command: msg.Command,
Params: []string{dc.nick, command, reason},
})
})
}
case "TAGMSG":
// TODO: relay to downstream connections that accept message-tags
case "ACK":
@ -1291,6 +1294,24 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
// Ignore
default:
uc.logger.Printf("unhandled message: %v", msg)
if downstreamID != 0 {
uc.forEachDownstreamByID(downstreamID, func(dc *downstreamConn) {
// best effort marshaling for unknown messages, replies and errors:
// most numerics start with the user nick, marshal it if that's the case
// otherwise, conservately keep the params without marshaling
params := msg.Params
if _, err := strconv.Atoi(msg.Command); err == nil { // numeric
if len(msg.Params) > 0 && isOurNick(uc.network, msg.Params[0]) {
params[0] = dc.nick
}
}
dc.SendMessage(&irc.Message{
Prefix: uc.srv.prefix(),
Command: msg.Command,
Params: params,
})
})
}
}
return nil
}