package main import ( "encoding/json" "fmt" "log" "net/http" "net/http/httputil" "os" "strings" ) type config struct { Listen string `json:"listen"` Domain string `json:"domain"` Organizations []string `json:"organizations"` } func searcher(config *config, w http.ResponseWriter, r *http.Request) { for _, org := range config.Organizations { actualUrl := fmt.Sprintf( "https://%s/api/packages/%s/maven/%s", config.Domain, org, strings.TrimLeft(r.URL.Path, "/"), ) resp, err := http.Head(actualUrl) if err != nil { w.WriteHeader(500) _, err := fmt.Fprintf(w, "%v", err) if err != nil { log.Fatal(err) } return } switch resp.StatusCode { case 200: w.Header().Set("Location", actualUrl) w.WriteHeader(307) return case 404: fallthrough case 403: continue case 502: fallthrough case 503: w.WriteHeader(503) return default: w.WriteHeader(500) rawResp, err := httputil.DumpResponse(resp, true) if err != nil { log.Fatal(err) return } _, err = w.Write(rawResp) if err != nil { log.Fatal(err) return } return } } w.WriteHeader(404) } func readConfig(path string) config { file, err := os.Open(path) if err != nil { panic(err) } var data config if err := json.NewDecoder(file).Decode(&data); err != nil { panic(err) } if err := file.Close(); err != nil { panic(err) } return data } func main() { if len(os.Args) < 2 { fmt.Println("Missed path to config") return } if len(os.Args) > 2 { fmt.Println("Excess arguments") return } config := readConfig(os.Args[1]) if config.Organizations == nil { fmt.Println("Missed organizations list") return } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { searcher(&config, w, r) }) log.Fatal(http.ListenAndServe(config.Listen, nil)) }