Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
xmpp: Find upload component from disco queries
  • Loading branch information
selfhoster1312 committed Mar 1, 2026
commit cfc944dc90751519a9ee47b07df0647e61939f52
31 changes: 31 additions & 0 deletions bridge/xmpp/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package bxmpp

import (
"regexp"
"strconv"

"github.com/matterbridge-org/matterbridge/bridge/config"
"github.com/xmppo/go-xmpp"
Expand Down Expand Up @@ -67,3 +68,33 @@ func (b *Bxmpp) announceUploadedFile(to string, text string, urlDesc string, url
return
}
}

func (b *Bxmpp) extractMaxSizeFromX(disco_x *[]xmpp.DiscoX) int64 {
for _, x := range *disco_x {
for i, field := range x.Field {
if field.Var == "max-file-size" {
if i > 0 {
if x.Field[i-1].Value[0] == "urn:xmpp:http:upload:0" {
return b.extractMaxSizeFromXFieldValue(field.Value[0])
}
}
}
}
}

b.Log.Debug("No HTTP max upload size found")

return 0
}

func (b *Bxmpp) extractMaxSizeFromXFieldValue(value string) int64 {
maxFileSize, err := strconv.ParseInt(value, 10, 64)
if err != nil {
// If the max-file-size can't be parsed, assume it's 0
// and log the error.
b.Log.Warnf("Failed to parse HTTP max upload size: %s", value)
return 0
}

return maxFileSize
}
46 changes: 45 additions & 1 deletion bridge/xmpp/xmpp.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ type Bxmpp struct {

avatarAvailability map[string]bool
avatarMap map[string]string

// The account's HTTP [upload component](https://xmpp.org/extensions/xep-0363.html#disco)
// is discovered in steps commented HTTP_UPLOAD_DISCO.
httpUploadComponent string
// The max attachment size is discovered in the last step of HTTP_UPLOAD_DISCO.
httpUploadMaxSize int64
}

func New(cfg *bridge.Config) bridge.Bridger {
Expand Down Expand Up @@ -318,6 +324,35 @@ func (b *Bxmpp) handleXMPP() error {
b.Log.Debugf("Avatar for %s is now available", v.From)
case xmpp.Presence:
// Do nothing.
case xmpp.DiscoItems:
// Received a list of items, most likely from trying to find the HTTP upload server
// Send a disco info query to all items to find out which is which
Comment thread
selfhoster1312 marked this conversation as resolved.
//
// HTTP_UPLOAD_DISCO step 2
for _, item := range v.Items {
_, err := b.xc.DiscoverInfo(item.Jid)
if err != nil {
b.Log.WithError(err).Warnf("Failed to disco info from %s", item.Jid)
}
}
case xmpp.DiscoResult:
// Received disco info about a specific item, most likely from trying
// to find the HTTP upload server.
for _, identity := range v.Identities {
if identity.Type != "file" || identity.Category != "store" {
// Filter out disco info about everything else.
continue
}

// HTTP_UPLOAD_DISCO step 3
foundSize := b.extractMaxSizeFromX(&v.X)

b.Log.Debugf("Found HTTP file upload component %s (maximum size: %d)", v.From, foundSize)
b.Lock()
b.httpUploadComponent = v.From
b.httpUploadMaxSize = foundSize
b.Unlock()
}
}
}
}
Expand Down Expand Up @@ -377,7 +412,16 @@ func (b *Bxmpp) skipMessage(message xmpp.Chat) bool {
func (b *Bxmpp) setConnected(state bool) {
b.Lock()
b.connected = state
defer b.Unlock()
b.Unlock()

// We are now (re)connected, send a disco query to find out HTTP upload server
// Ignore any errors encountered
//
// HTTP_UPLOAD_DISCO step 1
_, err := b.xc.DiscoverServerItems()
if err != nil {
b.Log.WithError(err).Warn("Failed to discover server items")
}
}

func (b *Bxmpp) Connected() bool {
Expand Down