Example #1
0
// 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 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)
}
Example #3
0
// 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 {
				stack := make([]byte, 4096) // 4k of stack should be sufficient to see the source
				n := runtime.Stack(stack, false)

				log.
					WithField(ctx, "stacktrace", string(stack[:n])).
					Errorf("panic: %+v", err)

				//TODO: include stack trace if in debug mode
				problem.Render(gctx.FromC(*c), w, problem.ServerError)
			}
		}()

		h.ServeHTTP(w, r)
	}

	return http.HandlerFunc(fn)
}
// JSON is a method for actions.JSON
func (action *NotImplementedAction) JSON() {
	problem.Render(action.Ctx, action.W, problem.NotImplemented)
}
Example #5
0
// JSON is a method for actions.JSON
func (action *NotFoundAction) JSON() {
	problem.Render(action.Ctx, action.W, problem.NotFound)
}