copy the other repo and make packages install.
This commit is contained in:
146
remote_calendar.go
Normal file
146
remote_calendar.go
Normal file
@@ -0,0 +1,146 @@
|
||||
package opentimestamps
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const userAgent = "go-opentimestamps"
|
||||
|
||||
const dumpResponse = false
|
||||
|
||||
type RemoteCalendar struct {
|
||||
baseURL string
|
||||
client *http.Client
|
||||
log *logrus.Logger
|
||||
}
|
||||
|
||||
func NewRemoteCalendar(baseURL string) (*RemoteCalendar, error) {
|
||||
// FIXME remove this
|
||||
if baseURL == "localhost" {
|
||||
baseURL = "http://localhost:14788"
|
||||
}
|
||||
// TODO validate url
|
||||
if !strings.HasSuffix(baseURL, "/") {
|
||||
baseURL += "/"
|
||||
}
|
||||
return &RemoteCalendar{
|
||||
baseURL,
|
||||
http.DefaultClient,
|
||||
logrus.New(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Check response status, return informational error message if
|
||||
// status is not `200 OK`.
|
||||
func checkStatusOK(resp *http.Response) error {
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
return nil
|
||||
}
|
||||
errMsg := fmt.Sprintf("unexpected response: %q", resp.Status)
|
||||
if resp.Body == nil {
|
||||
return fmt.Errorf("%s (body=nil)", errMsg)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
bodyBytes, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s (bodyErr=%v)", errMsg, err)
|
||||
} else {
|
||||
return fmt.Errorf("%s (body=%q)", errMsg, bodyBytes)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *RemoteCalendar) do(r *http.Request) (*http.Response, error) {
|
||||
r.Header.Add("Accept", "application/vnd.opentimestamps.v1")
|
||||
r.Header.Add("User-Agent", userAgent)
|
||||
c.log.Debugf("> %s %s", r.Method, r.URL)
|
||||
resp, err := c.client.Do(r)
|
||||
if err != nil {
|
||||
c.log.Errorf("> %s %s error: %v", r.Method, r.URL, err)
|
||||
return resp, err
|
||||
}
|
||||
c.log.Debugf("< %s %s - %v", r.Method, r.URL, resp.Status)
|
||||
if dumpResponse {
|
||||
bytes, err := httputil.DumpResponse(resp, true)
|
||||
if err == nil {
|
||||
c.log.Debugf("response dump:%s ", bytes)
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (c *RemoteCalendar) url(path string) string {
|
||||
return c.baseURL + path
|
||||
}
|
||||
|
||||
func (c *RemoteCalendar) Submit(digest []byte) (*Timestamp, error) {
|
||||
body := bytes.NewBuffer(digest)
|
||||
req, err := http.NewRequest("POST", c.url("digest"), body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.Body != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("expected 200, got %v", resp.Status)
|
||||
}
|
||||
return NewTimestampFromReader(resp.Body, digest)
|
||||
}
|
||||
|
||||
func (c *RemoteCalendar) GetTimestamp(commitment []byte) (*Timestamp, error) {
|
||||
url := c.url("timestamp/" + hex.EncodeToString(commitment))
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := checkStatusOK(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.Body != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return NewTimestampFromReader(resp.Body, commitment)
|
||||
}
|
||||
|
||||
type PendingTimestamp struct {
|
||||
Timestamp *Timestamp
|
||||
PendingAttestation *pendingAttestation
|
||||
}
|
||||
|
||||
func (p PendingTimestamp) Upgrade() (*Timestamp, error) {
|
||||
cal, err := NewRemoteCalendar(p.PendingAttestation.uri)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cal.GetTimestamp(p.Timestamp.Message)
|
||||
}
|
||||
|
||||
func PendingTimestamps(ts *Timestamp) (res []PendingTimestamp) {
|
||||
ts.Walk(func(ts *Timestamp) {
|
||||
for _, att := range ts.Attestations {
|
||||
p, ok := att.(*pendingAttestation)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
attCopy := *p
|
||||
res = append(res, PendingTimestamp{ts, &attCopy})
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user