// Copyright 2014 The Mellium Contributors. // Use of this source code is governed by the BSD-2-clause // license that can be found in the LICENSE-mellium file. // Original taken from mellium.im/xmpp/jid (BSD-2-Clause) and adjusted for my needs. // Copyright Martin Dosch package main import ( "fmt" "strings" "unicode/utf8" ) // MarshalJID checks that JIDs include localpart and serverpart // and return it marshaled. Shamelessly stolen from // mellium.im/xmpp/jid func MarshalJID(input string) (string, error) { var ( err error localpart string domainpart string resourcepart string ) s := input // Remove any portion from the first '/' character to the end of the // string (if there is a '/' character present). sep := strings.Index(s, "/") if sep == -1 { resourcepart = "" } else { // If the resource part exists, make sure it isn't empty. if sep == len(s)-1 { return input, fmt.Errorf("invalid JID %s: the resourcepart must be larger than 0 bytes", input) } resourcepart = s[sep+1:] s = s[:sep] } // Remove any portion from the beginning of the string to the first // '@' character (if there is an '@' character present). sep = strings.Index(s, "@") switch { case sep == -1: // There is no @ sign, and therefore no localpart. domainpart = s case sep == 0: // The JID starts with an @ sign (invalid empty localpart) err = fmt.Errorf("Invalid JID: %s", input) return input, err default: domainpart = s[sep+1:] localpart = s[:sep] } // We'll throw out any trailing dots on domainparts, since they're ignored: // // If the domainpart includes a final character considered to be a label // separator (dot) by [RFC1034], this character MUST be stripped from // the domainpart before the JID of which it is a part is used for the // purpose of routing an XML stanza, comparing against another JID, or // constructing an XMPP URI or IRI [RFC5122]. In particular, such a // character MUST be stripped before any other canonicalization steps // are taken. domainpart = strings.TrimSuffix(domainpart, ".") var jid string if !utf8.ValidString(localpart) || !utf8.ValidString(domainpart) || !utf8.ValidString(resourcepart) { return input, fmt.Errorf("invalid JID: %s", input) } if domainpart == "" { return input, fmt.Errorf("invalid JID: %s", input) } if localpart == "" { jid = domainpart } else { jid = localpart + "@" + domainpart } if resourcepart == "" { return jid, err } return jid + "/" + resourcepart, err }