~samwhited/xmpp

1d661818a23d7e91a1be61d52107073376b38be0 — Sam Whited 5 years ago b858a10
Remove JRD host-meta lookup.

I misread the spec, the XML version is required and the JSON version is
optional, you don't get to pick between the two. This will be clarified
in version 1.1.2 of XEP-0156: https://github.com/xsf/xeps/pull/198
3 files changed, 11 insertions(+), 114 deletions(-)

M internal/lookup.go
M internal/lookup_test.go
M lookup.go
M internal/lookup.go => internal/lookup.go +4 -20
@@ 8,7 8,7 @@ import (
	"encoding/xml"
)

// Represents a document of the form:
// Represents an Extensible Resource Descriptor (XRD) document of the form:
//
// <?xml version='1.0' encoding=utf-9'?>
// <XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>


@@ 20,29 20,13 @@ import (
//   …
// </XRD>
//
// or
//
// {
//   …
//   "links": [
//     …
//     {
//       "rel": "urn:xmpp:alt-connections:xbosh",
//       "href": "https://web.example.com:5280/bosh"
//     },
//     {
//       "rel": "urn:xmpp:alt-connections:websocket",
//       "href": "wss://web.example.com:443/ws"
//     },
//     …
//   ]
// }
// as defined by RFC 6415 and OASIS.XRD-1.0.
type XRD struct {
	XMLName xml.Name `xml:"http://docs.oasis-open.org/ns/xri/xrd-1.0 XRD"`
	Links   []Link   `xml:"Link"`
}

type Link struct {
	Rel  string `xml:"rel,attr",json:"rel"`
	Href string `xml:"href,attr",json:"href"`
	Rel  string `xml:"rel,attr"`
	Href string `xml:"href,attr"`
}

M internal/lookup_test.go => internal/lookup_test.go +0 -28
@@ 5,7 5,6 @@
package internal

import (
	"encoding/json"
	"encoding/xml"
	"testing"
)


@@ 35,30 34,3 @@ func TestUnmarshalWellKnownXML(t *testing.T) {
		t.Fatalf("Expected %v, but got %v", wsLink, xrd.Links[1])
	}
}

func TestUnmarshalWellKnownJSON(t *testing.T) {
	hostMeta := []byte(`{
  "links": [
    {
      "rel": "urn:xmpp:alt-connections:xbosh",
      "href": "https://web.example.com:5280/bosh"
    },
    {
      "rel": "urn:xmpp:alt-connections:websocket",
      "href": "wss://web.example.com:443/ws"
    }
  ]
}`)
	var xrd XRD
	if err := json.Unmarshal(hostMeta, &xrd); err != nil {
		t.Fatal(err)
	}
	switch {
	case len(xrd.Links) != 2:
		t.Fatalf("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])
	case xrd.Links[1] != wsLink:
		t.Fatalf("Expected %v, but got %v", wsLink, xrd.Links[1])
	}
}

M lookup.go => lookup.go +7 -66
@@ 5,7 5,6 @@
package xmpp

import (
	"encoding/json"
	"encoding/xml"
	"net"
	"net/http"


@@ 20,17 19,12 @@ import (
	"mellium.im/xmpp/jid"
)

// BUG(ssw): RFC6415 says that JSON may be returned by the host-meta file if we
//           set an Accepts header of "application/json"; we should try this
//           too in case they don't have a host-meta.json file.

const (
	wsPrefix     = "_xmpp-client-websocket="
	boshPrefix   = "_xmpp-client-xbosh="
	wsRel        = "urn:xmpp:alt-connections:websocket"
	boshRel      = "urn:xmpp:alt-connections:xbosh"
	hostMetaXML  = "/.well-known/host-meta"
	hostMetaJSON = "/.well-known/host-meta.json"
	wsPrefix    = "_xmpp-client-websocket="
	boshPrefix  = "_xmpp-client-xbosh="
	wsRel       = "urn:xmpp:alt-connections:websocket"
	boshRel     = "urn:xmpp:alt-connections:xbosh"
	hostMetaXML = "/.well-known/host-meta"
)

var (


@@ 133,42 127,8 @@ func lookupHostMeta(ctx context.Context, client *http.Client, name, conntype str
	}
	url.Path = ""

	ctx, cancel := context.WithCancel(ctx)

	var (
		xrd *internal.XRD
		wg  sync.WaitGroup
	)

	// Race! If one of the two goroutines does not error, we want that one. If
	// both error, or both are error free, we don't care.
	wg.Add(2)
	go func() {
		defer wg.Done()
		defer cancel()
		x, e := getHostMetaXML(ctx, client, url.String())
		if e != nil {
			err = e
			return
		}
		xrd, err = &x, e
	}()
	go func() {
		defer wg.Done()
		defer cancel()
		x, e := getHostMetaJSON(ctx, client, url.String())
		if e != nil {
			err = e
			return
		}
		xrd, err = &x, e
	}()

	// TODO: Don't use a waitgroup; instead return when either goroutine returns
	// successfully.
	wg.Wait()

	if xrd == nil {
	xrd, err := getHostMetaXML(ctx, client, url.String())
	if err != nil {
		return urls, err
	}



@@ 212,22 172,3 @@ func getHostMetaXML(
		}
	}
}

func getHostMetaJSON(
	ctx context.Context, client *http.Client, name string) (xrd internal.XRD, err error) {
	resp, err := ctxhttp.Get(ctx, client, path.Join(name, hostMetaJSON))
	if err != nil {
		return xrd, err
	}

	if _, ok := <-ctx.Done(); ok {
		return xrd, ctx.Err()
	}

	d := json.NewDecoder(resp.Body)

	// TODO: We should probably tokenize this and have the ability to cancel
	// anywhere in between.
	err = d.Decode(&xrd)
	return xrd, err
}