~samwhited/xmpp

6a65f351d38e3a14281a17bc810d3000a8a160a5 — Sam Whited 5 years ago 1d66181
Panic immediately on invalid conntype in lookup
3 files changed, 60 insertions(+), 14 deletions(-)

M internal/lookup_test.go
M lookup.go
A lookup_test.go
M internal/lookup_test.go => internal/lookup_test.go +4 -4
@@ 23,14 23,14 @@ func TestUnmarshalWellKnownXML(t *testing.T) {
</XRD>`)
	var xrd XRD
	if err := xml.Unmarshal(hostMeta, &xrd); err != nil {
		t.Fatal(err)
		t.Error(err)
	}
	switch {
	case len(xrd.Links) != 2:
		t.Fatalf("Expected 2 links in xrd unmarshal output, but found %d", len(xrd.Links))
		t.Errorf("Expected 2 links in xrd unmarshal output, but found %d", len(xrd.Links))
	case xrd.Links[0] != boshLink:
		t.Fatalf("Expected %v, but got %v", boshLink, xrd.Links[0])
		t.Errorf("Expected %v, but got %v", boshLink, xrd.Links[0])
	case xrd.Links[1] != wsLink:
		t.Fatalf("Expected %v, but got %v", wsLink, xrd.Links[1])
		t.Errorf("Expected %v, but got %v", wsLink, xrd.Links[1])
	}
}

M lookup.go => lookup.go +17 -10
@@ 35,22 35,29 @@ var (
)

// LookupWebsocket discovers websocket endpoints that are valid for the given
// address using DNS TXT records and Web Host Metadata as described in XEP-0156:
// Discovering Alternative XMPP Connection Methods. If client is nil, only DNS
// is queried.
// address using DNS TXT records and Web Host Metadata as described in XEP-0156.
// If client is nil, only DNS is queried.
func LookupWebsocket(ctx context.Context, client *http.Client, addr *jid.JID) (urls []string, err error) {
	return lookupEndpoint(ctx, client, addr, "ws")
}

// LookupBOSH discovers BOSH endpoints that are valid for the given address
// using DNS TXT records and Web Host Metadata as described in XEP-0156:
// Discovering Alternative XMPP Connection Methods. If client is nil, only DNS
// is queried.
// using DNS TXT records and Web Host Metadata as described in XEP-0156. If
// client is nil, only DNS is queried.
func LookupBOSH(ctx context.Context, client *http.Client, addr *jid.JID) (urls []string, err error) {
	return lookupEndpoint(ctx, client, addr, "bosh")
}

func validateConnTypeOrPanic(conntype string) {

	if conntype != "ws" && conntype != "bosh" {
		panic("xmpp.lookupEndpoint: Invalid conntype specified")
	}
}

func lookupEndpoint(ctx context.Context, client *http.Client, addr *jid.JID, conntype string) (urls []string, err error) {
	validateConnTypeOrPanic(conntype)

	// TODO: Should these even be fetched concurrently?
	var (
		u  []string


@@ 91,6 98,8 @@ func lookupEndpoint(ctx context.Context, client *http.Client, addr *jid.JID, con
// TODO(ssw): Rely on the OS DNS cache, or cache lookups ourselves?

func lookupDNS(ctx context.Context, name, conntype string) (urls []string, err error) {
	validateConnTypeOrPanic(conntype)

	txts, err := net.LookupTXT(name)
	if err != nil {
		return urls, err


@@ 110,8 119,6 @@ func lookupDNS(ctx context.Context, name, conntype string) (urls []string, err e
			if s = strings.TrimPrefix(txt, boshPrefix); s != txt {
				urls = append(urls, s)
			}
		default:
			panic("xmpp.lookupHostMeta: Invalid conntype specified")
		}
	}



@@ 121,6 128,8 @@ func lookupDNS(ctx context.Context, name, conntype string) (urls []string, err e
// TODO(ssw): Memoize the following functions?

func lookupHostMeta(ctx context.Context, client *http.Client, name, conntype string) (urls []string, err error) {
	validateConnTypeOrPanic(conntype)

	url, err := url.Parse(name)
	if err != nil {
		return urls, err


@@ 142,8 151,6 @@ func lookupHostMeta(ctx context.Context, client *http.Client, name, conntype str
			if link.Rel == boshRel {
				urls = append(urls, link.Href)
			}
		default:
			panic("xmpp.lookupHostMeta: Invalid conntype specified")
		}
	}
	return urls, err

A lookup_test.go => lookup_test.go +39 -0
@@ 0,0 1,39 @@
// 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 (
	"testing"
)

// If an invalid connection type is looked up, we should panic.
func TestLookupEndpointPanicsOnInvalidType(t *testing.T) {
	defer func() {
		if r := recover(); r == nil {
			t.Error("lookupEndpoint should panic if an invalid conntype is specified.")
		}
	}()
	lookupEndpoint(nil, nil, nil, "wssorbashorsomething")
}

// If an invalid connection type is looked up, we should panic.
func TestLookupDNSPanicsOnInvalidType(t *testing.T) {
	defer func() {
		if r := recover(); r == nil {
			t.Error("lookupDNS should panic if an invalid conntype is specified.")
		}
	}()
	lookupDNS(nil, "name", "wssorbashorsomething")
}

// If an invalid connection type is looked up, we should panic.
func TestLookupHostMetaPanicsOnInvalidType(t *testing.T) {
	defer func() {
		if r := recover(); r == nil {
			t.Error("lookupHostMeta should panic if an invalid conntype is specified.")
		}
	}()
	lookupHostMeta(nil, nil, "name", "wssorbashorsomething")
}