1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
// Copyright Martin Dosch.
// Use of this source code is governed by the BSD-2-clause
// license that can be found in the LICENSE file.
package xmppsrv
import (
"encoding/json"
"fmt"
"io"
"net/http"
)
// The Hostmeta2 type includes all informations from the host meta 2 file of a
// given server.
type Hostmeta2 struct {
XMPP struct {
TTL int `json:"ttl"`
PublicKeyPinsSha256 []string `json:"public-key-pins-sha-256"`
} `json:"xmpp"`
Links []struct {
Rel string `json:"rel"`
Href string `json:"href,omitempty"`
Ips []string `json:"ips,omitempty"`
Priority int `json:"priority,omitempty"`
Weight int `json:"weight,omitempty"`
Sni string `json:"sni,omitempty"`
Ech string `json:"ech,omitempty"`
Port int `json:"port,omitempty"`
} `json:"links"`
}
// LookupHostmeta2 looks up the host meta 2 file for a given server and returns the
// information as Hostmeta2 type and the HTTP status code.
func LookupHostmeta2(server string) (Hostmeta2, int, error) {
// TODO: 20241030: Also make DNS server configurable.
httpClient := &http.Client{}
resp, err := httpClient.Get("https://" + server + "/.well-known/host-meta.json")
if err != nil {
return Hostmeta2{}, 0, fmt.Errorf("xmppsrv: host-meta2: failed to request host-meta file: %v", err)
}
if resp.StatusCode == 404 {
return Hostmeta2{}, resp.StatusCode, fmt.Errorf("xmppsrv: host-meta2: failed to request host-meta2 file: HTTP status 404")
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return Hostmeta2{}, resp.StatusCode, fmt.Errorf("xmppsrv: host-meta2: failed to read http response body: %v", err)
}
hm2 := Hostmeta2{}
err = json.Unmarshal(body, &hm2)
if err != nil {
return Hostmeta2{}, resp.StatusCode, fmt.Errorf("xmppsrv: host-meta2: failed to unmarshal body: %v", err)
}
return hm2, resp.StatusCode, nil
}
|