package main import ( "fmt" "io" "log" "net/http" "os" "strings" ) const ( // MethodPurge declaration for Varnish. MethodPurge = "PURGE" ) var ( varnishList = MakeVarnishList() status = "200 Purged" ) // MakeVarnishList reads the list of varnish servers from a file on disk. func MakeVarnishList() []string { Data, err := os.ReadFile("./varnish") if err != nil { log.Fatal(err) } sliceData := strings.Split(string(Data), ",") return sliceData } // PurgeHandler handles PURGE request to broadcast it to all varnish instances. func PurgeHandler(w http.ResponseWriter, r *http.Request) { url := r.URL.String() status := SendToVarnish(url) if status != "200 Purged" { w.WriteHeader(405) } io.WriteString(w, status) } // SendToVarnish send to all varnish servers define in varnishList the PURGE request. func SendToVarnish(url string) string { status = "200 Purged" // Take url to ban as argument. // Loop over the list of Varnish servers and send PURGE request to each. for i := 0; i < len(varnishList); i++ { //status = "200 Purged" client := &http.Client{} domain := strings.Trim(varnishList[i], "\r\n") req, err := http.NewRequest(MethodPurge, domain + url, nil) if err != nil { log.Fatal("NewRequest: %s", err) } resp, err := client.Do(req) if err != nil { log.Fatal("Client.do: %s", err) } //fmt.Printf("Resp: %v\n", resp) if resp.StatusCode != 200 { status = "405 Not Allowed" } fmt.Println("Purge URL" + " " + domain + url + " : " + status) } return status } // HealthHandler handles healthcheck requests and return 200. func HealthHandler(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "OK") } func main() { http.HandleFunc("/", PurgeHandler) http.HandleFunc("/healthcheck", HealthHandler) log.Fatal(http.ListenAndServe(":6081",nil)) }