aboutsummaryrefslogtreecommitdiff
path: root/monitor/database.go
diff options
context:
space:
mode:
authorBen Burwell <ben@benburwell.com>2019-09-24 14:06:09 -0400
committerBen Burwell <ben@benburwell.com>2019-09-24 14:06:09 -0400
commitdea6ee40f067e0a3ef81972cfcfac1761eeb27d4 (patch)
tree5fb7e48ab9ee8b250058ff9f9ba28c21268e552d /monitor/database.go
parenta583fb71e1a3c4a99ecb8742168ad71c3b289b55 (diff)
Implement monitor package
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))
+}