~samwhited/xmpp

72e8e1bbce05835c7629fe8706b145e27da4c2ed — Sam Whited 4 years ago 466c97d
Don't return a set of features, just allow lookup
3 files changed, 21 insertions(+), 7 deletions(-)

M conn.go
M features.go
M stream.go
M conn.go => conn.go +8 -5
@@ 34,7 34,7 @@ type Conn struct {
	origin *jid.JID

	// The stream feature namespaces advertised for the current streams.
	features map[string]struct{}
	features map[string]interface{}
	flock    sync.Mutex

	// The negotiated features (by namespace) for the current session.


@@ 52,13 52,16 @@ type Conn struct {
	}
}

// Features returns a set of the currently available stream features namespaces
// (including namespaces for features that have already been negotiated).
func (c *Conn) Features() map[string]struct{} {
// Feature checks if a feature with the given namespace was advertised
// by the server for the current stream. If it was data will be the canonical
// representation of the feature as returned by the features Parse function.
func (c *Conn) Feature(namespace string) (data interface{}, ok bool) {
	c.flock.Lock()
	defer c.flock.Unlock()

	return c.features
	// TODO: Make the features struct actually store the parsed representation.
	data, ok = c.features[namespace]
	return
}

// NewConn attempts to use an existing connection (or any io.ReadWriteCloser) to

M features.go => features.go +12 -1
@@ 260,17 260,28 @@ parsefeatures:
			// If the token is a new feature, see if it's one we handle. If so, parse
			// it. Increment the total features count regardless.
			sf.total++
			conn.features[tok.Name.Space] = struct{}{}

			// Always add the feature to the list of features, even if we don't
			// support it.
			conn.features[tok.Name.Space] = nil

			if feature, ok := conn.config.Features[tok.Name]; ok && (conn.state&feature.Necessary) == feature.Necessary && (conn.state&feature.Prohibited) == 0 {
				req, data, err := feature.Parse(ctx, conn.in.d, &tok)
				if err != nil {
					return nil, err
				}

				// TODO: Since we're storing the features data on conn.features we can
				// probably remove it from this temporary cache.
				sf.cache[tok.Name.Space] = sfData{
					req:     req,
					data:    data,
					feature: feature,
				}

				// Since we do support the feature, add it to the connections list along
				// with any data returned from Parse.
				conn.features[tok.Name.Space] = data
				if req {
					sf.req = true
				}

M stream.go => stream.go +1 -1
@@ 215,7 215,7 @@ func (c *Conn) negotiateStreams(ctx context.Context, rwc io.ReadWriteCloser) (er
	// is still required.
	for done := false; !done || rwc != nil; {
		if rwc != nil {
			c.features = make(map[string]struct{})
			c.features = make(map[string]interface{})
			c.negotiated = make(map[string]struct{})
			c.rwc = rwc
			c.in.d = xml.NewDecoder(c.rwc)