package main import ( "flag" "fmt" "log" "net/http" "strconv" ) type passwordData struct { Length int Digits int Symbols int NoUpper bool DenyRepeat bool Password string } var d, defaults passwordData func generatePassword(w http.ResponseWriter, r *http.Request) { var err error if r.URL.Path != "/" { http.Error(w, "404 not found.", http.StatusNotFound) return } switch r.Method { case "GET": d.Password, err = generate(defaults.Length, defaults.Digits, defaults.Symbols, false, false) if err != nil { d.Password = "Error: " + err.Error() w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(d.Password)) return } w.WriteHeader(http.StatusOK) w.Write([]byte(d.Password)) case "POST": if err = r.ParseForm(); err != nil { w.WriteHeader(http.StatusUnprocessableEntity) w.Write([]byte(fmt.Sprintf("ParseForm() err: %v", err))) return } d.Length, err = strconv.Atoi(r.FormValue("length")) if err != nil { d.Length = defaults.Length } d.Digits, err = strconv.Atoi(r.FormValue("digits")) if err != nil { d.Digits = defaults.Digits } d.Symbols, err = strconv.Atoi(r.FormValue("symbols")) if err != nil { d.Symbols = defaults.Symbols } if r.FormValue("noupper") == "on" { d.NoUpper = true } if r.FormValue("denyrepeat") == "on" { d.DenyRepeat = true } d.Password, err = generate(d.Length, d.Digits, d.Symbols, d.NoUpper, !d.DenyRepeat) if err != nil { d.Password = "Error: " + err.Error() w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(d.Password)) return } if d.Length == 0 { d.Password = "Error: password can not have zero length" } w.WriteHeader(http.StatusOK) w.Write([]byte(d.Password)) default: w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Sorry, only GET and POST methods are supported.")) } } func checkHealth(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("Status:OK")) } func main() { // Set defaults portPtr := flag.Int("listen", 8080, "Specify on which port to listen") lengthPtr := flag.Int("length", 16, "Specify the password length") digitsPtr := flag.Int("digits", 2, "Specify the the number of digits in the password") symbolsPtr := flag.Int("symbols", 2, "Specify the the number of symbols in the password") flag.Parse() defaults.Length = *lengthPtr defaults.Digits = *digitsPtr defaults.Symbols = *symbolsPtr http.HandleFunc("/", generatePassword) http.HandleFunc("/health", checkHealth) log.Fatal(http.ListenAndServe(":"+strconv.Itoa(*portPtr), nil)) }