github.com/prebid/prebid-server/v2@v2.18.0/stored_requests/events/api/api.go (about) 1 package api 2 3 import ( 4 "io" 5 "net/http" 6 7 "github.com/julienschmidt/httprouter" 8 "github.com/prebid/prebid-server/v2/stored_requests/events" 9 "github.com/prebid/prebid-server/v2/util/jsonutil" 10 ) 11 12 type eventsAPI struct { 13 saves chan events.Save 14 invalidations chan events.Invalidation 15 } 16 17 // NewEventsAPI creates an EventProducer that generates cache events from HTTP requests. 18 // The returned httprouter.Handle must be registered on both POST (update) and DELETE (invalidate) 19 // methods and provided an `:id` param via the URL, e.g.: 20 // 21 // apiEvents, apiEventsHandler, err := NewEventsApi() 22 // router.POST("/stored_requests", apiEventsHandler) 23 // router.DELETE("/stored_requests", apiEventsHandler) 24 // listener := events.Listen(cache, apiEvents) 25 // 26 // The returned HTTP endpoint should not be exposed on a public network without authentication 27 // as it allows direct writing to the cache via Update. 28 func NewEventsAPI() (events.EventProducer, httprouter.Handle) { 29 api := &eventsAPI{ 30 invalidations: make(chan events.Invalidation), 31 saves: make(chan events.Save), 32 } 33 return api, httprouter.Handle(api.HandleEvent) 34 } 35 36 func (api *eventsAPI) HandleEvent(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { 37 if r.Method == "POST" { 38 body, err := io.ReadAll(r.Body) 39 if err != nil { 40 w.WriteHeader(http.StatusBadRequest) 41 w.Write([]byte("Missing update data.\n")) 42 return 43 } 44 45 var save events.Save 46 if err := jsonutil.UnmarshalValid(body, &save); err != nil { 47 w.WriteHeader(http.StatusBadRequest) 48 w.Write([]byte("Invalid update.\n")) 49 return 50 } 51 52 api.saves <- save 53 } else if r.Method == "DELETE" { 54 body, err := io.ReadAll(r.Body) 55 if err != nil { 56 w.WriteHeader(http.StatusBadRequest) 57 w.Write([]byte("Missing invalidation data.\n")) 58 return 59 } 60 61 var invalidation events.Invalidation 62 if err := jsonutil.UnmarshalValid(body, &invalidation); err != nil { 63 w.WriteHeader(http.StatusBadRequest) 64 w.Write([]byte("Invalid invalidation.\n")) 65 return 66 } 67 68 api.invalidations <- invalidation 69 } else { 70 w.WriteHeader(http.StatusMethodNotAllowed) 71 } 72 } 73 74 func (api *eventsAPI) Invalidations() <-chan events.Invalidation { 75 return api.invalidations 76 } 77 78 func (api *eventsAPI) Saves() <-chan events.Save { 79 return api.saves 80 }