File: jid.go

package info (click to toggle)
go-sendxmpp 0.15.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 332 kB
  • sloc: makefile: 11
file content (93 lines) | stat: -rw-r--r-- 2,551 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// 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
}