profilefed/webfinger/lookup.go

64 lines
1.4 KiB
Go

package webfinger
import (
"encoding/json"
"errors"
"net/http"
"net/url"
"strings"
)
// Lookup looks up the given resource string at the given server.
// The server parameter shouldn't contain a URL scheme.
func Lookup(resource, server string) (desc *Descriptor, err error) {
u := url.URL{
Scheme: "http",
Host: server,
Path: "/.well-known/webfinger",
RawQuery: "resource=" + url.QueryEscape(resource),
}
res, err := http.Get(u.String())
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, errors.New(res.Status)
}
desc = &Descriptor{}
err = json.NewDecoder(res.Body).Decode(desc)
if err != nil {
return nil, err
}
return desc, nil
}
// LookupAcct looks up the given account ID. It uses the
// server in the ID to do the lookup. For example, user@example.com
// would use example.com as the server.
func LookupAcct(id string) (*Descriptor, error) {
_, server, ok := strings.Cut(id, "@")
if !ok {
return nil, errors.New("invalid acct id")
}
if !strings.HasPrefix(id, "acct:") {
id = "acct:" + id
}
return Lookup(id, server)
}
// LookupURL looks up the given resource URL. It uses the
// URL host to do the lookup. For example, http://example.com/1
// would use example.com as the server.
func LookupURL(resource string) (*Descriptor, error) {
u, err := url.ParseRequestURI(resource)
if err != nil {
return nil, err
}
return Lookup(resource, u.Host)
}