Put different transforms into different functions
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		
							parent
							
								
									2ac1c8ba5f
								
							
						
					
					
						commit
						14ca478ecc
					
				
					 1 changed files with 81 additions and 68 deletions
				
			
		
							
								
								
									
										149
									
								
								main.go
									
										
									
									
									
								
							
							
						
						
									
										149
									
								
								main.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,10 +1,12 @@
 | 
			
		|||
// vi:ts=4:sts=4:sw=4:noet:tw=72
 | 
			
		||||
// (c) 2018 Karthik Karanth (https://github.com/medakk/gotiny)
 | 
			
		||||
// (c) 2018-2021 Andreas Neue <an@dnix.de>
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strconv"
 | 
			
		||||
| 
						 | 
				
			
			@ -23,7 +25,7 @@ func init() {
 | 
			
		|||
	flag.Parse()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func resizeHandler(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
func transform(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	// Get the query parameters from the request URL
 | 
			
		||||
	path := r.URL.EscapedPath()
 | 
			
		||||
	parm := strings.Split(path, "/")
 | 
			
		||||
| 
						 | 
				
			
			@ -43,81 +45,92 @@ func resizeHandler(w http.ResponseWriter, r *http.Request) {
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer resp.Body.Close()
 | 
			
		||||
	// Ensure that a valid response was given
 | 
			
		||||
	if resp.StatusCode/100 != 2 {
 | 
			
		||||
		writeError(w, imgPath, method, fmt.Sprintf("failed to fetch image (%v)", resp.StatusCode), http.StatusBadRequest)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	buf := []byte{}
 | 
			
		||||
	errMsg := ""
 | 
			
		||||
	errCode := 200
 | 
			
		||||
 | 
			
		||||
	switch method {
 | 
			
		||||
	case "resize":
 | 
			
		||||
		allowed := strings.Split(*sizesFilter, ",")
 | 
			
		||||
		forbidden := true
 | 
			
		||||
		if allowed[0] == "*" {
 | 
			
		||||
			forbidden = false
 | 
			
		||||
		} else {
 | 
			
		||||
			for _, v := range allowed {
 | 
			
		||||
				if args == v {
 | 
			
		||||
					forbidden = false
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if forbidden {
 | 
			
		||||
			writeError(w, imgPath, method, "size is not allowed", http.StatusForbidden)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		size := strings.Split(args, "x")
 | 
			
		||||
		if len(size) < 2 {
 | 
			
		||||
			writeError(w, imgPath, method, "url, width, and height are required", http.StatusBadRequest)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		width := size[0]
 | 
			
		||||
		height := size[1]
 | 
			
		||||
 | 
			
		||||
		// Validate that all three required fields are present
 | 
			
		||||
		if imgPath == "" || width == "" || height == "" {
 | 
			
		||||
			writeError(w, imgPath, method, "url, width, and height are required", http.StatusBadRequest)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Convert width and height to integers
 | 
			
		||||
		iw, errW := strconv.Atoi(width)
 | 
			
		||||
		ih, errH := strconv.Atoi(height)
 | 
			
		||||
		if errW != nil || errH != nil {
 | 
			
		||||
			writeError(w, imgPath, method, "width and height must be integers", http.StatusBadRequest)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Ensure that a valid response was given
 | 
			
		||||
		if resp.StatusCode/100 != 2 {
 | 
			
		||||
			writeError(w, imgPath, method, fmt.Sprintf("failed to fetch image (%v)", resp.StatusCode), http.StatusBadRequest)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Read from response body, convert and write to output buffer
 | 
			
		||||
		img, err := vips.NewImageFromReader(resp.Body)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			writeError(w, imgPath, method, fmt.Sprintf("%v", err), http.StatusInternalServerError)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		err = img.Thumbnail(iw, ih, 0)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			writeError(w, imgPath, method, fmt.Sprintf("%v", err), http.StatusInternalServerError)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		ep := vips.NewDefaultExportParams() // default export params are sufficient
 | 
			
		||||
		buf, _, _ := img.Export(ep)
 | 
			
		||||
		_, err = w.Write(buf)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			writeError(w, imgPath, method, fmt.Sprintf("%v", err), http.StatusInternalServerError)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	
 | 
			
		||||
	case "pass":
 | 
			
		||||
		break
 | 
			
		||||
		
 | 
			
		||||
	case "resize":
 | 
			
		||||
		buf, errMsg, errCode = doResize(resp.Body, args)
 | 
			
		||||
		if buf == nil {
 | 
			
		||||
			writeError(w, imgPath, method, errMsg, errCode)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	case "thumbnail":
 | 
			
		||||
		break
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		writeError(w, imgPath, method, "unknown method", http.StatusBadRequest)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err = w.Write(buf)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		writeError(w, imgPath, method, fmt.Sprintf("%v", err), http.StatusInternalServerError)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func doResize(body io.ReadCloser, args string) ([]byte, string, int) {
 | 
			
		||||
	allowed := strings.Split(*sizesFilter, ",")
 | 
			
		||||
	forbidden := true
 | 
			
		||||
	if allowed[0] == "*" {
 | 
			
		||||
		forbidden = false
 | 
			
		||||
	} else {
 | 
			
		||||
		for _, v := range allowed {
 | 
			
		||||
			if args == v {
 | 
			
		||||
				forbidden = false
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if forbidden {
 | 
			
		||||
		return nil, "size is not allowed", http.StatusForbidden
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size := strings.Split(args, "x")
 | 
			
		||||
	if len(size) < 2 {
 | 
			
		||||
		return nil, "width and height are required", http.StatusBadRequest
 | 
			
		||||
	}
 | 
			
		||||
	width := size[0]
 | 
			
		||||
	height := size[1]
 | 
			
		||||
 | 
			
		||||
	// Validate that all three required fields are present
 | 
			
		||||
	if width == "" || height == "" {
 | 
			
		||||
		return nil, "width and height are required", http.StatusBadRequest
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Convert width and height to integers
 | 
			
		||||
	iw, errW := strconv.Atoi(width)
 | 
			
		||||
	ih, errH := strconv.Atoi(height)
 | 
			
		||||
	if errW != nil || errH != nil {
 | 
			
		||||
		return nil, "width and height must be integers", http.StatusBadRequest
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Read from response body, convert and write to output buffer
 | 
			
		||||
	img, err := vips.NewImageFromReader(body)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Sprintf("%v", err), http.StatusInternalServerError
 | 
			
		||||
	}
 | 
			
		||||
	err = img.Thumbnail(iw, ih, 0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Sprintf("%v", err), http.StatusInternalServerError
 | 
			
		||||
	}
 | 
			
		||||
	ep := vips.NewDefaultExportParams() // default export params are sufficient
 | 
			
		||||
	buf, _, _ := img.Export(ep)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Sprintf("%v", err), http.StatusInternalServerError
 | 
			
		||||
	}
 | 
			
		||||
	return buf, "", 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeError(w http.ResponseWriter, imgPath, method, err string, status int) {
 | 
			
		||||
| 
						 | 
				
			
			@ -130,6 +143,6 @@ func main() {
 | 
			
		|||
	vips.Startup(nil)
 | 
			
		||||
	defer vips.Shutdown()
 | 
			
		||||
 | 
			
		||||
	http.HandleFunc("/", resizeHandler)
 | 
			
		||||
	http.HandleFunc("/", transform)
 | 
			
		||||
	log.Fatal(http.ListenAndServe(*listenAddr, nil))
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue