caldav: add DiscoverContextURL

This commit is contained in:
Simon Ser
2023-12-27 23:16:49 +01:00
parent 174622c1eb
commit 7e076258d6
3 changed files with 44 additions and 32 deletions

View File

@@ -7,6 +7,7 @@ import (
"fmt"
"io"
"mime"
"net"
"net/http"
"net/url"
"path"
@@ -14,6 +15,42 @@ import (
"unicode"
)
// DiscoverContextURL performs a DNS-based CardDAV/CalDAV service discovery as
// described in RFC 6352 section 11. It returns the URL to the CardDAV server.
func DiscoverContextURL(ctx context.Context, service, domain string) (string, error) {
var resolver net.Resolver
// Only lookup TLS records, plaintext connections are insecure
_, addrs, err := resolver.LookupSRV(ctx, service+"s", "tcp", domain)
if dnsErr, ok := err.(*net.DNSError); ok {
if dnsErr.IsTemporary {
return "", err
}
} else if err != nil {
return "", err
}
if len(addrs) == 0 {
return "", fmt.Errorf("webdav: domain doesn't have an SRV record")
}
addr := addrs[0]
target := strings.TrimSuffix(addr.Target, ".")
if target == "" {
return "", fmt.Errorf("webdav: empty target in SRV record")
}
// TODO: perform a TXT lookup, check for a "path" key in the response
u := url.URL{Scheme: "https"}
if addr.Port == 443 {
u.Host = target
} else {
u.Host = fmt.Sprintf("%v:%v", target, addr.Port)
}
u.Path = "/.well-known/" + service
return u.String(), nil
}
// HTTPClient performs HTTP requests. It's implemented by *http.Client.
type HTTPClient interface {
Do(req *http.Request) (*http.Response, error)