// Execute trigger content negottion and the actual execution of one of the // action's handlers. func (base *Base) Execute(action interface{}) { contentType := render.Negotiate(base.Ctx, base.R) switch contentType { case render.MimeHal, render.MimeJSON: action, ok := action.(JSON) if !ok { goto NotAcceptable } action.JSON() if base.Err != nil { problem.Render(base.Ctx, base.W, base.Err) return } case render.MimeEventStream: action, ok := action.(SSE) if !ok { goto NotAcceptable } stream, ok := sse.NewStream(base.Ctx, base.W, base.R) if !ok { return } for { action.SSE(stream) if base.Err != nil { stream.Err(base.Err) } if stream.IsDone() { return } select { case <-base.Ctx.Done(): return case <-sse.Pumped(): //no-op, continue onto the next iteration } } default: goto NotAcceptable } return NotAcceptable: problem.Render(base.Ctx, base.W, problem.NotAcceptable) return }
// ServeHTTPC is a method for web.Handler func (action RateLimitExceededAction) ServeHTTP(w http.ResponseWriter, r *http.Request) { ap := &action.Action c := web.C{ Env: map[interface{}]interface{}{ "app": action.App, }, } ap.Prepare(c, w, r) ap.App = action.App problem.Render(action.Ctx, action.W, problem.RateLimitExceeded) }
// RecoverMiddleware helps the server recover from panics. It ensures that // no request can fully bring down the horizon server, and it also logs the // panics to the logging subsystem. func RecoverMiddleware(c *web.C, h http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { ctx := gctx.FromC(*c) defer func() { if err := recover(); err != nil { err := errors.Wrap(err, 2) problem.Render(ctx, w, err) } }() h.ServeHTTP(w, r) } return http.HandlerFunc(fn) }
// RecoverMiddleware helps the server recover from panics. It ensures that // no request can fully bring down the horizon server, and it also logs the // panics to the logging subsystem. func RecoverMiddleware(c *web.C, h http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { ctx := gctx.FromC(*c) defer func() { if rec := recover(); rec != nil { err := extractErrorFromPanic(rec) reportToSentry(err, r) problem.Render(ctx, w, err) } }() h.ServeHTTP(w, r) } return http.HandlerFunc(fn) }
// JSON format action handler func (action *TransactionCreateAction) JSON() { l := action.App.submitter.Submit(action.Ctx, action.GetString("tx")) select { case result := <-l: resource := &ResultResource{result} if resource.IsSuccess() { hal.Render(action.W, resource.Success()) } else { problem.Render(action.Ctx, action.W, resource.Error()) } case <-action.Ctx.Done(): return } }
// JSON is a method for actions.JSON func (action *NotImplementedAction) JSON() { problem.Render(action.Ctx, action.W, problem.NotImplemented) }
// JSON is a method for actions.JSON func (action *NotFoundAction) JSON() { problem.Render(action.Ctx, action.W, problem.NotFound) }