~samwhited/xmpp

d4ce9cbb186ddec356931ab5db050f25d5b25ee8 — Sam Whited 5 years ago 8284999
Separate state bits for input/output stream closed
3 files changed, 20 insertions(+), 15 deletions(-)

M starttls.go
M starttls_test.go
M stream.go
M starttls.go => starttls.go +6 -5
@@ 74,7 74,7 @@ func StartTLS(required bool) StreamFeature {
					case tok.Name.Local == "proceed":
						// Skip the </proceed> token.
						if err = conn.in.d.Skip(); err != nil {
							return EndStream, streamerror.InvalidXML
							return mask, streamerror.InvalidXML
						}
						conn.rwc = tls.Client(netconn, conn.config.TLSConfig)
					case tok.Name.Local == "failure":


@@ 82,10 82,11 @@ func StartTLS(required bool) StreamFeature {
						if err = conn.in.d.Skip(); err != nil {
							err = streamerror.InvalidXML
						}
						// Failure is not an "error", it's expected behavior. The server is
						// telling us to end the stream. However, if we encounter bad XML
						// while skipping the </failure> token, return that error.
						return EndStream, err
						// Failure is not an "error", it's expected behavior. Immediately
						// afterwards the server will end the stream. However, if we
						// encounter bad XML while skipping the </failure> token, return
						// that error.
						return mask, err
					default:
						return mask, streamerror.UnsupportedStanzaType
					}

M starttls_test.go => starttls_test.go +1 -1
@@ 182,7 182,7 @@ func TestNegotiateClient(t *testing.T) {
		{[]string{`<proceed xmlns="badns"/>`}, true, Secure | StreamRestartRequired},
		{[]string{`<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>`}, false, Secure | StreamRestartRequired},
		{[]string{`<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'></bad>`}, true, 0},
		{[]string{`<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>`}, false, EndStream},
		{[]string{`<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>`}, false, 0},
		{[]string{`<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'></bad>`}, true, 0},
		{[]string{`</somethingbadhappened>`}, true, 0},
		{[]string{`<notproceedorfailure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>`}, true, 0},

M stream.go => stream.go +13 -9
@@ 21,7 21,7 @@ const streamIDLength = 16

// SessionState represents the current state of an XMPP session. For a
// description of each bit, see the various SessionState typed constants.
type SessionState int8
type SessionState uint8

const (
	// Indicates that the underlying connection has been secured. For instance,


@@ 36,18 36,22 @@ const (
	// sent and received.
	Ready

	// Indicates that the session was initiated by a foreign entity.
	Received

	// Indicates that the output stream has been closed with a stream end tag.
	// When set all write operations will return an error even if the underlying
	// TCP connection is still open.
	OutputStreamClosed

	// Indicates that the input stream has been closed with a stream end tag. When
	// set all read operations will return an error.
	InputStreamClosed

	// Indicates that the session's streams must be restarted. This bit will
	// trigger an automatic restart and will be flipped back to off as soon as the
	// stream is restarted.
	StreamRestartRequired

	// Indicates that the session was initiated by a foreign entity.
	Received

	// Indicates that the stream should be (or has been) terminated. After being
	// flipped, this bit is left off unless the stream is restarted. This does not
	// provide any information about the underlying TLS connection.
	EndStream
)

type stream struct {