52 lines
1.2 KiB
Go
52 lines
1.2 KiB
Go
|
package disco
|
||
|
|
||
|
import (
|
||
|
"net/url"
|
||
|
)
|
||
|
|
||
|
type Host struct {
|
||
|
discoURL *url.URL
|
||
|
services map[string]interface{}
|
||
|
}
|
||
|
|
||
|
// ServiceURL returns the URL associated with the given service identifier,
|
||
|
// which should be of the form "servicename.vN".
|
||
|
//
|
||
|
// A non-nil result is always an absolute URL with a scheme of either https
|
||
|
// or http.
|
||
|
//
|
||
|
// If the requested service is not supported by the host, this method returns
|
||
|
// a nil URL.
|
||
|
//
|
||
|
// If the discovery document entry for the given service is invalid (not a URL),
|
||
|
// it is treated as absent, also returning a nil URL.
|
||
|
func (h Host) ServiceURL(id string) *url.URL {
|
||
|
if h.services == nil {
|
||
|
return nil // no services supported for an empty Host
|
||
|
}
|
||
|
|
||
|
urlStr, ok := h.services[id].(string)
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
ret, err := url.Parse(urlStr)
|
||
|
if err != nil {
|
||
|
return nil
|
||
|
}
|
||
|
if !ret.IsAbs() {
|
||
|
ret = h.discoURL.ResolveReference(ret) // make absolute using our discovery doc URL
|
||
|
}
|
||
|
if ret.Scheme != "https" && ret.Scheme != "http" {
|
||
|
return nil
|
||
|
}
|
||
|
if ret.User != nil {
|
||
|
// embedded username/password information is not permitted; credentials
|
||
|
// are handled out of band.
|
||
|
return nil
|
||
|
}
|
||
|
ret.Fragment = "" // fragment part is irrelevant, since we're not a browser
|
||
|
|
||
|
return h.discoURL.ResolveReference(ret)
|
||
|
}
|