aboutsummaryrefslogtreecommitdiff
path: root/monitor/database.go
diff options
context:
space:
mode:
Diffstat (limited to 'monitor/database.go')
-rw-r--r--monitor/database.go56
1 files changed, 56 insertions, 0 deletions
diff --git a/monitor/database.go b/monitor/database.go
new file mode 100644
index 0000000..7a0ead1
--- /dev/null
+++ b/monitor/database.go
@@ -0,0 +1,56 @@
+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))
+}