ソースを参照

processing.Result

Viktor Sokolov 2 ヶ月 前
コミット
453bcc5ddd
4 ファイル変更92 行追加77 行削除
  1. 5 0
      httpheaders/headers.go
  2. 19 19
      processing/processing.go
  3. 43 43
      processing/processing_test.go
  4. 25 15
      processing_handler.go

+ 5 - 0
httpheaders/headers.go

@@ -61,4 +61,9 @@ const (
 	XForwardedHost                  = "X-Forwarded-Host"
 	XForwardedProto                 = "X-Forwarded-Proto"
 	XFrameOptions                   = "X-Frame-Options"
+	XOriginWidth                    = "X-Origin-Width"
+	XOriginHeight                   = "X-Origin-Height"
+	XResultWidth                    = "X-Result-Width"
+	XResultHeight                   = "X-Result-Height"
+	XOriginContentLength            = "X-Origin-Content-Length"
 )

+ 19 - 19
processing/processing.go

@@ -247,14 +247,15 @@ func saveImageToFitBytes(ctx context.Context, po *options.ProcessingOptions, img
 	}
 }
 
-type Meta struct {
+type Result struct {
+	OutData      imagedata.ImageData
 	OriginWidth  int
 	OriginHeight int
 	ResultWidth  int
 	ResultHeight int
 }
 
-func ProcessImage(ctx context.Context, imgdata imagedata.ImageData, po *options.ProcessingOptions) (imagedata.ImageData, *Meta, error) {
+func ProcessImage(ctx context.Context, imgdata imagedata.ImageData, po *options.ProcessingOptions) (*Result, error) {
 	runtime.LockOSThread()
 	defer runtime.UnlockOSThread()
 
@@ -278,12 +279,12 @@ func ProcessImage(ctx context.Context, imgdata imagedata.ImageData, po *options.
 			log.Debugf("Can't load thumbnail: %s", err)
 			// Failed to load thumbnail, rollback to the full image
 			if err := img.Load(imgdata, 1, 1.0, pages); err != nil {
-				return nil, nil, err
+				return nil, err
 			}
 		}
 	} else {
 		if err := img.Load(imgdata, 1, 1.0, pages); err != nil {
-			return nil, nil, err
+			return nil, err
 		}
 	}
 
@@ -315,29 +316,29 @@ func ProcessImage(ctx context.Context, imgdata imagedata.ImageData, po *options.
 	}
 
 	if !vips.SupportsSave(po.Format) {
-		return nil, nil, newSaveFormatError(po.Format)
+		return nil, newSaveFormatError(po.Format)
 	}
 
 	if po.Format.SupportsAnimationSave() && animated {
 		if err := transformAnimated(ctx, img, po, imgdata); err != nil {
-			return nil, nil, err
+			return nil, err
 		}
 	} else {
 		if animated {
 			// We loaded animated image but the resulting format doesn't support
 			// animations, so we need to reload image as not animated
 			if err := img.Load(imgdata, 1, 1.0, 1); err != nil {
-				return nil, nil, err
+				return nil, err
 			}
 		}
 
 		if err := mainPipeline.Run(ctx, img, po, imgdata); err != nil {
-			return nil, nil, err
+			return nil, err
 		}
 	}
 
 	if err := finalizePipeline.Run(ctx, img, po, imgdata); err != nil {
-		return nil, nil, err
+		return nil, err
 	}
 
 	if po.Format == imagetype.AVIF && (img.Width() < 16 || img.Height() < 16) {
@@ -364,16 +365,15 @@ func ProcessImage(ctx context.Context, imgdata imagedata.ImageData, po *options.
 		outData, err = img.Save(po.Format, po.GetQuality())
 	}
 
-	var m *Meta
-
-	if err == nil {
-		m = &Meta{
-			OriginWidth:  originWidth,
-			OriginHeight: originHeight,
-			ResultWidth:  img.Width(),
-			ResultHeight: img.Height(),
-		}
+	if err != nil {
+		return nil, err
 	}
 
-	return outData, m, err
+	return &Result{
+		OutData:      outData,
+		OriginWidth:  originWidth,
+		OriginHeight: originHeight,
+		ResultWidth:  img.Width(),
+		ResultHeight: img.Height(),
+	}, nil
 }

+ 43 - 43
processing/processing_test.go

@@ -49,10 +49,10 @@ func (s *ProcessingTestSuite) openFile(name string) imagedata.ImageData {
 	return imagedata
 }
 
-func (s *ProcessingTestSuite) checkSize(m *Meta, width, height int) {
-	s.Require().NotNil(m)
-	s.Require().Equal(width, m.ResultWidth, "Width mismatch")
-	s.Require().Equal(height, m.ResultHeight, "Height mismatch")
+func (s *ProcessingTestSuite) checkSize(r *Result, width, height int) {
+	s.Require().NotNil(r)
+	s.Require().Equal(width, r.ResultWidth, "Width mismatch")
+	s.Require().Equal(height, r.ResultHeight, "Height mismatch")
 }
 
 func (s *ProcessingTestSuite) TestResizeToFit() {
@@ -84,11 +84,11 @@ func (s *ProcessingTestSuite) TestResizeToFit() {
 			po.Width = tc.width
 			po.Height = tc.height
 
-			outImgdata, m, err := ProcessImage(context.Background(), imgdata, po)
+			result, err := ProcessImage(context.Background(), imgdata, po)
 			s.Require().NoError(err)
-			s.Require().NotNil(outImgdata)
+			s.Require().NotNil(result)
 
-			s.checkSize(m, tc.outWidth, tc.outHeight)
+			s.checkSize(result, tc.outWidth, tc.outHeight)
 		})
 	}
 }
@@ -123,11 +123,11 @@ func (s *ProcessingTestSuite) TestResizeToFitEnlarge() {
 			po.Width = tc.width
 			po.Height = tc.height
 
-			outImgdata, m, err := ProcessImage(context.Background(), imgdata, po)
+			result, err := ProcessImage(context.Background(), imgdata, po)
 			s.Require().NoError(err)
-			s.Require().NotNil(outImgdata)
+			s.Require().NotNil(result)
 
-			s.checkSize(m, tc.outWidth, tc.outHeight)
+			s.checkSize(result, tc.outWidth, tc.outHeight)
 		})
 	}
 }
