Add downstreamConn.SendBatch helper

This commit is contained in:
Simon Ser 2021-06-05 12:38:52 +02:00
parent bd41e3bd2b
commit 0081c96ec0

View File

@ -187,6 +187,8 @@ type downstreamConn struct {
supportedCaps map[string]string supportedCaps map[string]string
caps map[string]bool caps map[string]bool
lastBatchRef uint64
saslServer sasl.Server saslServer sasl.Server
} }
@ -379,6 +381,10 @@ func (dc *downstreamConn) SendMessage(msg *irc.Message) {
} }
} }
} }
if !dc.caps["batch"] && msg.Tags["batch"] != "" {
msg = msg.Copy()
delete(msg.Tags, "batch")
}
if msg.Command == "JOIN" && !dc.caps["extended-join"] { if msg.Command == "JOIN" && !dc.caps["extended-join"] {
msg.Params = msg.Params[:1] msg.Params = msg.Params[:1]
} }
@ -389,6 +395,30 @@ func (dc *downstreamConn) SendMessage(msg *irc.Message) {
dc.conn.SendMessage(msg) dc.conn.SendMessage(msg)
} }
func (dc *downstreamConn) SendBatch(typ string, params []string, tags irc.Tags, f func(batchRef irc.TagValue)) {
dc.lastBatchRef++
ref := fmt.Sprintf("%v", dc.lastBatchRef)
if dc.caps["batch"] {
dc.SendMessage(&irc.Message{
Tags: tags,
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: append([]string{"+" + ref, typ}, params...),
})
}
f(irc.TagValue(ref))
if dc.caps["batch"] {
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"-" + ref},
})
}
}
// sendMessageWithID sends an outgoing message with the specified internal ID. // sendMessageWithID sends an outgoing message with the specified internal ID.
func (dc *downstreamConn) sendMessageWithID(msg *irc.Message, id string) { func (dc *downstreamConn) sendMessageWithID(msg *irc.Message, id string) {
dc.SendMessage(msg) dc.SendMessage(msg)
@ -1083,26 +1113,18 @@ func (dc *downstreamConn) welcome() error {
dc.updateSupportedCaps() dc.updateSupportedCaps()
if dc.caps["soju.im/bouncer-networks-notify"] { if dc.caps["soju.im/bouncer-networks-notify"] {
dc.SendMessage(&irc.Message{ dc.SendBatch("soju.im/bouncer-networks", nil, nil, func(batchRef irc.TagValue) {
Prefix: dc.srv.prefix(), dc.user.forEachNetwork(func(network *network) {
Command: "BATCH", idStr := fmt.Sprintf("%v", network.ID)
Params: []string{"+networks", "soju.im/bouncer-networks"}, attrs := getNetworkAttrs(network)
}) dc.SendMessage(&irc.Message{
dc.user.forEachNetwork(func(network *network) { Tags: irc.Tags{"batch": batchRef},
idStr := fmt.Sprintf("%v", network.ID) Prefix: dc.srv.prefix(),
attrs := getNetworkAttrs(network) Command: "BOUNCER",
dc.SendMessage(&irc.Message{ Params: []string{"NETWORK", idStr, attrs.String()},
Tags: irc.Tags{"batch": irc.TagValue("networks")}, })
Prefix: dc.srv.prefix(),
Command: "BOUNCER",
Params: []string{"NETWORK", idStr, attrs.String()},
}) })
}) })
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"-networks"},
})
} }
dc.forEachUpstream(func(uc *upstreamConn) { dc.forEachUpstream(func(uc *upstreamConn) {
@ -1192,39 +1214,24 @@ func (dc *downstreamConn) sendTargetBacklog(net *network, target, msgID string)
return return
} }
batchRef := "history" dc.SendBatch("chathistory", []string{dc.marshalEntity(net, target)}, nil, func(batchRef irc.TagValue) {
if dc.caps["batch"] { for _, msg := range history {
dc.SendMessage(&irc.Message{ if !dc.messageSupportsHistory(msg) {
Prefix: dc.srv.prefix(), continue
Command: "BATCH",
Params: []string{"+" + batchRef, "chathistory", dc.marshalEntity(net, target)},
})
}
for _, msg := range history {
if !dc.messageSupportsHistory(msg) {
continue
}
if ch != nil && ch.Detached {
if net.detachedMessageNeedsRelay(ch, msg) {
dc.relayDetachedMessage(net, msg)
} }
} else {
if dc.caps["batch"] {
msg.Tags["batch"] = irc.TagValue(batchRef)
}
dc.SendMessage(dc.marshalMessage(msg, net))
}
}
if dc.caps["batch"] { if ch != nil && ch.Detached {
dc.SendMessage(&irc.Message{ if net.detachedMessageNeedsRelay(ch, msg) {
Prefix: dc.srv.prefix(), dc.relayDetachedMessage(net, msg)
Command: "BATCH", }
Params: []string{"-" + batchRef}, } else {
}) if dc.caps["batch"] {
} msg.Tags["batch"] = irc.TagValue(batchRef)
}
dc.SendMessage(dc.marshalMessage(msg, net))
}
}
})
} }
func (dc *downstreamConn) relayDetachedMessage(net *network, msg *irc.Message) { func (dc *downstreamConn) relayDetachedMessage(net *network, msg *irc.Message) {
@ -2107,30 +2114,19 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
}} }}
} }
batchRef := "history-targets" dc.SendBatch("draft/chathistory-targets", nil, nil, func(batchRef irc.TagValue) {
dc.SendMessage(&irc.Message{ for _, target := range targets {
Prefix: dc.srv.prefix(), if ch := uc.network.channels.Value(target.Name); ch != nil && ch.Detached {
Command: "BATCH", continue
Params: []string{"+" + batchRef, "draft/chathistory-targets"}, }
})
for _, target := range targets { dc.SendMessage(&irc.Message{
if ch := uc.network.channels.Value(target.Name); ch != nil && ch.Detached { Tags: irc.Tags{"batch": batchRef},
continue Prefix: dc.srv.prefix(),
Command: "CHATHISTORY",
Params: []string{"TARGETS", target.Name, target.LatestMessage.UTC().Format(serverTimeLayout)},
})
} }
dc.SendMessage(&irc.Message{
Tags: irc.Tags{"batch": irc.TagValue(batchRef)},
Prefix: dc.srv.prefix(),
Command: "CHATHISTORY",
Params: []string{"TARGETS", target.Name, target.LatestMessage.UTC().Format(serverTimeLayout)},
})
}
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"-" + batchRef},
}) })
return nil return nil
@ -2140,22 +2136,11 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
return newChatHistoryError(subcommand, target) return newChatHistoryError(subcommand, target)
} }
batchRef := "history" dc.SendBatch("chathistory", []string{target}, nil, func(batchRef irc.TagValue) {
dc.SendMessage(&irc.Message{ for _, msg := range history {
Prefix: dc.srv.prefix(), msg.Tags["batch"] = batchRef
Command: "BATCH", dc.SendMessage(dc.marshalMessage(msg, uc.network))
Params: []string{"+" + batchRef, "chathistory", target}, }
})
for _, msg := range history {
msg.Tags["batch"] = irc.TagValue(batchRef)
dc.SendMessage(dc.marshalMessage(msg, uc.network))
}
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"-" + batchRef},
}) })
case "BOUNCER": case "BOUNCER":
var subcommand string var subcommand string
@ -2165,26 +2150,18 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
switch strings.ToUpper(subcommand) { switch strings.ToUpper(subcommand) {
case "LISTNETWORKS": case "LISTNETWORKS":
dc.SendMessage(&irc.Message{ dc.SendBatch("soju.im/bouncer-networks", nil, nil, func(batchRef irc.TagValue) {
Prefix: dc.srv.prefix(), dc.user.forEachNetwork(func(network *network) {
Command: "BATCH", idStr := fmt.Sprintf("%v", network.ID)
Params: []string{"+networks", "soju.im/bouncer-networks"}, attrs := getNetworkAttrs(network)
}) dc.SendMessage(&irc.Message{
dc.user.forEachNetwork(func(network *network) { Tags: irc.Tags{"batch": batchRef},
idStr := fmt.Sprintf("%v", network.ID) Prefix: dc.srv.prefix(),
attrs := getNetworkAttrs(network) Command: "BOUNCER",
dc.SendMessage(&irc.Message{ Params: []string{"NETWORK", idStr, attrs.String()},
Tags: irc.Tags{"batch": irc.TagValue("networks")}, })
Prefix: dc.srv.prefix(),
Command: "BOUNCER",
Params: []string{"NETWORK", idStr, attrs.String()},
}) })
}) })
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"-networks"},
})
case "ADDNETWORK": case "ADDNETWORK":
var attrsStr string var attrsStr string
if err := parseMessageParams(msg, nil, &attrsStr); err != nil { if err := parseMessageParams(msg, nil, &attrsStr); err != nil {