~samwhited/xmpp

d57d0a8e9fe7f3514a5e0b0ab9e6612b1f36e1a6 — Sam Whited 4 years ago 3b3b4c4
all: remove Config

Fixes #38
6 files changed, 27 insertions(+), 45 deletions(-)

M component/component.go
D config.go
M internal/stream.go
M internal/stream_test.go
M session.go
M session_test.go
M component/component.go => component/component.go +1 -1
@@ 31,7 31,7 @@ const (
// the component protocol.
func NewClientSession(ctx context.Context, addr *jid.JID, secret []byte, rw io.ReadWriter) (*xmpp.Session, error) {
	addr = addr.Domain()
	return xmpp.NegotiateSession(ctx, nil, addr, addr, rw, Negotiator(addr, secret, false))
	return xmpp.NegotiateSession(ctx, addr, addr, rw, Negotiator(addr, secret, false))
}

// AcceptSession accepts an XMPP session on the given io.ReadWriter using the

D config.go => config.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

import (
	"golang.org/x/text/language"
)

// Config represents the configuration of an XMPP session.
type Config struct {
	// The default language for any streams constructed using this config.
	Lang language.Tag
}

M internal/stream.go => internal/stream.go +15 -7
@@ 10,8 10,6 @@ import (
	"fmt"
	"io"

	"golang.org/x/text/language"

	"mellium.im/xmpp/internal/ns"
	"mellium.im/xmpp/jid"
	"mellium.im/xmpp/stream"


@@ 27,7 25,7 @@ type StreamInfo struct {
	id      string
	version Version
	xmlns   string
	lang    language.Tag
	lang    string
}

// This MUST only return stream errors.


@@ 60,7 58,7 @@ func streamFromStartElement(s xml.StartElement) (StreamInfo, error) {
				return streamData, stream.InvalidNamespace
			}
		case xml.Name{Space: "xml", Local: "lang"}:
			streamData.lang = language.Make(attr.Value)
			streamData.lang = attr.Value
		}
	}
	return streamData, nil


