func (hndl ContextHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
+ if err := app.LoadConfig(ctx); err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
if err := hndl(ctx, w, r); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
func (hndl AuthenticatedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
+ if err := app.LoadConfig(ctx); err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
gaeUser := user.Current(ctx)
if gaeUser == nil {
url, err := user.LoginURL(ctx, r.URL.String())
// this is used when setting up a new subscriber in the UI. Once set
// up, this code path should not be triggered.
if verify := r.FormValue("verify"); verify != "" {
- if verify == "@FITBIT_SUBSCRIBER_CODE@" {
+ if verify == app.Config.FitbitSubscriberCode {
w.WriteHeader(http.StatusNoContent)
} else {
w.WriteHeader(http.StatusNotFound)
// Fitbit recommendation: "If signature verification fails, you should
// respond with a 404"
if !fitbit.CheckSignature(ctx, data, r.Header.Get("X-Fitbit-Signature")) {
+ log.Warningf(ctx, "signature mismatch")
w.WriteHeader(http.StatusNotFound)
return nil
}
// handleNotifications parses fitbit notifications and requests the individual
// activities from Fitbit. It is executed asynchronously via the delay package.
func handleNotifications(ctx context.Context, payload []byte) error {
+ if err := app.LoadConfig(ctx); err != nil {
+ return err
+ }
+
var subscriptions []fitbit.Subscription
if err := json.Unmarshal(payload, &subscriptions); err != nil {
return err
break
}
if err := gfitClient.SetDistance(ctx, distanceMeters, tm); err != nil {
- errs = append(errs, fmt.Errorf("gfitClient.SetDistance(%d) = %v", distanceMeters, err))
+ errs = append(errs, fmt.Errorf("gfitClient.SetDistance(%g) = %v", distanceMeters, err))
return
}
}()