aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/client.go13
-rw-r--r--handler_test.go17
-rw-r--r--instance.go18
-rw-r--r--instance_test.go40
-rw-r--r--reqres_test.go7
5 files changed, 69 insertions, 26 deletions
diff --git a/client/client.go b/client/client.go
index 21be669..6ab654a 100644
--- a/client/client.go
+++ b/client/client.go
@@ -4,7 +4,6 @@ import (
"bytes"
"context"
"fmt"
- "strings"
"crypto/ed25519"
"crypto/tls"
@@ -99,7 +98,7 @@ func (c *Client) AddEntry(ctx context.Context, name, checksum []byte) (*stfe.StI
}
glog.V(3).Infof("created post data: %s", string(data))
- url := c.protocol() + strings.Join([]string{c.Log.BaseUrl, string(stfe.EndpointAddEntry)}, "/")
+ url := stfe.EndpointAddEntry.Url(c.protocol() + c.Log.BaseUrl)
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("failed creating http request: %v", err)
@@ -126,7 +125,7 @@ func (c *Client) AddEntry(ctx context.Context, name, checksum []byte) (*stfe.StI
// GetSth fetches and verifies the most recent STH. Safe to use without a
// client chain and corresponding private key.
func (c *Client) GetSth(ctx context.Context) (*stfe.StItem, error) {
- url := c.protocol() + strings.Join([]string{c.Log.BaseUrl, string(stfe.EndpointGetSth)}, "/")
+ url := stfe.EndpointGetSth.Url(c.protocol() + c.Log.BaseUrl)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, fmt.Errorf("failed creating http request: %v", err)
@@ -152,7 +151,7 @@ func (c *Client) GetSth(ctx context.Context) (*stfe.StItem, error) {
// GetConsistencyProof fetches and verifies a consistency proof between two
// STHs. Safe to use without a client chain and corresponding private key.
func (c *Client) GetConsistencyProof(ctx context.Context, first, second *stfe.StItem) (*stfe.StItem, error) {
- url := c.protocol() + strings.Join([]string{c.Log.BaseUrl, string(stfe.EndpointGetConsistencyProof)}, "/")
+ url := stfe.EndpointGetConsistencyProof.Url(c.protocol() + c.Log.BaseUrl)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, fmt.Errorf("failed creating http request: %v", err)
@@ -181,7 +180,7 @@ func (c *Client) GetConsistencyProof(ctx context.Context, first, second *stfe.St
// STH. Safe to use without a client chain and corresponding private key.
func (c *Client) GetProofByHash(ctx context.Context, treeSize uint64, rootHash, leaf []byte) (*stfe.StItem, error) {
leafHash := rfc6962.DefaultHasher.HashLeaf(leaf)
- url := c.protocol() + strings.Join([]string{c.Log.BaseUrl, string(stfe.EndpointGetProofByHash)}, "/")
+ url := stfe.EndpointGetProofByHash.Url(c.protocol() + c.Log.BaseUrl)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, fmt.Errorf("failed creating http request: %v", err)
@@ -214,7 +213,7 @@ func (c *Client) GetProofByHash(ctx context.Context, treeSize uint64, rootHash,
// Note that a certificate chain is considered valid if it is chained correctly.
// In other words, the caller may want to check whether the anchor is trusted.
func (c *Client) GetEntries(ctx context.Context, start, end uint64) ([]*stfe.GetEntryResponse, error) {
- url := c.protocol() + strings.Join([]string{c.Log.BaseUrl, string(stfe.EndpointGetEntries)}, "/")
+ url := stfe.EndpointGetEntries.Url(c.protocol() + c.Log.BaseUrl)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, fmt.Errorf("failed creating http request: %v", err)
@@ -252,7 +251,7 @@ func (c *Client) GetEntries(ctx context.Context, start, end uint64) ([]*stfe.Get
// GetAnchors fetches the log's trust anchors. Safe to use without a client
// chain and corresponding private key.
func (c *Client) GetAnchors(ctx context.Context) ([]*x509.Certificate, error) {
- url := c.protocol() + strings.Join([]string{c.Log.BaseUrl, string(stfe.EndpointGetAnchors)}, "/")
+ url := stfe.EndpointGetAnchors.Url(c.protocol() + c.Log.BaseUrl)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, fmt.Errorf("failed creating http request: %v", err)
diff --git a/handler_test.go b/handler_test.go
index 0c8b1a6..34f390a 100644
--- a/handler_test.go
+++ b/handler_test.go
@@ -5,7 +5,6 @@ import (
"context"
"crypto"
"fmt"
- "strings"
"testing"
"time"
@@ -86,7 +85,7 @@ func TestGetHandlersRejectPost(t *testing.T) {
s := httptest.NewServer(handler)
defer s.Close()
- url := strings.Join([]string{s.URL, th.instance.LogParameters.Prefix, string(endpoint)}, "/")
+ url := endpoint.Url(s.URL, th.instance.LogParameters.Prefix)
if rsp, err := http.Post(url, "application/json", nil); err != nil {
t.Fatalf("http.Post(%s)=(_,%q), want (_,nil)", url, err)
} else if rsp.StatusCode != http.StatusMethodNotAllowed {
@@ -106,7 +105,7 @@ func TestPostHandlersRejectGet(t *testing.T) {
s := httptest.NewServer(handler)
defer s.Close()
- url := strings.Join([]string{s.URL, th.instance.LogParameters.Prefix, string(endpoint)}, "/")
+ url := endpoint.Url(s.URL, th.instance.LogParameters.Prefix)
if rsp, err := http.Get(url); err != nil {
t.Fatalf("http.Get(%s)=(_,%q), want (_,nil)", url, err)
} else if rsp.StatusCode != http.StatusMethodNotAllowed {
@@ -121,7 +120,7 @@ func TestGetAnchors(t *testing.T) {
th := newTestHandler(t, nil)
defer th.mockCtrl.Finish()
- url := strings.Join([]string{"http://example.com", th.instance.LogParameters.Prefix, string(EndpointGetAnchors)}, "/")
+ url := EndpointGetAnchors.Url("http://example.com", th.instance.LogParameters.Prefix)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
t.Fatalf("failed creating http request: %v", err)
@@ -200,7 +199,7 @@ func TestGetEntries(t *testing.T) {
th := newTestHandler(t, nil)
defer th.mockCtrl.Finish()
- url := strings.Join([]string{"http://example.com", th.instance.LogParameters.Prefix, string(EndpointGetEntries)}, "/")
+ url := EndpointGetEntries.Url("http://example.com", th.instance.LogParameters.Prefix)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
t.Fatalf("failed creating http request: %v", err)
@@ -313,7 +312,7 @@ func TestAddEntry(t *testing.T) {
th := newTestHandler(t, table.signer)
defer th.mockCtrl.Finish()
- url := strings.Join([]string{"http://example.com", th.instance.LogParameters.Prefix, string(EndpointAddEntry)}, "/")
+ url := EndpointAddEntry.Url("http://example.com", th.instance.LogParameters.Prefix)
req, err := http.NewRequest("POST", url, table.breq)
if err != nil {
t.Fatalf("failed creating http request: %v", err)
@@ -407,7 +406,7 @@ func TestGetSth(t *testing.T) {
th := newTestHandler(t, table.signer)
defer th.mockCtrl.Finish()
- url := strings.Join([]string{"http://example.com", th.instance.LogParameters.Prefix, string(EndpointGetSth)}, "/")
+ url := EndpointGetSth.Url("http://example.com", th.instance.LogParameters.Prefix)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
t.Fatalf("failed creating http request: %v", err)
@@ -511,7 +510,7 @@ func TestGetConsistencyProof(t *testing.T) {
th := newTestHandler(t, nil)
defer th.mockCtrl.Finish()
- url := strings.Join([]string{"http://example.com", th.instance.LogParameters.Prefix, string(EndpointGetConsistencyProof)}, "/")
+ url := EndpointGetConsistencyProof.Url("http://example.com", th.instance.LogParameters.Prefix)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
t.Fatalf("failed creating http request: %v", err)
@@ -620,7 +619,7 @@ func TestGetProofByHash(t *testing.T) {
th := newTestHandler(t, nil)
defer th.mockCtrl.Finish()
- url := strings.Join([]string{"http://example.com", th.instance.LogParameters.Prefix, string(EndpointGetProofByHash)}, "/")
+ url := EndpointGetProofByHash.Url("http://example.com", th.instance.LogParameters.Prefix)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
t.Fatalf("failed creating http request: %v", err)
diff --git a/instance.go b/instance.go
index 8a0007a..55b23fc 100644
--- a/instance.go
+++ b/instance.go
@@ -28,6 +28,12 @@ const (
EndpointGetSth = Endpoint("get-sth")
)
+// Url builds an endpoint url from a number of components, e.g., base and prefix
+func (e Endpoint) Url(components ...string) string {
+ components = append(components, string(e))
+ return strings.Join(components, "/")
+}
+
// Instance is an instance of a particular log front-end
type Instance struct {
LogParameters *LogParameters
@@ -116,27 +122,27 @@ func (i *Instance) registerHandlers(mux *http.ServeMux) {
handler handler
}{
{
- strings.Join([]string{"", i.LogParameters.Prefix, string(EndpointAddEntry)}, "/"),
+ EndpointAddEntry.Url("", i.LogParameters.Prefix),
handler{instance: i, handler: addEntry, endpoint: EndpointAddEntry, method: http.MethodPost},
},
{
- strings.Join([]string{"", i.LogParameters.Prefix, string(EndpointGetEntries)}, "/"),
+ EndpointGetEntries.Url("", i.LogParameters.Prefix),
handler{instance: i, handler: getEntries, endpoint: EndpointGetEntries, method: http.MethodGet},
},
{
- strings.Join([]string{"", i.LogParameters.Prefix, string(EndpointGetAnchors)}, "/"),
+ EndpointGetAnchors.Url("", i.LogParameters.Prefix),
handler{instance: i, handler: getAnchors, endpoint: EndpointGetAnchors, method: http.MethodGet},
},
{
- strings.Join([]string{"", i.LogParameters.Prefix, string(EndpointGetProofByHash)}, "/"),
+ EndpointGetProofByHash.Url("", i.LogParameters.Prefix),
handler{instance: i, handler: getProofByHash, endpoint: EndpointGetProofByHash, method: http.MethodGet},
},
{
- strings.Join([]string{"", i.LogParameters.Prefix, string(EndpointGetConsistencyProof)}, "/"),
+ EndpointGetConsistencyProof.Url("", i.LogParameters.Prefix),
handler{instance: i, handler: getConsistencyProof, endpoint: EndpointGetConsistencyProof, method: http.MethodGet},
},
{
- strings.Join([]string{"", i.LogParameters.Prefix, string(EndpointGetSth)}, "/"),
+ EndpointGetSth.Url("", i.LogParameters.Prefix),
handler{instance: i, handler: getSth, endpoint: EndpointGetSth, method: http.MethodGet},
},
} {
diff --git a/instance_test.go b/instance_test.go
index 7facdd6..6fe0e5b 100644
--- a/instance_test.go
+++ b/instance_test.go
@@ -38,3 +38,43 @@ func makeTestLogParameters(t *testing.T, signer crypto.Signer) *LogParameters {
HashType: testHashType,
}
}
+
+func TestEndpointUrl(t *testing.T) {
+ base, prefix := "http://example.com", "test"
+ for _, table := range []struct {
+ endpoint Endpoint
+ want string
+ }{
+ {
+ endpoint: EndpointAddEntry,
+ want: "http://example.com/test/add-entry",
+ },
+ {
+ endpoint: EndpointGetEntries,
+ want: "http://example.com/test/get-entries",
+ },
+ {
+ endpoint: EndpointGetProofByHash,
+ want: "http://example.com/test/get-proof-by-hash",
+ },
+ {
+ endpoint: EndpointGetConsistencyProof,
+ want: "http://example.com/test/get-consistency-proof",
+ },
+ {
+ endpoint: EndpointGetSth,
+ want: "http://example.com/test/get-sth",
+ },
+ {
+ endpoint: EndpointGetAnchors,
+ want: "http://example.com/test/get-anchors",
+ },
+ } {
+ if got, want := table.endpoint.Url(base, prefix), table.want; got != want {
+ t.Errorf("got %s but wanted %s with multiple components", got, want)
+ }
+ if got, want := table.endpoint.Url(base+"/"+prefix), table.want; got != want {
+ t.Errorf("got %s but wanted %s with one component", got, want)
+ }
+ }
+}
diff --git a/reqres_test.go b/reqres_test.go
index fadfb73..1bb0348 100644
--- a/reqres_test.go
+++ b/reqres_test.go
@@ -4,7 +4,6 @@ import (
"bytes"
"fmt"
"strconv"
- "strings"
"testing"
"crypto/x509"
@@ -66,7 +65,7 @@ func TestNewGetEntriesRequest(t *testing.T) {
end: fmt.Sprintf("%d", testMaxRange-1),
},
} {
- url := strings.Join([]string{"http://example.com/", lp.Prefix, string(EndpointGetEntries)}, "/")
+ url := EndpointGetEntries.Url("http://example.com/", lp.Prefix)
r, err := http.NewRequest("GET", url, nil)
if err != nil {
t.Fatalf("must make http request in test %q: %v", table.description, err)
@@ -137,7 +136,7 @@ func TestNewGetProofByHashRequest(t *testing.T) {
hash: b64(testNodeHash),
},
} {
- url := strings.Join([]string{"http://example.com/", lp.Prefix, string(EndpointGetProofByHash)}, "/")
+ url := EndpointGetProofByHash.Url("http://example.com/", lp.Prefix)
r, err := http.NewRequest("GET", url, nil)
if err != nil {
t.Fatalf("must make http request in test %q: %v", table.description, err)
@@ -202,7 +201,7 @@ func TestNewGetConsistencyProofRequest(t *testing.T) {
second: "2",
},
} {
- url := strings.Join([]string{"http://example.com/", lp.Prefix, string(EndpointGetConsistencyProof)}, "/")
+ url := EndpointGetConsistencyProof.Url("http://example.com/", lp.Prefix)
r, err := http.NewRequest("GET", url, nil)
if err != nil {
t.Fatalf("must make http request in test %q: %v", table.description, err)