@@ 72,7 70,7 @@ func streamFromStartElement(s xml.StartElement) (StreamInfo, error) {
// because we can guarantee well-formedness of the XML with a print in this case
// and printing is much faster than encoding. Afterwards, clear the
// StreamRestartRequired bit and set the output stream information.
func SendNewStream(rw io.ReadWriter, s2s bool, version Version, lang language.Tag, location, origin, id string) (StreamInfo, error) {
func SendNewStream(rw io.ReadWriter, s2s bool, version Version, lang string, location, origin, id string) (StreamInfo, error) {
	streamData := StreamInfo{}
	switch s2s {
	case true:


@@ 89,12 87,22 @@ func SendNewStream(rw io.ReadWriter, s2s bool, version Version, lang language.Ta
	}

	_, err := fmt.Fprintf(rw,
		XMLHeader+`<stream:stream%sto='%s' from='%s' version='%s' xml:lang='%s' xmlns='%s' xmlns:stream='http://etherx.jabber.org/streams'>`,
		XMLHeader+`<stream:stream%sto='%s' from='%s' version='%s' xml:lang='`,
		id,
		location,
		origin,
		version,
		lang,
	)
	if err != nil {
		return streamData, err
	}

	err = xml.EscapeText(rw, []byte(lang))
	if err != nil {
		return streamData, err
	}

	_, err = fmt.Fprintf(rw, `' xmlns='%s' xmlns:stream='http://etherx.jabber.org/streams'>`,
		streamData.xmlns,
	)
	if err != nil {

M internal/stream_test.go => internal/stream_test.go +2 -4
@@ 11,8 11,6 @@ import (
	"strings"
	"testing"

	"golang.org/x/text/language"

	"mellium.im/xmpp/internal"
)



@@ 35,7 33,7 @@ func TestSendNewS2S(t *testing.T) {
			if tc.id {
				ids = "abc"
			}
			_, err := internal.SendNewStream(&b, tc.s2s, internal.Version{1, 0}, language.Und, "example.net", "test@example.net", ids)
			_, err := internal.SendNewStream(&b, tc.s2s, internal.Version{1, 0}, "und", "example.net", "test@example.net", ids)

			str := b.String()
			if !strings.HasPrefix(str, internal.XMLHeader) {


@@ 84,7 82,7 @@ func TestSendNewS2SReturnsWriteErr(t *testing.T) {
	}{
		nopReader{},
		errWriter{},
	}, true, internal.Version{1, 0}, language.Und, "example.net", "test@example.net", "abc")
	}, true, internal.Version{1, 0}, "und", "example.net", "test@example.net", "abc")
	if err != io.ErrUnexpectedEOF {
		t.Errorf("Expected errWriterErr (%s) but got `%s`", io.ErrUnexpectedEOF, err)
	}

M session.go => session.go +8 -16
@@ 53,8 53,6 @@ const (
// A Session represents an XMPP session comprising an input and an output XML
// stream.
type Session struct {
	config *Config

	conn *Conn

	state SessionState


@@ 101,12 99,11 @@ type Negotiator func(ctx context.Context, session *Session, data interface{}) (m
// Calling NegotiateSession with a nil Negotiator panics.
//
// For more information see the Negotiator type.
func NegotiateSession(ctx context.Context, config *Config, location, origin *jid.JID, rw io.ReadWriter, negotiate Negotiator) (*Session, error) {
func NegotiateSession(ctx context.Context, location, origin *jid.JID, rw io.ReadWriter, negotiate Negotiator) (*Session, error) {
	if negotiate == nil {
		panic("xmpp: attempted to negotiate session with nil negotiator")
	}
	s := &Session{
		config:     config,
		conn:       newConn(rw),
		origin:     origin,
		location:   location,


@@ 145,8 142,8 @@ func NegotiateSession(ctx context.Context, config *Config, location, origin *jid
// If the provided context is canceled before stream negotiation is complete an
// error is returned.
// After stream negotiation if the context is canceled it has no effect.
func NewClientSession(ctx context.Context, origin *jid.JID, config *Config, rw io.ReadWriter, features ...StreamFeature) (*Session, error) {
	return NegotiateSession(ctx, config, origin.Domain(), origin, rw, negotiator(false, features))
func NewClientSession(ctx context.Context, origin *jid.JID, lang string, rw io.ReadWriter, features ...StreamFeature) (*Session, error) {
	return NegotiateSession(ctx, origin.Domain(), origin, rw, negotiator(false, lang, features))
}

// NewServerSession attempts to use an existing connection (or any


@@ 154,8 151,8 @@ func NewClientSession(ctx context.Context, origin *jid.JID, config *Config, rw i
// If the provided context is canceled before stream negotiation is complete an
// error is returned.
// After stream negotiation if the context is canceled it has no effect.
func NewServerSession(ctx context.Context, location, origin *jid.JID, config *Config, rw io.ReadWriter, features ...StreamFeature) (*Session, error) {
	return NegotiateSession(ctx, config, location, origin, rw, negotiator(true, features))
func NewServerSession(ctx context.Context, location, origin *jid.JID, lang string, rw io.ReadWriter, features ...StreamFeature) (*Session, error) {
	return NegotiateSession(ctx, location, origin, rw, negotiator(true, lang, features))
}

// Serve decodes incoming XML tokens from the connection and delegates handling


@@ 216,11 213,6 @@ func (s *Session) encode(v interface{}) error {
	return s.out.e.Encode(v)
}

// Config returns the connections config.
func (s *Session) Config() *Config {
	return s.config
}

// Close ends the output stream (by sending a closing </stream:stream> token).
// It does not close the underlying connection.
// Calling Close() multiple times will only result in one closing


@@ 346,7 338,7 @@ func (s *Session) handleInputStream(handler Handler) error {
	}
}

func negotiator(s2s bool, features []StreamFeature) Negotiator {
func negotiator(s2s bool, lang string, features []StreamFeature) Negotiator {
	return func(ctx context.Context, s *Session, doRestart interface{}) (mask SessionState, rw io.ReadWriter, restartNext interface{}, err error) {
		// Loop for as long as we're not done negotiating features or a stream restart
		// is still required.


@@ 359,14 351,14 @@ func negotiator(s2s bool, features []StreamFeature) Negotiator {
				if err != nil {
					return mask, nil, false, err
				}
				s.out.StreamInfo, err = internal.SendNewStream(s.Conn(), s2s, internal.DefaultVersion, s.config.Lang, s.location.String(), s.origin.String(), internal.RandomID())
				s.out.StreamInfo, err = internal.SendNewStream(s.Conn(), s2s, internal.DefaultVersion, lang, s.location.String(), s.origin.String(), internal.RandomID())
				if err != nil {
					return mask, nil, false, err
				}
			} else {
				// If we're the initiating entity, send a new stream and then wait for
				// one in response.
				s.out.StreamInfo, err = internal.SendNewStream(s.Conn(), s2s, internal.DefaultVersion, s.config.Lang, s.location.String(), s.origin.String(), "")
				s.out.StreamInfo, err = internal.SendNewStream(s.Conn(), s2s, internal.DefaultVersion, lang, s.location.String(), s.origin.String(), "")
				if err != nil {
					return mask, nil, false, err
				}

M session_test.go => session_test.go +1 -2
@@ 24,7 24,6 @@ func errNegotiator(ctx context.Context, session *xmpp.Session, data interface{})
}

type negotiateTestCase struct {
	config     *xmpp.Config
	negotiator xmpp.Negotiator
	err        error
	panics     bool


@@ 57,7 56,7 @@ func TestNegotiator(t *testing.T) {
				Reader: rand.New(rand.NewSource(99)),
				Writer: ioutil.Discard,
			}
			_, err := xmpp.NegotiateSession(context.Background(), tc.config, nil, nil, rw, tc.negotiator)
			_, err := xmpp.NegotiateSession(context.Background(), nil, nil, rw, tc.negotiator)
			if err != tc.err {
				t.Errorf("Unexpected error: want=%v, got=%v", tc.err, err)
			}