package web import ( "encoding/json" "errors" "fmt" "image" "image/png" "net/http" "git.fjla.uk/fred.boniface/barcodes/generation" "git.fjla.uk/fred.boniface/barcodes/validation" "github.com/boombuler/barcode" ) // Generates a barcode from the data and options provided in the request func generateBarcode(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost && r.Method != http.MethodGet { http.Error(w, "Use a POST or GET request for barcode generation. See the help page for more information", http.StatusMethodNotAllowed) return } var req *BarcodeRequest var err error if r.Method == http.MethodGet { req, err = generateFromGet(r) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } } else { err := json.NewDecoder(r.Body).Decode(&req) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } } parameters := generation.Parameters{ Format: generation.BarcodeType(req.BarcodeType), ECCLevel: generation.ECCLevel(req.ECCLevel), Content: req.Content, } validate := validation.Validate(parameters) if !validate { fmt.Println("Validation Failed") http.Error(w, "Validation Failed", http.StatusBadRequest) return } barcodeGen, err := generation.Generate(parameters) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if barcodeGen == nil { fmt.Println("Generation failed, no barcode created") http.Error(w, "Barcode Generation Failed", http.StatusInternalServerError) return } barcodeGen, _ = barcode.Scale(barcodeGen, int(req.Width), int(req.Height)) image, isImage := barcodeGen.(image.Image) if !isImage { fmt.Println("Generation failed - no image") http.Error(w, "Generated Barcode is not an image", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "image/png") err = png.Encode(w, image) if err != nil { http.Error(w, "Error streaming barcode", http.StatusInternalServerError) } } func generateFromGet(r *http.Request) (*BarcodeRequest, error) { //var parameters generation.Parameters if r.Method == http.MethodGet { validTypes := map[string]bool{ "qr": true, "aztec": true, "datamatrix": true, } typeParam := r.URL.Query().Get("type") content := r.URL.Query().Get("text") if typeParam == "" || content == "" { return nil, errors.New("both 'type' and 'text' parameters are required") } if !validTypes[typeParam] { return nil, errors.New("'type' must be 'qr', 'aztec', or 'datamatrix'") } barcodeReq := &BarcodeRequest{ BarcodeType: typeParam, Width: 300, Height: 300, ECCLevel: 2, Content: content, } return barcodeReq, nil } else { return nil, errors.New("incorrect request type passed to function") } }