~samwhited/xmpp

aeda1b367bd1e6cd5838f5e2d7fd4af44cce9363 — Sam Whited 2 years ago 3862a9a
all: bump to new xmlstream and fix flushing
M bind.go => bind.go +9 -6
@@ 90,11 90,8 @@ func bind(server func(jid.JID, string) (jid.JID, error)) StreamFeature {
			if err = e.EncodeToken(start); err != nil {
				return req, err
			}
			if err = e.EncodeToken(start.End()); err != nil {
				return req, err
			}

			return req, e.Flush()
			err = e.EncodeToken(start.End())
			return req, err
		},
		Parse: func(ctx context.Context, r xml.TokenReader, start *xml.StartElement) (bool, interface{}, error) {
			parsed := struct {


@@ 157,7 154,10 @@ func bind(server func(jid.JID, string) (jid.JID, error)) StreamFeature {
				}

				_, err = resp.WriteXML(session)
				return mask, nil, err
				if err != nil {
					return mask, nil, err
				}
				return mask, nil, session.Flush()
			}

			// Client encodes an IQ requesting resource binding.


@@ 175,6 175,9 @@ func bind(server func(jid.JID, string) (jid.JID, error)) StreamFeature {
			if err != nil {
				return mask, nil, err
			}
			if err = session.Flush(); err != nil {
				return mask, nil, err
			}

			// Client waits on an IQ response.
			//

M bind_test.go => bind_test.go +3 -0
@@ 24,6 24,9 @@ func TestBindList(t *testing.T) {
	if err != nil {
		t.Fatal(err)
	}
	if err = e.Flush(); err != nil {
		t.Fatal(err)
	}
	if !req {
		t.Error("Bind must always be required")
	}

M compress/compression.go => compress/compression.go +5 -8
@@ 40,7 40,7 @@ func New(methods ...Method) xmpp.StreamFeature {
		Necessary: xmpp.Secure | xmpp.Authn,
		List: func(ctx context.Context, e xmlstream.TokenWriter, start xml.StartElement) (req bool, err error) {
			if err = e.EncodeToken(start); err != nil {
				return
				return req, err
			}

			methodStart := xml.StartElement{Name: xml.Name{Local: "method"}}


@@ 53,20 53,17 @@ func New(methods ...Method) xmpp.StreamFeature {
				}

				if err = e.EncodeToken(methodStart); err != nil {
					return
					return req, err
				}
				if err = e.EncodeToken(xml.CharData(m.Name)); err != nil {
					return
					return req, err
				}
				if err = e.EncodeToken(methodStart.End()); err != nil {
					return
					return req, err
				}
			}

			if err = e.EncodeToken(start.End()); err != nil {
				return
			}
			return false, e.Flush()
			return req, e.EncodeToken(start.End())
		},
		Parse: func(ctx context.Context, r xml.TokenReader, start *xml.StartElement) (bool, interface{}, error) {
			listed := struct {

M doc.go => doc.go +6 -2
@@ 76,14 76,18 @@
// To receive XML on the input stream, Session implements the xml.TokenReader
// interface defined in encoding/xml; this allows session to be wrapped with
// xml.NewTokenDecoder.
// To send XML on the output stream, Session has an EncodeToken and Flush
// method like the "mellium.im/xmlstream".TokenWriter interface.
// To send XML on the output stream, Session has an EncodeToken method like the
// "mellium.im/xmlstream".TokenWriter interface.
// The session may also buffer writes and has a Flush method which will write
// any buffered XML to the underlying connection.
// The mellium.im/xmpp/stanza package contains functions and structs that aid in
// the construction of message, presence and IQ elements which have special
// semantics in XMPP and are known as "stanzas".
//
//     // Send initial presence to let the server know we want to receive messages.
//     _, err = xmlstream.Copy(session, stanza.WrapPresence(nil, stanza.AvailablePresence, nil))
//     …
//     err = session.Flush()
//
// To make the common case of polling for incoming XML on the input stream—and
// possibly writing to the output stream in response—easier, Session includes

M features.go => features.go +4 -4
@@ 270,7 270,7 @@ func writeStreamFeatures(ctx context.Context, s *Session, features []StreamFeatu
				Name: feature.Name,
			})
			if err != nil {
				return
				return list, err
			}
			list.cache[feature.Name.Space] = sfData{
				req:     r,


@@ 284,12 284,12 @@ func writeStreamFeatures(ctx context.Context, s *Session, features []StreamFeatu
		}
	}
	if err = s.EncodeToken(start.End()); err != nil {
		return
		return list, err
	}
	if err = s.Flush(); err != nil {
		return
		return list, err
	}
	return
	return list, err
}

func readStreamFeatures(ctx context.Context, s *Session, start xml.StartElement, features []StreamFeature) (*streamFeaturesList, error) {

M go.mod => go.mod +1 -1
@@ 6,5 6,5 @@ require (
	golang.org/x/net v0.0.0-20180216171745-136a25c244d3
	golang.org/x/text v0.0.0-20180208041248-4e4a3210bb54
	mellium.im/sasl v0.1.1
	mellium.im/xmlstream v0.12.1
	mellium.im/xmlstream v0.13.0
)

M go.sum => go.sum +4 -0
@@ 20,3 20,7 @@ mellium.im/xmlstream v0.12.0 h1:0GPPdFc9L8QAA/sV5xw0JqpVrfzWq9MkMaYExqU5ET0=
mellium.im/xmlstream v0.12.0/go.mod h1:EadHCpZVaEeBmMJ276+Rw8hEBZWcKjv/y0njL1k5zCU=
mellium.im/xmlstream v0.12.1 h1:sa2cmyWsV62j/iNN4nAMFrRNRNXil2GivcjgRxpn+n8=
mellium.im/xmlstream v0.12.1/go.mod h1:PDwtcQeiAyF7FrUBRWnVO91nIskvhOFYzOeftngiM7Q=
mellium.im/xmlstream v0.12.3 h1:gm7mpQCUPeyi2WcfxMN2n6PoFNdqkDFvK3pYNITYjtc=
mellium.im/xmlstream v0.12.3/go.mod h1:PDwtcQeiAyF7FrUBRWnVO91nIskvhOFYzOeftngiM7Q=
mellium.im/xmlstream v0.13.0 h1:xKeoziZFGs8NnlxB1oT73yuoCx1rF9+bCyy0ee0mY8E=
mellium.im/xmlstream v0.13.0/go.mod h1:PDwtcQeiAyF7FrUBRWnVO91nIskvhOFYzOeftngiM7Q=

M ibr2/ibr2.go => ibr2/ibr2.go +6 -8
@@ 47,7 47,7 @@ func challengeStart(typ string) xml.StartElement {
func listFunc(challenges ...Challenge) func(context.Context, xmlstream.TokenWriter, xml.StartElement) (bool, error) {
	return func(ctx context.Context, e xmlstream.TokenWriter, start xml.StartElement) (req bool, err error) {
		if err = e.EncodeToken(start); err != nil {
			return
			return req, err
		}

		// List challenges


@@ 60,21 60,19 @@ func listFunc(challenges ...Challenge) func(context.Context, xmlstream.TokenWrit
				Name: xml.Name{Local: "challenge"},
			}
			if err = e.EncodeToken(challengeStart); err != nil {
				return
				return req, err
			}
			if err = e.EncodeToken(xml.CharData(c.Type)); err != nil {
				return
				return req, err
			}
			if err = e.EncodeToken(challengeStart.End()); err != nil {
				return
				return req, err
			}
			seen[c.Type] = struct{}{}
		}

		if err = e.EncodeToken(start.End()); err != nil {
			return
		}
		return req, e.Flush()
		err = e.EncodeToken(start.End())
		return req, err
	}
}


M ibr2/ibr2_test.go => ibr2/ibr2_test.go +5 -1
@@ 9,6 9,7 @@ import (
	"context"
	"encoding/xml"
	"fmt"
	"io"
	"reflect"
	"testing"
)


@@ 27,12 28,15 @@ func TestList(t *testing.T) {
	if err != nil {
		t.Fatalf("List returned error: %v\n", err)
	}
	if err = e.Flush(); err != nil {
		t.Fatalf("Error flushing: %q", err)
	}
	o := struct {
		XMLName   xml.Name `xml:"recover"`
		Challenge []string `xml:"challenge"`
	}{}
	err = d.Decode(&o)
	if err != nil {
	if err != nil && err != io.EOF {
		t.Fatalf("Decoding error: %v\n", err)
	}
	if len(o.Challenge) != 2 {

M ibr2/oob.go => ibr2/oob.go +1 -4
@@ 21,10 21,7 @@ func OOB(data *oob.Data, f func(*oob.Data) error) Challenge {
	return Challenge{
		Type: oob.NS,
		Send: func(ctx context.Context, w xmlstream.TokenWriter) (err error) {
			if err = writeDataTo(w, data); err != nil {
				return err
			}
			return w.Flush()
			return writeDataTo(w, data)
		},
		Receive: func(ctx context.Context, server bool, r xml.TokenReader, start *xml.StartElement) error {
			// The server does not receive a reply for this mechanism.

M mux/mux_test.go => mux/mux_test.go +3 -0
@@ 113,6 113,9 @@ func TestFallback(t *testing.T) {
	if err != nil {
		t.Errorf("Unexpected error: `%v'", err)
	}
	if err = e.Flush(); err != nil {
		t.Errorf("Unexpected error: `%v'", err)
	}

	const expected = `<iq to="juliet@example.com" from="romeo@example.com" type="error"><error type="cancel"><feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"></feature-not-implemented></error></iq>`
	if buf.String() != expected {

M ping/example_test.go => ping/example_test.go +4 -0
@@ 23,6 23,10 @@ func ExampleIQ() {
	if _, err := xmlstream.Copy(e, ping); err != nil {
		log.Fatal(err)
	}
	if err := e.Flush(); err != nil {
		log.Fatal(err)
	}

	// Output:
	// <iq type="get" to="feste@example.net/siJo4eeT">
	//	<ping xmlns="urn:xmpp:ping"></ping>

M session.go => session.go +7 -2
@@ 82,7 82,7 @@ type Session struct {
	}
	out struct {
		internal.StreamInfo
		e xmlstream.TokenWriter
		e tokenWriteFlusher
	}
}



@@ 442,7 442,12 @@ type wrapWriter struct {
func (w wrapWriter) EncodeToken(t xml.Token) error { return w.encode(t) }
func (w wrapWriter) Flush() error                  { return w.flush() }

func stanzaAddID(w xmlstream.TokenWriter) xmlstream.TokenWriter {
type tokenWriteFlusher interface {
	xmlstream.TokenWriter
	xmlstream.Flusher
}

func stanzaAddID(w tokenWriteFlusher) tokenWriteFlusher {
	depth := 0
	return wrapWriter{
		encode: func(t xml.Token) error {

M stanza/example_pingstream_test.go => stanza/example_pingstream_test.go +3 -0
@@ 30,6 30,9 @@ func Example_stream() {
	if _, err := xmlstream.Copy(e, ping); err != nil {
		log.Fatal(err)
	}
	if err := e.Flush(); err != nil {
		log.Fatal(err)
	}
	// Output:
	// <iq type="get" to="feste@example.net/siJo4eeT">
	//	<ping xmlns="urn:xmpp:ping"></ping>

M stanza/stanza_test.go => stanza/stanza_test.go +9 -0
@@ 62,6 62,9 @@ func TestIQ(t *testing.T) {
			if _, err := xmlstream.Copy(e, iq); err != tc.err {
				t.Errorf("Unexpected error: want=`%v', got=`%v'", tc.err, err)
			}
			if err := e.Flush(); err != nil {
				t.Fatalf("Error flushing: %q", err)
			}

			o := b.String()
			jidattr := fmt.Sprintf(`to="%s"`, tc.to)


@@ 109,6 112,9 @@ func TestMessage(t *testing.T) {
			if _, err := xmlstream.Copy(e, message); err != tc.err {
				t.Errorf("Unexpected error: want=`%v', got=`%v'", tc.err, err)
			}
			if err := e.Flush(); err != nil {
				t.Fatalf("Error flushing: %q", err)
			}

			o := b.String()
			jidattr := fmt.Sprintf(`to="%s"`, tc.to)


@@ 157,6 163,9 @@ func TestPresence(t *testing.T) {
			if _, err := xmlstream.Copy(e, presence); err != tc.err {
				t.Errorf("Unexpected error: want=`%v', got=`%v'", tc.err, err)
			}
			if err := e.Flush(); err != nil {
				t.Fatalf("Error flushing: %q", err)
			}

			o := b.String()
			jidattr := fmt.Sprintf(`to="%s"`, tc.to)

M stream/error.go => stream/error.go +1 -5
@@ 225,11 225,7 @@ func (s Error) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
// WriteXML satisfies the xmlstream.WriterTo interface.
// It is like MarshalXML except it writes tokens to w.
func (s Error) WriteXML(w xmlstream.TokenWriter) (n int, err error) {
	n, err = xmlstream.Copy(w, s.TokenReader(nil))
	if err != nil {
		return n, err
	}
	return n, w.Flush()
	return xmlstream.Copy(w, s.TokenReader(nil))
}

// TokenReader returns a new xml.TokenReader that returns an encoding of