@@ -167,11 +167,11 @@ func (s *ProcessingTestSuite) TestResizeToFitExtend() {
 			po.Width = tc.width
 			po.Height = tc.height
 
-			outImgdata, m, err := ProcessImage(context.Background(), imgdata, po)
+			result, err := ProcessImage(context.Background(), imgdata, po)
 			s.Require().NoError(err)
-			s.Require().NotNil(outImgdata)
+			s.Require().NotNil(result)
 
-			s.checkSize(m, tc.outWidth, tc.outHeight)
+			s.checkSize(result, tc.outWidth, tc.outHeight)
 		})
 	}
 }
@@ -211,11 +211,11 @@ func (s *ProcessingTestSuite) TestResizeToFitExtendAR() {
 			po.Width = tc.width
 			po.Height = tc.height
 
-			outImgdata, m, err := ProcessImage(context.Background(), imgdata, po)
+			result, err := ProcessImage(context.Background(), imgdata, po)
 			s.Require().NoError(err)
-			s.Require().NotNil(outImgdata)
+			s.Require().NotNil(result)
 
-			s.checkSize(m, tc.outWidth, tc.outHeight)
+			s.checkSize(result, tc.outWidth, tc.outHeight)
 		})
 	}
 }
@@ -249,11 +249,11 @@ func (s *ProcessingTestSuite) TestResizeToFill() {
 			po.Width = tc.width
 			po.Height = tc.height
 
-			outImgdata, m, err := ProcessImage(context.Background(), imgdata, po)
+			result, err := ProcessImage(context.Background(), imgdata, po)
 			s.Require().NoError(err)
-			s.Require().NotNil(outImgdata)
+			s.Require().NotNil(result)
 
-			s.checkSize(m, tc.outWidth, tc.outHeight)
+			s.checkSize(result, tc.outWidth, tc.outHeight)
 		})
 	}
 }
@@ -288,11 +288,11 @@ func (s *ProcessingTestSuite) TestResizeToFillEnlarge() {
 			po.Width = tc.width
 			po.Height = tc.height
 
-			outImgdata, m, err := ProcessImage(context.Background(), imgdata, po)
+			result, err := ProcessImage(context.Background(), imgdata, po)
 			s.Require().NoError(err)
-			s.Require().NotNil(outImgdata)
+			s.Require().NotNil(result)
 
-			s.checkSize(m, tc.outWidth, tc.outHeight)
+			s.checkSize(result, tc.outWidth, tc.outHeight)
 		})
 	}
 }
@@ -334,11 +334,11 @@ func (s *ProcessingTestSuite) TestResizeToFillExtend() {
 			po.Width = tc.width
 			po.Height = tc.height
 
-			outImgdata, m, err := ProcessImage(context.Background(), imgdata, po)
+			result, err := ProcessImage(context.Background(), imgdata, po)
 			s.Require().NoError(err)
-			s.Require().NotNil(outImgdata)
+			s.Require().NotNil(result)
 
-			s.checkSize(m, tc.outWidth, tc.outHeight)
+			s.checkSize(result, tc.outWidth, tc.outHeight)
 		})
 	}
 }
