diff --git a/cmd/qrbill-example/example.go b/cmd/qrbill-api/api.go similarity index 66% rename from cmd/qrbill-example/example.go rename to cmd/qrbill-api/api.go index 06d4042..e475202 100644 --- a/cmd/qrbill-example/example.go +++ b/cmd/qrbill-api/api.go @@ -8,8 +8,6 @@ import ( "io" "log" "net/http" - "regexp" - "strings" "github.com/davecgh/go-spew/spew" "github.com/stapelberg/qrbill" @@ -61,26 +59,39 @@ func qrchFromRequest(r *http.Request) *qrbill.QRCH { } } -var fieldNameRe = regexp.MustCompile(`
( )*([^:]+):`) -var stringLiteralRe = regexp.MustCompile(`"([^"]*)"`) +func logic() error { + var listen = flag.String("listen", "localhost:9933", "[host]:port to listen on") + flag.Parse() -func qrHandler(format string) http.Handler { - if format != "png" && - format != "svg" && - format != "txt" && - format != "html" { - log.Fatalf("BUG: format must be either png, svg, txt or html") - } - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandleFunc("/qr", func(w http.ResponseWriter, r *http.Request) { prefix := "[" + r.RemoteAddr + "]" - log.Printf("%s handling request for %s", prefix, r.URL.Path) - defer log.Printf("%s done: %s", prefix, r.URL.Path) + format := r.FormValue("format") + log.Printf("%s handling request for %s, format=%s", prefix, r.URL.Path, format) + defer log.Printf("%s request completed (%s)", prefix, r.URL.Path) + + if format == "" { + msg := fmt.Sprintf("no ?format= parameter specified. Try %s", + "http://"+*listen+"/qr?format=html") + log.Printf("%s %s", prefix, msg) + http.Error(w, msg, http.StatusBadRequest) + return + } + + if format != "png" && + format != "svg" && + format != "txt" && + format != "html" { + msg := fmt.Sprintf("format (%q) must be one of png, svg, txt or html", format) + log.Printf("%s %s", prefix, msg) + http.Error(w, msg, http.StatusBadRequest) + return + } qrch := qrchFromRequest(r) bill, err := qrch.Encode() if err != nil { - log.Print(err) + log.Printf("%s %s", prefix, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -90,14 +101,14 @@ func qrHandler(format string) http.Handler { case "png": code, err := bill.EncodeToImage() if err != nil { - log.Print(err) + log.Printf("%s %s", prefix, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } var buf bytes.Buffer if err := png.Encode(&buf, code); err != nil { - log.Print(err) + log.Printf("%s %s", prefix, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -108,7 +119,7 @@ func qrHandler(format string) http.Handler { var err error b, err = bill.EncodeToSVG() if err != nil { - log.Print(err) + log.Printf("%s %s", prefix, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -120,58 +131,30 @@ func qrHandler(format string) http.Handler { spew.Fdump(w, qrch.Fill()) case "html": - w.Header().Add("Content-Type", "text/html; charset=utf-8") - fmt.Fprintf(w, ` - - QR Bill HTML Debug Page - - - -`) - sp := spew.Sdump(qrch.Fill()) - sp = strings.ReplaceAll(sp, "\n", "
") - sp = strings.ReplaceAll(sp, " ", " ") - sp = stringLiteralRe.ReplaceAllStringFunc(sp, func(stringLiteral string) string { - return `` + stringLiteral + "" - }) - sp = fieldNameRe.ReplaceAllStringFunc(sp, func(fieldName string) string { - return `` + fieldName + "" - }) - fmt.Fprintf(w, "%s", sp) + debugHTML(w, r, prefix, qrch) } // TODO: add cache control headers if _, err := io.Copy(w, bytes.NewReader(b)); err != nil { - log.Print(err) + log.Printf("%s %s", prefix, err) return } }) -} -func logic() error { - var listen = flag.String("listen", "localhost:9933", "[host]:port to listen on") - flag.Parse() - http.Handle("/qr.png", qrHandler("png")) - http.Handle("/qr.svg", qrHandler("svg")) - http.Handle("/qr.txt", qrHandler("txt")) - http.Handle("/qr.html", qrHandler("html")) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.Error(w, "not found", http.StatusNotFound) return } w.Header().Add("Content-Type", "text/html; charset=utf-8") - // TODO: add explanation for how to construt a URL + // TODO: add explanation for how to construct a URL // e.g. for usage in filemaker web view fmt.Fprintf(w, "