aboutsummaryrefslogtreecommitdiff
path: root/instance.go
diff options
context:
space:
mode:
authorRasmus Dahlberg <rasmus.dahlberg@kau.se>2021-02-25 14:36:35 +0100
committerRasmus Dahlberg <rasmus.dahlberg@kau.se>2021-02-25 14:36:35 +0100
commitc05c22ddbc771e7713849cae40f9d91bfafa0503 (patch)
treeb97d11ab2a914806e6f671f9aff1cab9767b2eab /instance.go
parentc9b4b43654f0ff26207cc63449f13298cd3c56e8 (diff)
major refactor based on README.md and TODOs
Updated types, improved units tests, isolated most test data to have it in one place, renamed and created new files to improve readability, and fixed a bunch of minor TODOs.
Diffstat (limited to 'instance.go')
-rw-r--r--instance.go138
1 files changed, 42 insertions, 96 deletions
diff --git a/instance.go b/instance.go
index c729bc8..6f1314b 100644
--- a/instance.go
+++ b/instance.go
@@ -1,123 +1,69 @@
package stfe
import (
- "crypto"
+ "context"
"fmt"
- "strings"
"time"
"net/http"
+ "github.com/golang/glog"
"github.com/google/trillian"
- "github.com/system-transparency/stfe/namespace"
)
-// Instance is an instance of a particular log front-end
+// Instance is an instance of the system transparency front-end
type Instance struct {
Client trillian.TrillianLogClient
- SthSource SthSource
LogParameters *LogParameters
+ SthSource SthSource
}
-// LogParameters is a collection of log parameters
-type LogParameters struct {
- LogId []byte // used externally by everyone
- TreeId int64 // used internally by Trillian
- Prefix string // e.g., "test" for <base>/test
- MaxRange int64 // max entries per get-entries request
- Submitters *namespace.NamespacePool // trusted submitters
- Witnesses *namespace.NamespacePool // trusted witnesses
- Deadline time.Duration // gRPC deadline
- Interval time.Duration // cosigning sth frequency
- Signer crypto.Signer // interface to access private key
- HashType crypto.Hash // hash function used by Trillian
+// Handlers returns a list of STFE handlers
+func (i *Instance) Handlers() []Handler {
+ return []Handler{
+ Handler{Instance: i, Handler: addEntry, Endpoint: EndpointAddEntry, Method: http.MethodPost},
+ Handler{Instance: i, Handler: addCosignature, Endpoint: EndpointAddCosignature, Method: http.MethodPost},
+ Handler{Instance: i, Handler: getLatestSth, Endpoint: EndpointGetLatestSth, Method: http.MethodGet},
+ Handler{Instance: i, Handler: getStableSth, Endpoint: EndpointGetStableSth, Method: http.MethodGet},
+ Handler{Instance: i, Handler: getCosignedSth, Endpoint: EndpointGetCosignedSth, Method: http.MethodGet},
+ Handler{Instance: i, Handler: getProofByHash, Endpoint: EndpointGetProofByHash, Method: http.MethodPost},
+ Handler{Instance: i, Handler: getConsistencyProof, Endpoint: EndpointGetConsistencyProof, Method: http.MethodPost},
+ Handler{Instance: i, Handler: getEntries, Endpoint: EndpointGetEntries, Method: http.MethodPost},
+ }
}
-// Endpoint is a named HTTP API endpoint
-type Endpoint string
-
-const (
- EndpointAddEntry = Endpoint("add-entry")
- EndpointAddCosignature = Endpoint("add-cosignature")
- EndpointGetEntries = Endpoint("get-entries")
- EndpointGetAnchors = Endpoint("get-anchors")
- EndpointGetProofByHash = Endpoint("get-proof-by-hash")
- EndpointGetConsistencyProof = Endpoint("get-consistency-proof")
- EndpointGetLatestSth = Endpoint("get-latest-sth")
- EndpointGetStableSth = Endpoint("get-stable-sth")
- EndpointGetCosignedSth = Endpoint("get-cosigned-sth")
-)
-
-func (i Instance) String() string {
- return fmt.Sprintf("%s\n", i.LogParameters)
+// Handler implements the http.Handler interface, and contains a reference
+// to an STFE server instance as well as a function that uses it.
+type Handler struct {
+ Instance *Instance
+ Endpoint Endpoint
+ Method string
+ Handler func(context.Context, *Instance, http.ResponseWriter, *http.Request) (int, error)
}
-func (lp LogParameters) String() string {
- return fmt.Sprintf("LogId(%s) TreeId(%d) Prefix(%s) MaxRange(%d) Submitters(%d) Witnesses(%d) Deadline(%v) Interval(%v)", lp.id(), lp.TreeId, lp.Prefix, lp.MaxRange, len(lp.Submitters.List()), len(lp.Witnesses.List()), lp.Deadline, lp.Interval)
-}
+// ServeHTTP is part of the http.Handler interface
+func (a Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ // export prometheus metrics
+ var now time.Time = time.Now()
+ var statusCode int
+ defer func() {
+ rspcnt.Inc(string(a.Instance.LogParameters.LogIdBytes), string(a.Endpoint), fmt.Sprintf("%d", statusCode))
+ latency.Observe(time.Now().Sub(now).Seconds(), string(a.Instance.LogParameters.LogIdBytes), string(a.Endpoint), fmt.Sprintf("%d", statusCode))
+ }()
+ reqcnt.Inc(string(a.Instance.LogParameters.LogIdBytes), string(a.Endpoint))
-func (e Endpoint) String() string {
- return string(e)
-}
+ ctx, cancel := context.WithDeadline(r.Context(), now.Add(a.Instance.LogParameters.Deadline))
+ defer cancel()
-// NewInstance creates a new STFE instance
-func NewInstance(lp *LogParameters, client trillian.TrillianLogClient, source SthSource) *Instance {
- return &Instance{
- LogParameters: lp,
- Client: client,
- SthSource: source,
+ if r.Method != a.Method {
+ glog.Warningf("%s/%s: got HTTP %s, wanted HTTP %s", a.Instance.LogParameters.Prefix, string(a.Endpoint), r.Method, a.Method)
+ http.Error(w, "", http.StatusMethodNotAllowed)
+ return
}
-}
-// NewLogParameters creates new log parameters. Note that the signer is
-// assumed to be an ed25519 signing key. Could be fixed at some point.
-func NewLogParameters(signer crypto.Signer, logId *namespace.Namespace, treeId int64, prefix string, submitters, witnesses *namespace.NamespacePool, maxRange int64, interval, deadline time.Duration) (*LogParameters, error) {
- if signer == nil {
- return nil, fmt.Errorf("need a signer but got none")
- }
- if maxRange < 1 {
- return nil, fmt.Errorf("max range must be at least one")
- }
- lid, err := logId.Marshal()
+ statusCode, err := a.Handler(ctx, a.Instance, w, r)
if err != nil {
- return nil, fmt.Errorf("failed encoding log identifier: %v", err)
- }
- return &LogParameters{
- LogId: lid,
- TreeId: treeId,
- Prefix: prefix,
- MaxRange: maxRange,
- Submitters: submitters,
- Witnesses: witnesses,
- Deadline: deadline,
- Interval: interval,
- Signer: signer,
- HashType: crypto.SHA256, // STFE assumes RFC 6962 hashing
- }, nil
-}
-
-// Handlers returns a list of STFE handlers
-func (i *Instance) Handlers() []Handler {
- return []Handler{
- Handler{instance: i, handler: addEntry, endpoint: EndpointAddEntry, method: http.MethodPost},
- Handler{instance: i, handler: addCosi, endpoint: EndpointAddCosignature, method: http.MethodPost},
- Handler{instance: i, handler: getEntries, endpoint: EndpointGetEntries, method: http.MethodGet},
- Handler{instance: i, handler: getAnchors, endpoint: EndpointGetAnchors, method: http.MethodGet},
- Handler{instance: i, handler: getProofByHash, endpoint: EndpointGetProofByHash, method: http.MethodGet},
- Handler{instance: i, handler: getConsistencyProof, endpoint: EndpointGetConsistencyProof, method: http.MethodGet},
- Handler{instance: i, handler: getSth, endpoint: EndpointGetLatestSth, method: http.MethodGet},
- Handler{instance: i, handler: getStableSth, endpoint: EndpointGetStableSth, method: http.MethodGet},
- Handler{instance: i, handler: getCosi, endpoint: EndpointGetCosignedSth, method: http.MethodGet},
+ glog.Warningf("handler error %s/%s: %v", a.Instance.LogParameters.Prefix, a.Endpoint, err)
+ http.Error(w, "", statusCode)
}
}
-
-// id formats the log's identifier as base64
-func (i *LogParameters) id() string {
- return b64(i.LogId)
-}
-
-// Path joins a number of components to form a full endpoint path, e.g., base
-// ("example.com"), prefix ("st/v1"), and the endpoint itself ("get-sth").
-func (e Endpoint) Path(components ...string) string {
- return strings.Join(append(components, string(e)), "/")
-}