package monitor import ( "fmt" "io/ioutil" "log" "net/http" "golang.org/x/mod/sumdb/note" "golang.org/x/mod/sumdb/tlog" ) type Database struct { URL string Key string } func (db *Database) readRemote(path string) ([]byte, error) { log.Printf("GET %s", path) resp, err := http.Get("https://" + db.URL + path) if err != nil { return nil, err } if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("get %s: expected HTTP OK but got %s", path, resp.Status) } if resp.ContentLength > 1e6 { return nil, fmt.Errorf("get %s: body too large (%d bytes)", path, resp.ContentLength) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("get %s: %v", err) } return body, nil } func (db *Database) VerifyNote(msg []byte) (*note.Note, error) { verifier, err := note.NewVerifier(db.Key) if err != nil { return nil, err } return note.Open(msg, note.VerifierList(verifier)) } func (db *Database) FetchSTH() (tlog.Tree, error) { resp, err := db.readRemote("/latest") if err != nil { return tlog.Tree{}, err } note, err := db.VerifyNote(resp) if err != nil { return tlog.Tree{}, err } return tlog.ParseTree([]byte(note.Text)) }