package apiv1 import ( "context" "errors" "net/http" "git.ar21.de/yolokube/country-geo-locations/internal/cache" "git.ar21.de/yolokube/country-geo-locations/internal/database" "git.ar21.de/yolokube/country-geo-locations/pkg/geoloc" "github.com/go-chi/chi/v5" ) type LocationHandler struct { cache *cache.Cache db *database.Database } func NewLocationHandler(cache *cache.Cache, db *database.Database) *LocationHandler { return &LocationHandler{ cache: cache, db: db, } } func (lh *LocationHandler) SearchIPHandlerFunc(w http.ResponseWriter, r *http.Request) { ipinfo, ok := r.Context().Value(keyIPInfo).(*geoloc.IPInfo) if !ok { renderResponse(w, r, errRender(errors.New("could not get ipinfo object"))) return } renderResponse(w, r, newIPInfoResponse(ipinfo)) } func (lh *LocationHandler) SearchIPHandler(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var ipinfo *geoloc.IPInfo if ipAddress := chi.URLParam(r, "ipAddress"); ipAddress != "" { ipnetnum, err := geoloc.CalculateIPNum(ipAddress) if err != nil { renderResponse(w, r, errInvalidRequest(err)) return } newipnet, found := lh.cache.Get(ipnetnum) if found { ipnetnum = newipnet } ipinfo, err = lh.db.SearchIPNet(ipnetnum) if err != nil { renderResponse(w, r, errNotFound()) return } if !found { lh.cache.Set(ipnetnum, ipinfo.IPNumFrom) } } ctx := context.WithValue(r.Context(), keyIPInfo, ipinfo) next.ServeHTTP(w, r.WithContext(ctx)) }) }