@@ -380,11 +380,11 @@ func (s *ProcessingTestSuite) TestResizeToFillExtendAR() {
 			po.Width = tc.width
 			po.Height = tc.height
 
-			outImgdata, m, err := ProcessImage(context.Background(), imgdata, po)
+			result, err := ProcessImage(context.Background(), imgdata, po)
 			s.Require().NoError(err)
-			s.Require().NotNil(outImgdata)
+			s.Require().NotNil(result)
 
-			s.checkSize(m, tc.outWidth, tc.outHeight)
+			s.checkSize(result, tc.outWidth, tc.outHeight)
 		})
 	}
 }
@@ -418,11 +418,11 @@ func (s *ProcessingTestSuite) TestResizeToFillDown() {
 			po.Width = tc.width
 			po.Height = tc.height
 
-			outImgdata, m, err := ProcessImage(context.Background(), imgdata, po)
+			result, err := ProcessImage(context.Background(), imgdata, po)
 			s.Require().NoError(err)
-			s.Require().NotNil(outImgdata)
+			s.Require().NotNil(result)
 
-			s.checkSize(m, tc.outWidth, tc.outHeight)
+			s.checkSize(result, tc.outWidth, tc.outHeight)
 		})
 	}
 }
@@ -457,11 +457,11 @@ func (s *ProcessingTestSuite) TestResizeToFillDownEnlarge() {
 			po.Width = tc.width
 			po.Height = tc.height
 
-			outImgdata, m, err := ProcessImage(context.Background(), imgdata, po)
+			result, err := ProcessImage(context.Background(), imgdata, po)
 			s.Require().NoError(err)
-			s.Require().NotNil(outImgdata)
+			s.Require().NotNil(result)
 
-			s.checkSize(m, tc.outWidth, tc.outHeight)
+			s.checkSize(result, tc.outWidth, tc.outHeight)
 		})
 	}
 }
@@ -503,11 +503,11 @@ func (s *ProcessingTestSuite) TestResizeToFillDownExtend() {
 			po.Width = tc.width
 			po.Height = tc.height
 
-			outImgdata, m, err := ProcessImage(context.Background(), imgdata, po)
+			result, err := ProcessImage(context.Background(), imgdata, po)
 			s.Require().NoError(err)
-			s.Require().NotNil(outImgdata)
+			s.Require().NotNil(result)
 
-			s.checkSize(m, tc.outWidth, tc.outHeight)
+			s.checkSize(result, tc.outWidth, tc.outHeight)
 		})
 	}
 }
@@ -547,11 +547,11 @@ func (s *ProcessingTestSuite) TestResizeToFillDownExtendAR() {
 			po.Width = tc.width
 			po.Height = tc.height
 
-			outImgdata, m, err := ProcessImage(context.Background(), imgdata, po)
+			result, err := ProcessImage(context.Background(), imgdata, po)
 			s.Require().NoError(err)
-			s.Require().NotNil(outImgdata)
+			s.Require().NotNil(result)
 
-			s.checkSize(m, tc.outWidth, tc.outHeight)
+			s.checkSize(result, tc.outWidth, tc.outHeight)
 		})
 	}
 }
@@ -976,12 +976,12 @@ func (s *ProcessingTestSuite) TestResultSizeLimit() {
 			po.Rotate = tc.rotate
 			po.Padding = tc.padding
 
-			outImgdata, m, err := ProcessImage(context.Background(), imgdata, po)
+			result, err := ProcessImage(context.Background(), imgdata, po)
 
 			s.Require().NoError(err)
-			s.Require().NotNil(outImgdata)
+			s.Require().NotNil(result)
 
-			s.checkSize(m, tc.outWidth, tc.outHeight)
+			s.checkSize(result, tc.outWidth, tc.outHeight)
 		})
 	}
 }

+ 25 - 15
processing_handler.go

@@ -125,8 +125,8 @@ func setCanonical(rw http.ResponseWriter, originURL string) {
 	}
 }
 
