aboutsummaryrefslogtreecommitdiff
path: root/instance.go
diff options
context:
space:
mode:
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)), "/")
-}