Skip to content

Commit

Permalink
api: Add status (#22)
Browse files Browse the repository at this point in the history
* api: Add status

* Avoid leaking body on decode error
  • Loading branch information
dajohi committed Mar 14, 2018
1 parent 788ac33 commit 947c90c
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 6 deletions.
12 changes: 12 additions & 0 deletions api/v1/v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
// XXX add a clamp to all batches

const (
StatusRoute = "/v1/status/" // Server status
TimestampRoute = "/v1/timestamp/" // Digests ingest
VerifyRoute = "/v1/verify/" // Multi verify ingest

Expand Down Expand Up @@ -41,6 +42,17 @@ var (
RegexpTimestamp = regexp.MustCompile("[0-9]{10}")
)

// Status is used to ask the server if everything is running properly.
// ID is user settable and can be used as a unique identifier by the client.
type Status struct {
ID string `json:"id"`
}

// StatusReply is returned by the server if everything is running properly.
type StatusReply struct {
ID string `json:"id"`
}

// Timestamp is used to ask the timestamp server to store a batch of digests.
// ID is user settable and can be used as a unique identifier by the client.
type Timestamp struct {
Expand Down
65 changes: 59 additions & 6 deletions dcrtimed/dcrtimed.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ type DcrtimeStore struct {
httpClient *http.Client
}

func (d *DcrtimeStore) sendToBackend(w http.ResponseWriter, route, contentType, remoteAddr string, body *bytes.Reader) {
func (d *DcrtimeStore) sendToBackend(w http.ResponseWriter, method, route, contentType, remoteAddr string, body *bytes.Reader) {
storeHost := fmt.Sprintf("https://%s%s", d.cfg.StoreHost, route)

req, err := http.NewRequest("POST", storeHost, body)
req, err := http.NewRequest(method, storeHost, body)
if err != nil {
log.Errorf("Error generating new http request: %v", err)
util.RespondWithError(w, http.StatusServiceUnavailable,
Expand Down Expand Up @@ -96,6 +96,28 @@ func (d *DcrtimeStore) sendToBackend(w http.ResponseWriter, route, contentType,
}
}

func (d *DcrtimeStore) proxyStatus(w http.ResponseWriter, r *http.Request) {
b, err := ioutil.ReadAll(r.Body)
r.Body.Close()
if err != nil {
util.RespondWithError(w, http.StatusBadRequest,
"Unable to read request")
return
}

var s v1.Status
decoder := json.NewDecoder(bytes.NewReader(b))
if err := decoder.Decode(&s); err != nil {
util.RespondWithError(w, http.StatusBadRequest,
"Invalid request payload")
return
}

d.sendToBackend(w, r.Method, v1.StatusRoute, r.Header.Get("Content-Type"),
r.RemoteAddr, bytes.NewReader(b))
log.Infof("Status %v", r.RemoteAddr)
}

func (d *DcrtimeStore) proxyTimestamp(w http.ResponseWriter, r *http.Request) {
b, err := ioutil.ReadAll(r.Body)
r.Body.Close()
Expand All @@ -113,7 +135,7 @@ func (d *DcrtimeStore) proxyTimestamp(w http.ResponseWriter, r *http.Request) {
return
}

d.sendToBackend(w, v1.TimestampRoute, r.Header.Get("Content-Type"),
d.sendToBackend(w, r.Method, v1.TimestampRoute, r.Header.Get("Content-Type"),
r.RemoteAddr, bytes.NewReader(b))

for _, v := range t.Digests {
Expand All @@ -138,7 +160,7 @@ func (d *DcrtimeStore) proxyVerify(w http.ResponseWriter, r *http.Request) {
return
}

d.sendToBackend(w, v1.VerifyRoute, r.Header.Get("Content-Type"),
d.sendToBackend(w, r.Method, v1.VerifyRoute, r.Header.Get("Content-Type"),
r.RemoteAddr, bytes.NewReader(b))
log.Infof("Verify %v: Timestamps %v Digests %v",
r.RemoteAddr, len(v.Timestamps), len(v.Digests))
Expand All @@ -163,16 +185,42 @@ func convertDigests(d []string) ([][sha256.Size]byte, error) {
return result, nil
}

// status returns server status information
func (d *DcrtimeStore) status(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()

var s v1.Status
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&s); err != nil {
util.RespondWithError(w, http.StatusBadRequest,
"Invalid request payload")
return
}

// Log for audit trail and reuse loop to translate MultiError to JSON
// Results.
via := r.RemoteAddr
xff := r.Header.Get(forward)
if xff != "" {
via = fmt.Sprintf("%v via %v", xff, r.RemoteAddr)
}
log.Infof("Status %v", via)

// Tell client the good news.
util.RespondWithJSON(w, http.StatusOK, v1.StatusReply(s))
}

// timestamp takes a frontend timestamp and sends it off to the backend.
func (d *DcrtimeStore) timestamp(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()

var t v1.Timestamp
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&t); err != nil {
util.RespondWithError(w, http.StatusBadRequest,
"Invalid request payload")
return
}
defer r.Body.Close()

// Validate all digests. If one is invalid return failure.
digests, err := convertDigests(t.Digests)
Expand Down Expand Up @@ -242,14 +290,15 @@ func (d *DcrtimeStore) timestamp(w http.ResponseWriter, r *http.Request) {
}

func (d *DcrtimeStore) verify(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()

var v v1.Verify
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&v); err != nil {
util.RespondWithError(w, http.StatusBadRequest,
"Invalid request payload")
return
}
defer r.Body.Close()

// Validate all digests. If one is invalid return failure.
digests, err := convertDigests(v.Digests)
Expand Down Expand Up @@ -500,11 +549,15 @@ func _main() error {
TLSClientConfig: tlsConfig,
}
d.httpClient = &http.Client{Transport: tr}
d.router.HandleFunc(v1.StatusRoute,
d.proxyStatus).Methods("GET")
d.router.HandleFunc(v1.TimestampRoute,
d.proxyTimestamp).Methods("POST")
d.router.HandleFunc(v1.VerifyRoute,
d.proxyVerify).Methods("POST")
} else {
d.router.HandleFunc(v1.StatusRoute,
d.status).Methods("GET")
d.router.HandleFunc(v1.TimestampRoute,
d.timestamp).Methods("POST")
d.router.HandleFunc(v1.VerifyRoute,
Expand Down

0 comments on commit 947c90c

Please sign in to comment.