-func writeDebugHeaders(ctx context.Context, rw http.ResponseWriter, originData imagedata.ImageData, meta *processing.Meta) {
-	if !config.EnableDebugHeaders || meta == nil {
+func writeOriginContentLengthDebugHeader(ctx context.Context, rw http.ResponseWriter, originData imagedata.ImageData) {
+	if !config.EnableDebugHeaders {
 		return
 	}
 
@@ -135,11 +135,18 @@ func writeDebugHeaders(ctx context.Context, rw http.ResponseWriter, originData i
 		checkErr(ctx, "image_data_size", err)
 	}
 
-	rw.Header().Set("X-Origin-Content-Length", strconv.Itoa(size))
-	rw.Header().Set("X-Origin-Width", strconv.Itoa(meta.OriginWidth))
-	rw.Header().Set("X-Origin-Height", strconv.Itoa(meta.OriginHeight))
-	rw.Header().Set("X-Result-Width", strconv.Itoa(meta.ResultWidth))
-	rw.Header().Set("X-Result-Height", strconv.Itoa(meta.ResultHeight))
+	rw.Header().Set(httpheaders.XOriginContentLength, strconv.Itoa(size))
+}
+
+func writeDebugHeaders(rw http.ResponseWriter, result *processing.Result) {
+	if !config.EnableDebugHeaders || result == nil {
+		return
+	}
+
+	rw.Header().Set(httpheaders.XOriginWidth, strconv.Itoa(result.OriginWidth))
+	rw.Header().Set(httpheaders.XOriginHeight, strconv.Itoa(result.OriginHeight))
+	rw.Header().Set(httpheaders.XResultWidth, strconv.Itoa(result.ResultWidth))
+	rw.Header().Set(httpheaders.XResultHeight, strconv.Itoa(result.ResultHeight))
 }
 
 func respondWithImage(reqID string, r *http.Request, rw http.ResponseWriter, statusCode int, resultData imagedata.ImageData, po *options.ProcessingOptions, originURL string, originData imagedata.ImageData, originHeaders http.Header) {
@@ -150,22 +157,22 @@ func respondWithImage(reqID string, r *http.Request, rw http.ResponseWriter, sta
 		contentDisposition = resultData.Format().ContentDispositionFromURL(originURL, po.ReturnAttachment)
 	}
 
-	rw.Header().Set("Content-Type", resultData.Format().Mime())
-	rw.Header().Set("Content-Disposition", contentDisposition)
+	rw.Header().Set(httpheaders.ContentType, resultData.Format().Mime())
+	rw.Header().Set(httpheaders.ContentDisposition, contentDisposition)
 
 	setCacheControl(rw, po.Expires, originHeaders)
 	setLastModified(rw, originHeaders)
 	setVary(rw)
 	setCanonical(rw, originURL)
 
-	rw.Header().Set("Content-Security-Policy", "script-src 'none'")
+	rw.Header().Set(httpheaders.ContentSecurityPolicy, "script-src 'none'")
 
 	resultSize, err := resultData.Size()
 	if err != nil {
 		checkErr(r.Context(), "image_data_size", err)
 	}
 
-	rw.Header().Set("Content-Length", strconv.Itoa(resultSize))
+	rw.Header().Set(httpheaders.ContentLength, strconv.Itoa(resultSize))
 	rw.WriteHeader(statusCode)
 
 	_, err = io.Copy(rw, resultData.Reader())
@@ -453,10 +460,12 @@ func handleProcessing(reqID string, rw http.ResponseWriter, r *http.Request) {
 
 			defer sanitized.Close()
 
+			writeOriginContentLengthDebugHeader(ctx, rw, originData)
 			respondWithImage(reqID, r, rw, statusCode, sanitized, po, imageURL, originData, originHeaders)
 			return
 		}
 
+		writeOriginContentLengthDebugHeader(ctx, rw, originData)
 		respondWithImage(reqID, r, rw, statusCode, originData, po, imageURL, originData, originHeaders)
 		return
 	}
@@ -476,7 +485,7 @@ func handleProcessing(reqID string, rw http.ResponseWriter, r *http.Request) {
 		))
 	}
 
-	resultData, meta, err := func() (imagedata.ImageData, *processing.Meta, error) {
+	result, err := func() (*processing.Result, error) {
 		defer metrics.StartProcessingSegment(ctx, metrics.Meta{
 			metrics.MetaProcessingOptions: metricsMeta[metrics.MetaProcessingOptions],
 		})()
@@ -484,11 +493,12 @@ func handleProcessing(reqID string, rw http.ResponseWriter, r *http.Request) {
 	}()
 	checkErr(ctx, "processing", err)
 
-	defer resultData.Close()
+	defer result.OutData.Close()
 
 	checkErr(ctx, "timeout", router.CheckTimeout(ctx))
 
-	writeDebugHeaders(r.Context(), rw, originData, meta)
+	writeDebugHeaders(rw, result)
+	writeOriginContentLengthDebugHeader(ctx, rw, originData)
 
-	respondWithImage(reqID, r, rw, statusCode, resultData, po, imageURL, originData, originHeaders)
+	respondWithImage(reqID, r, rw, statusCode, result.OutData, po, imageURL, originData, originHeaders)
 }