tavern/web/handler.go

98 lines
2.9 KiB
Go

package web
import (
"net/http"
"strconv"
"github.com/getsentry/sentry-go"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"github.com/ngerakines/tavern/config"
"github.com/ngerakines/tavern/errors"
"github.com/ngerakines/tavern/storage"
)
type handler struct {
storage storage.Storage
logger *zap.Logger
domain string
sentryConfig config.SentryConfig
webFingerQueue storage.StringQueue
adminUser string
}
func (h handler) hardFail(ctx *gin.Context, err error, fields ...zap.Field) {
if h.sentryConfig.Enabled {
hub := sentry.CurrentHub().Clone()
hub.Scope().SetRequest(sentry.Request{}.FromHTTPRequest(ctx.Request))
hub.CaptureException(err)
}
trans, transOK := ctx.Get("trans")
if !transOK {
panic("trans not found in context")
}
fields = append(fields, zap.Error(err), zap.Strings("error_chain", errors.ErrorChain(err)))
h.logger.Error("request hard failed", fields...)
ctx.HTML(http.StatusInternalServerError, "error", gin.H{"error": err.Error(), "Trans": trans})
ctx.Abort()
}
func (h handler) hardFailJson(ctx *gin.Context, err error, fields ...zap.Field) {
if h.sentryConfig.Enabled {
hub := sentry.CurrentHub().Clone()
hub.Scope().SetRequest(sentry.Request{}.FromHTTPRequest(ctx.Request))
hub.CaptureException(err)
}
fields = append(fields, zap.Error(err), zap.Strings("error_chain", errors.ErrorChain(err)))
h.logger.Error("request hard failed", fields...)
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
ctx.Abort()
}
func (h handler) WriteJRD(c *gin.Context, data map[string]interface{}) {
c.Writer.Header().Set("Content-Type", "application/jrd+json")
c.Writer.Header().Set("Cache-Control", "no-cache")
c.Writer.Header().Set("Pragma", "no-cache")
c.JSON(200, data)
}
func (h handler) writeJSONLD(c *gin.Context, data map[string]interface{}) {
c.Writer.Header().Set("Content-Type", "application/activity+json")
c.Writer.Header().Set("Cache-Control", "no-cache")
c.Writer.Header().Set("Pragma", "no-cache")
c.JSON(200, data)
}
func (h handler) writeActivityJsonWithProfile(c *gin.Context, data map[string]interface{}) {
c.Writer.Header().Set("Content-Type", `application/ld+json; profile="https://www.w3.org/ns/activitystreams"`)
c.Writer.Header().Set("Cache-Control", "no-cache")
c.Writer.Header().Set("Pragma", "no-cache")
c.JSON(200, data)
}
func (h handler) flashErrorOrFail(c *gin.Context, location string, err error) {
session := sessions.Default(c)
h.logger.Error("error", zap.Error(err))
if err := appendFlashError(session, err.Error()); err != nil {
h.hardFail(c, errors.NewCannotSaveSessionError(err))
return
}
c.Redirect(http.StatusFound, location)
}
func intParam(c *gin.Context, name string, defaultValue int) int {
if input := c.Query(name); input != "" {
value, err := strconv.Atoi(input)
if err == nil && value >= 0 {
return value
}
}
return defaultValue
}