mirror of
https://github.com/imgproxy/imgproxy.git
synced 2024-11-24 08:12:38 +02:00
Implement fallback images in a similar fashion to watermarks. (#374)
* 220. Implement fallback images in a similar fashion to watermarks. * 220. Fix error formatting. * 220. Fixes based on @darthsim's feedback.
This commit is contained in:
parent
cf6f481d83
commit
21b990d895
@ -224,6 +224,10 @@ type config struct {
|
||||
WatermarkURL string
|
||||
WatermarkOpacity float64
|
||||
|
||||
FallbackImageData string
|
||||
FallbackImagePath string
|
||||
FallbackImageURL string
|
||||
|
||||
NewRelicAppName string
|
||||
NewRelicKey string
|
||||
|
||||
@ -377,6 +381,10 @@ func configure() error {
|
||||
strEnvConfig(&conf.WatermarkURL, "IMGPROXY_WATERMARK_URL")
|
||||
floatEnvConfig(&conf.WatermarkOpacity, "IMGPROXY_WATERMARK_OPACITY")
|
||||
|
||||
strEnvConfig(&conf.FallbackImageData, "IMGPROXY_FALLBACK_IMAGE_DATA")
|
||||
strEnvConfig(&conf.FallbackImagePath, "IMGPROXY_FALLBACK_IMAGE_PATH")
|
||||
strEnvConfig(&conf.FallbackImageURL, "IMGPROXY_FALLBACK_IMAGE_URL")
|
||||
|
||||
strEnvConfig(&conf.NewRelicAppName, "IMGPROXY_NEW_RELIC_APP_NAME")
|
||||
strEnvConfig(&conf.NewRelicKey, "IMGPROXY_NEW_RELIC_KEY")
|
||||
|
||||
|
@ -9,35 +9,51 @@ import (
|
||||
|
||||
func getWatermarkData() (*imageData, error) {
|
||||
if len(conf.WatermarkData) > 0 {
|
||||
return base64WatermarkData(conf.WatermarkData)
|
||||
return base64ImageData(conf.WatermarkData)
|
||||
}
|
||||
|
||||
if len(conf.WatermarkPath) > 0 {
|
||||
return fileWatermarkData(conf.WatermarkPath)
|
||||
return fileImageData(conf.WatermarkPath)
|
||||
}
|
||||
|
||||
if len(conf.WatermarkURL) > 0 {
|
||||
return remoteWatermarkData(conf.WatermarkURL)
|
||||
return remoteImageData(conf.WatermarkURL)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func base64WatermarkData(encoded string) (*imageData, error) {
|
||||
func getFallbackImageData() (*imageData, error) {
|
||||
if len(conf.FallbackImageData) > 0 {
|
||||
return base64ImageData(conf.FallbackImageData)
|
||||
}
|
||||
|
||||
if len(conf.FallbackImagePath) > 0 {
|
||||
return fileImageData(conf.FallbackImagePath)
|
||||
}
|
||||
|
||||
if len(conf.FallbackImageURL) > 0 {
|
||||
return remoteImageData(conf.FallbackImageURL)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func base64ImageData(encoded string) (*imageData, error) {
|
||||
data, err := base64.StdEncoding.DecodeString(encoded)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Can't decode watermark data: %s", err)
|
||||
return nil, fmt.Errorf("Can't decode image data: %s", err)
|
||||
}
|
||||
|
||||
imgtype, err := checkTypeAndDimensions(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Can't decode watermark: %s", err)
|
||||
return nil, fmt.Errorf("Can't decode image: %s", err)
|
||||
}
|
||||
|
||||
return &imageData{Data: data, Type: imgtype}, nil
|
||||
}
|
||||
|
||||
func fileWatermarkData(path string) (*imageData, error) {
|
||||
func fileImageData(path string) (*imageData, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Can't read watermark: %s", err)
|
||||
@ -56,18 +72,18 @@ func fileWatermarkData(path string) (*imageData, error) {
|
||||
return imgdata, err
|
||||
}
|
||||
|
||||
func remoteWatermarkData(imageURL string) (*imageData, error) {
|
||||
func remoteImageData(imageURL string) (*imageData, error) {
|
||||
res, err := requestImage(imageURL)
|
||||
if res != nil {
|
||||
defer res.Body.Close()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Can't download watermark: %s", err)
|
||||
return nil, fmt.Errorf("Can't download image: %s", err)
|
||||
}
|
||||
|
||||
imgdata, err := readAndCheckImage(res.Body, int(res.ContentLength))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Can't download watermark: %s", err)
|
||||
return nil, fmt.Errorf("Can't download image: %s", err)
|
||||
}
|
||||
|
||||
return imgdata, err
|
@ -16,6 +16,7 @@ var (
|
||||
processingSem chan struct{}
|
||||
|
||||
headerVaryValue string
|
||||
fallback *imageData
|
||||
)
|
||||
|
||||
func initProcessingHandler() error {
|
||||
@ -45,6 +46,10 @@ func initProcessingHandler() error {
|
||||
|
||||
headerVaryValue = strings.Join(vary, ", ")
|
||||
|
||||
if err := loadFallback(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -153,7 +158,12 @@ func handleProcessing(reqID string, rw http.ResponseWriter, r *http.Request) {
|
||||
if prometheusEnabled {
|
||||
incrementPrometheusErrorsTotal("download")
|
||||
}
|
||||
panic(err)
|
||||
if fallback != nil {
|
||||
logError("Could not load image. Using fallback image: %s", err.Error())
|
||||
ctx = context.WithValue(ctx, imageDataCtxKey, fallback)
|
||||
} else {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
checkTimeout(ctx)
|
||||
@ -186,3 +196,11 @@ func handleProcessing(reqID string, rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
respondWithImage(ctx, reqID, r, rw, imageData)
|
||||
}
|
||||
|
||||
func loadFallback() (err error) {
|
||||
fallback, err = getFallbackImageData()
|
||||
if err != nil {
|
||||
logError("Could not load fallback data. Fallback images will not be available: %s", err.Error())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user