~samwhited/xmpp

c0106c5ad49d98d6bf96716e403bb39062264952 — Sam Whited 5 years ago b864a86
ns: Move namespaces to own package

This lets us prevent import loops (eg. if we want to access namespace
constants from a sibling tree under xmpp/)
9 files changed, 46 insertions(+), 35 deletions(-)

M bind.go
M features.go
D ns.go
A ns/ns.go
M sasl.go
M sasl_test.go
M starttls.go
M starttls_test.go
M stream.go
M bind.go => bind.go +3 -2
@@ 12,6 12,7 @@ import (

	"mellium.im/xmpp/internal"
	"mellium.im/xmpp/jid"
	"mellium.im/xmpp/ns"
	"mellium.im/xmpp/streamerror"
)



@@ 23,7 24,7 @@ const (
// BindResource is a stream feature that can be used for binding a resource.
func BindResource() StreamFeature {
	return StreamFeature{
		Name:       xml.Name{Space: NSBind, Local: "bind"},
		Name:       xml.Name{Space: ns.Bind, Local: "bind"},
		Necessary:  Authn,
		Prohibited: Bind | Ready,
		List: func(ctx context.Context, w io.Writer) (bool, error) {


@@ 66,7 67,7 @@ func BindResource() StreamFeature {
					} `xml:"urn:ietf:params:xml:ns:xmpp-bind bind"`
				}{}
				switch start.Name {
				case xml.Name{Space: NSClient, Local: "iq"}:
				case xml.Name{Space: ns.Client, Local: "iq"}:
					if err = conn.in.d.DecodeElement(&resp, &start); err != nil {
						return mask, err
					}

M features.go => features.go +3 -2
@@ 10,6 10,7 @@ import (
	"fmt"
	"io"

	"mellium.im/xmpp/ns"
	"mellium.im/xmpp/streamerror"
)



@@ 147,7 148,7 @@ func readStreamFeatures(ctx context.Context, conn *Conn, start xml.StartElement)
	switch {
	case start.Name.Local != "features":
		return nil, streamerror.InvalidXML
	case start.Name.Space != NSStream:
	case start.Name.Space != ns.Stream:
		return nil, streamerror.BadNamespacePrefix
	}



@@ 186,7 187,7 @@ parsefeatures:
				return nil, err
			}
		case xml.EndElement:
			if tok.Name.Local == "features" && tok.Name.Space == NSStream {
			if tok.Name.Local == "features" && tok.Name.Space == ns.Stream {
				// We've reached the end of the features list!
				return sf, nil
			}

D ns.go => ns.go +0 -15
@@ 1,15 0,0 @@
// Copyright 2016 Sam Whited.
// Use of this source code is governed by the BSD 2-clause license that can be
// found in the LICENSE file.

package xmpp

const (
	NSBind     = "urn:ietf:params:xml:ns:xmpp-bind"
	NSClient   = "jabber:client"
	NSSASL     = "urn:ietf:params:xml:ns:xmpp-sasl"
	NSServer   = "jabber:server"
	NSStartTLS = "urn:ietf:params:xml:ns:xmpp-tls"
	NSStream   = "http://etherx.jabber.org/streams"
	NSXML      = "http://www.w3.org/XML/1998/namespace"
)

A ns/ns.go => ns/ns.go +18 -0
@@ 0,0 1,18 @@
// Copyright 2016 Sam Whited.
// Use of this source code is governed by the BSD 2-clause license that can be
// found in the LICENSE file.

// Package ns provides namespace constants that are used by the xmpp package and
// other internal packages.
package ns // import "mellium.im/xmpp/ns"

const (
	Bind     = "urn:ietf:params:xml:ns:xmpp-bind"
	Client   = "jabber:client"
	SASL     = "urn:ietf:params:xml:ns:xmpp-sasl"
	Server   = "jabber:server"
	Stanza   = "urn:ietf:params:xml:ns:xmpp-stanzas"
	StartTLS = "urn:ietf:params:xml:ns:xmpp-tls"
	Stream   = "http://etherx.jabber.org/streams"
	XML      = "http://www.w3.org/XML/1998/namespace"
)

M sasl.go => sasl.go +4 -3
@@ 13,6 13,7 @@ import (

	"mellium.im/sasl"
	"mellium.im/xmpp/internal/saslerr"
	"mellium.im/xmpp/ns"
	"mellium.im/xmpp/streamerror"
)



@@ 36,7 37,7 @@ func SASL(mechanisms ...*sasl.Mechanism) StreamFeature {
		panic("xmpp: Must specify at least 1 SASL mechanism")
	}
	return StreamFeature{
		Name: xml.Name{Space: NSSASL, Local: "mechanisms"},
		Name: xml.Name{Space: ns.SASL, Local: "mechanisms"},
		// Necessary:  Secure,
		Prohibited: Authn,
		List: func(ctx context.Context, conn io.Writer) (req bool, err error) {


@@ 140,7 141,7 @@ func SASL(mechanisms ...*sasl.Mechanism) StreamFeature {

func decodeSASLChallenge(d *xml.Decoder, start xml.StartElement) (challenge []byte, success bool, err error) {
	switch start.Name {
	case xml.Name{Space: NSSASL, Local: "challenge"}, xml.Name{Space: NSSASL, Local: "success"}:
	case xml.Name{Space: ns.SASL, Local: "challenge"}, xml.Name{Space: ns.SASL, Local: "success"}:
		challenge := struct {
			Data []byte `xml:",chardata"`
		}{}


@@ 148,7 149,7 @@ func decodeSASLChallenge(d *xml.Decoder, start xml.StartElement) (challenge []by
			return nil, false, err
		}
		return challenge.Data, start.Name.Local == "success", nil
	case xml.Name{Space: NSSASL, Local: "failure"}:
	case xml.Name{Space: ns.SASL, Local: "failure"}:
		fail := saslerr.Failure{}
		if err = d.DecodeElement(&fail, &start); err != nil {
			return nil, false, err

M sasl_test.go => sasl_test.go +2 -1
@@ 12,6 12,7 @@ import (
	"testing"

	"mellium.im/sasl"
	"mellium.im/xmpp/ns"
)

func TestSASLPanicsNoMechanisms(t *testing.T) {


@@ 49,7 50,7 @@ func TestSASLList(t *testing.T) {
		t.Fatal(err)
	}
	se := tok.(xml.StartElement)
	if se.Name.Local != "mechanisms" || se.Name.Space != NSSASL {
	if se.Name.Local != "mechanisms" || se.Name.Space != ns.SASL {
		t.Errorf("Unexpected name for mechanisms start element: %+v", se.Name)
	}
	// Skip two mechanisms

M starttls.go => starttls.go +4 -3
@@ 13,6 13,7 @@ import (
	"io"
	"net"

	"mellium.im/xmpp/ns"
	"mellium.im/xmpp/streamerror"
)



@@ 27,7 28,7 @@ var (
// implement net.Conn) and the connection config must have a TLSConfig.
func StartTLS(required bool) StreamFeature {
	return StreamFeature{
		Name:       xml.Name{Local: "starttls", Space: NSStartTLS},
		Name:       xml.Name{Local: "starttls", Space: ns.StartTLS},
		Prohibited: Secure,
		List: func(ctx context.Context, conn io.Writer) (req bool, err error) {
			if required {


@@ 45,7 46,7 @@ func StartTLS(required bool) StreamFeature {
				}
			}{}
			err := d.DecodeElement(&parsed, start)
			return parsed.Required.XMLName.Local == "required" && parsed.Required.XMLName.Space == NSStartTLS, nil, err
			return parsed.Required.XMLName.Local == "required" && parsed.Required.XMLName.Space == ns.StartTLS, nil, err
		},
		Negotiate: func(ctx context.Context, conn *Conn, data interface{}) (mask SessionState, err error) {
			netconn, ok := conn.rwc.(net.Conn)


@@ 68,7 69,7 @@ func StartTLS(required bool) StreamFeature {
				switch tok := t.(type) {
				case xml.StartElement:
					switch {
					case tok.Name.Space != NSStartTLS:
					case tok.Name.Space != ns.StartTLS:
						return mask, streamerror.UnsupportedStanzaType
					case tok.Name.Local == "proceed":
						// Skip the </proceed> token.

M starttls_test.go => starttls_test.go +7 -5
@@ 15,6 15,8 @@ import (
	"strings"
	"testing"
	"time"

	"mellium.im/xmpp/ns"
)

// There is no room for variation on the starttls feature negotiation, so step


@@ 38,8 40,8 @@ func TestStartTLSList(t *testing.T) {
		}
		se := tok.(xml.StartElement)
		switch {
		case se.Name != xml.Name{Space: NSStartTLS, Local: "starttls"}:
			t.Errorf("Expected starttls to start with %+v token but got %+v", NSStartTLS, se.Name)
		case se.Name != xml.Name{Space: ns.StartTLS, Local: "starttls"}:
			t.Errorf("Expected starttls to start with %+v token but got %+v", ns.StartTLS, se.Name)
		case len(se.Attr) != 1:
			t.Errorf("Expected starttls start element to have 1 attribute (xmlns), but got %+v", se.Attr)
		}


@@ 50,7 52,7 @@ func TestStartTLSList(t *testing.T) {
			}
			se := tok.(xml.StartElement)
			switch {
			case se.Name != xml.Name{Space: NSStartTLS, Local: "required"}:
			case se.Name != xml.Name{Space: ns.StartTLS, Local: "required"}:
				t.Errorf("Expected required start element but got %+v", se)
			case len(se.Attr) > 0:
				t.Errorf("Expected starttls required to have no attributes but got %d", len(se.Attr))


@@ 58,7 60,7 @@ func TestStartTLSList(t *testing.T) {
			tok, err = d.Token()
			ee := tok.(xml.EndElement)
			switch {
			case se.Name != xml.Name{Space: NSStartTLS, Local: "required"}:
			case se.Name != xml.Name{Space: ns.StartTLS, Local: "required"}:
				t.Errorf("Expected required end element but got %+v", ee)
			}
		}


@@ 68,7 70,7 @@ func TestStartTLSList(t *testing.T) {
		}
		ee := tok.(xml.EndElement)
		switch {
		case se.Name != xml.Name{Space: NSStartTLS, Local: "starttls"}:
		case se.Name != xml.Name{Space: ns.StartTLS, Local: "starttls"}:
			t.Errorf("Expected starttls end element but got %+v", ee)
		}
	}

M stream.go => stream.go +5 -4
@@ 13,6 13,7 @@ import (
	"golang.org/x/text/language"
	"mellium.im/xmpp/internal"
	"mellium.im/xmpp/jid"
	"mellium.im/xmpp/ns"
	"mellium.im/xmpp/streamerror"
)



@@ 86,7 87,7 @@ func streamFromStartElement(s xml.StartElement) (stream, error) {
			}
			stream.xmlns = attr.Value
		case xml.Name{Space: "xmlns", Local: "stream"}:
			if attr.Value != NSStream {
			if attr.Value != ns.Stream {
				return stream, streamerror.InvalidNamespace
			}
		case xml.Name{Space: "xml", Local: "lang"}:


@@ 111,9 112,9 @@ func sendNewStream(w io.Writer, cfg *Config, id string) error {
	}
	switch cfg.S2S {
	case true:
		stream.xmlns = NSServer
		stream.xmlns = ns.Server
	case false:
		stream.xmlns = NSClient
		stream.xmlns = ns.Client
	}

	stream.id = id


@@ 174,7 175,7 @@ func expectNewStream(ctx context.Context, r io.Reader) error {
			switch {
			case tok.Name.Local != "stream":
				return streamerror.BadFormat
			case tok.Name.Space != NSStream:
			case tok.Name.Space != ns.Stream:
				return streamerror.InvalidNamespace
			}