func NewShotHandler(app *ZerodropApp) *ShotHandler {
	config := app.Config
	ctx := &BlacklistContext{Databases: make(map[string]*ipcat.IntervalSet)}
	if config.GeoDB != "" {
		var err error
		ctx.GeoDB, err = geoip2.Open(config.GeoDB)
		if err != nil {
			log.Printf("Could not open geolocation database: %s", err.Error())
		}
	}
	for key, location := range config.IPCat {
		key = strings.ToLower(key)
		reader, err := os.Open(location)
		if err != nil {
			log.Printf("Could not open database %q: %s", key, err.Error())
			continue
		}
		ipset := ipcat.NewIntervalSet(4096)
		if err := ipset.ImportCSV(reader); err != nil {
			log.Printf("Could not import database %q: %s", key, err.Error())
			continue
		}
		ctx.Databases[key] = ipset
	}
	return &ShotHandler{
		App:     app,
		Context: ctx,
	}
}
NewShotHandler constructs a new ShotHandler from the arguments.
package main
import (
	"io"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
	"github.com/oftn-oswg/ipcat"
	"github.com/oschwald/geoip2-golang"
)
var headerCacheControl = "no-cache, no-store, must-revalidate"
var sudo = &AdminClaims{Admin: true}
type ShotHandler struct {
	App     *ZerodropApp
	Context *BlacklistContext
}