mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-09-28 20:43:54 +02:00
feat: Implement AlwaysRasterizeSvg (#1257)
Implement AlwaysRasterizeSvg Add sanitize to skip processing Add tests Refactoring skipProcessing
This commit is contained in:
@@ -93,7 +93,8 @@ var (
|
||||
AllowLinkLocalSourceAddresses bool
|
||||
AllowPrivateSourceAddresses bool
|
||||
|
||||
SanitizeSvg bool
|
||||
SanitizeSvg bool
|
||||
AlwaysRasterizeSvg bool
|
||||
|
||||
CookiePassthrough bool
|
||||
CookieBaseURL string
|
||||
@@ -288,6 +289,7 @@ func Reset() {
|
||||
AllowPrivateSourceAddresses = true
|
||||
|
||||
SanitizeSvg = true
|
||||
AlwaysRasterizeSvg = false
|
||||
|
||||
CookiePassthrough = false
|
||||
CookieBaseURL = ""
|
||||
@@ -429,6 +431,7 @@ func Configure() error {
|
||||
configurators.Bool(&AllowPrivateSourceAddresses, "IMGPROXY_ALLOW_PRIVATE_SOURCE_ADDRESSES")
|
||||
|
||||
configurators.Bool(&SanitizeSvg, "IMGPROXY_SANITIZE_SVG")
|
||||
configurators.Bool(&AlwaysRasterizeSvg, "IMGPROXY_ALWAYS_RASTERIZE_SVG")
|
||||
|
||||
configurators.Bool(&AllowSecurityOptions, "IMGPROXY_ALLOW_SECURITY_OPTIONS")
|
||||
|
||||
@@ -680,7 +683,6 @@ func Configure() error {
|
||||
|
||||
if LocalFileSystemRoot != "" {
|
||||
stat, err := os.Stat(LocalFileSystemRoot)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Cannot use local directory: %s", err)
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -372,32 +373,28 @@ func handleProcessing(reqID string, rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
checkErr(ctx, "timeout", router.CheckTimeout(ctx))
|
||||
|
||||
if originData.Type == po.Format || po.Format == imagetype.Unknown {
|
||||
// Don't process SVG
|
||||
if originData.Type == imagetype.SVG {
|
||||
if config.SanitizeSvg {
|
||||
sanitized, svgErr := svg.Sanitize(originData)
|
||||
checkErr(ctx, "svg_processing", svgErr)
|
||||
// Skip processing svg with unknown or the same destination imageType
|
||||
// if it's not forced by AlwaysRasterizeSvg option
|
||||
// Also skip processing if the format is in SkipProcessingFormats
|
||||
shouldSkipProcessing := (originData.Type == po.Format || po.Format == imagetype.Unknown) &&
|
||||
(slices.Contains(po.SkipProcessingFormats, originData.Type) ||
|
||||
originData.Type == imagetype.SVG && !config.AlwaysRasterizeSvg)
|
||||
|
||||
// Since we'll replace origin data, it's better to close it to return
|
||||
// it's buffer to the pool
|
||||
originData.Close()
|
||||
if shouldSkipProcessing {
|
||||
if originData.Type == imagetype.SVG && config.SanitizeSvg {
|
||||
sanitized, svgErr := svg.Sanitize(originData)
|
||||
checkErr(ctx, "svg_processing", svgErr)
|
||||
|
||||
originData = sanitized
|
||||
}
|
||||
// Since we'll replace origin data, it's better to close it to return
|
||||
// it's buffer to the pool
|
||||
originData.Close()
|
||||
|
||||
originData = sanitized
|
||||
|
||||
respondWithImage(reqID, r, rw, statusCode, originData, po, imageURL, originData)
|
||||
return
|
||||
}
|
||||
|
||||
if len(po.SkipProcessingFormats) > 0 {
|
||||
for _, f := range po.SkipProcessingFormats {
|
||||
if f == originData.Type {
|
||||
respondWithImage(reqID, r, rw, statusCode, originData, po, imageURL, originData)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
respondWithImage(reqID, r, rw, statusCode, originData, po, imageURL, originData)
|
||||
return
|
||||
}
|
||||
|
||||
if !vips.SupportsLoad(originData.Type) {
|
||||
|
@@ -608,7 +608,6 @@ func (s *ProcessingHandlerTestSuite) TestModifiedSinceReqExactMatchLastModifiedD
|
||||
require.Equal(s.T(), "", modifiedSince)
|
||||
rw.WriteHeader(200)
|
||||
rw.Write(data)
|
||||
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
@@ -619,6 +618,7 @@ func (s *ProcessingHandlerTestSuite) TestModifiedSinceReqExactMatchLastModifiedD
|
||||
|
||||
require.Equal(s.T(), 200, res.StatusCode)
|
||||
}
|
||||
|
||||
func (s *ProcessingHandlerTestSuite) TestModifiedSinceReqExactMatchLastModifiedEnabled() {
|
||||
config.LastModifiedEnabled = true
|
||||
lastModified := "Wed, 21 Oct 2015 07:28:00 GMT"
|
||||
@@ -657,6 +657,7 @@ func (s *ProcessingHandlerTestSuite) TestModifiedSinceReqCompareMoreRecentLastMo
|
||||
|
||||
require.Equal(s.T(), 200, res.StatusCode)
|
||||
}
|
||||
|
||||
func (s *ProcessingHandlerTestSuite) TestModifiedSinceReqCompareMoreRecentLastModifiedEnabled() {
|
||||
config.LastModifiedEnabled = true
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
@@ -678,6 +679,7 @@ func (s *ProcessingHandlerTestSuite) TestModifiedSinceReqCompareMoreRecentLastMo
|
||||
|
||||
require.Equal(s.T(), 304, res.StatusCode)
|
||||
}
|
||||
|
||||
func (s *ProcessingHandlerTestSuite) TestModifiedSinceReqCompareTooOldLastModifiedDisabled() {
|
||||
config.LastModifiedEnabled = false
|
||||
data := s.readTestFile("test1.png")
|
||||
@@ -698,6 +700,7 @@ func (s *ProcessingHandlerTestSuite) TestModifiedSinceReqCompareTooOldLastModifi
|
||||
|
||||
require.Equal(s.T(), 200, res.StatusCode)
|
||||
}
|
||||
|
||||
func (s *ProcessingHandlerTestSuite) TestModifiedSinceReqCompareTooOldLastModifiedEnabled() {
|
||||
config.LastModifiedEnabled = true
|
||||
data := s.readTestFile("test1.png")
|
||||
@@ -721,6 +724,49 @@ func (s *ProcessingHandlerTestSuite) TestModifiedSinceReqCompareTooOldLastModifi
|
||||
|
||||
require.Equal(s.T(), 200, res.StatusCode)
|
||||
}
|
||||
|
||||
func (s *ProcessingHandlerTestSuite) TestAlwaysRasterizeSvg() {
|
||||
config.AlwaysRasterizeSvg = true
|
||||
|
||||
rw := s.send("/unsafe/rs:fill:40:40/plain/local:///test1.svg")
|
||||
res := rw.Result()
|
||||
|
||||
require.Equal(s.T(), 200, res.StatusCode)
|
||||
require.Equal(s.T(), "image/png", res.Header.Get("Content-Type"))
|
||||
}
|
||||
|
||||
func (s *ProcessingHandlerTestSuite) TestAlwaysRasterizeSvgWithEnforceAvif() {
|
||||
config.AlwaysRasterizeSvg = true
|
||||
config.EnforceWebp = true
|
||||
|
||||
rw := s.send("/unsafe/plain/local:///test1.svg", http.Header{"Accept": []string{"image/webp"}})
|
||||
res := rw.Result()
|
||||
|
||||
require.Equal(s.T(), 200, res.StatusCode)
|
||||
require.Equal(s.T(), "image/webp", res.Header.Get("Content-Type"))
|
||||
}
|
||||
|
||||
func (s *ProcessingHandlerTestSuite) TestAlwaysRasterizeSvgDisabled() {
|
||||
config.AlwaysRasterizeSvg = false
|
||||
config.EnforceWebp = true
|
||||
|
||||
rw := s.send("/unsafe/plain/local:///test1.svg")
|
||||
res := rw.Result()
|
||||
|
||||
require.Equal(s.T(), 200, res.StatusCode)
|
||||
require.Equal(s.T(), "image/svg+xml", res.Header.Get("Content-Type"))
|
||||
}
|
||||
|
||||
func (s *ProcessingHandlerTestSuite) TestAlwaysRasterizeSvgWithFormat() {
|
||||
config.AlwaysRasterizeSvg = true
|
||||
config.SkipProcessingFormats = []imagetype.Type{imagetype.SVG}
|
||||
rw := s.send("/unsafe/plain/local:///test1.svg@svg")
|
||||
res := rw.Result()
|
||||
|
||||
require.Equal(s.T(), 200, res.StatusCode)
|
||||
require.Equal(s.T(), "image/svg+xml", res.Header.Get("Content-Type"))
|
||||
}
|
||||
|
||||
func TestProcessingHandler(t *testing.T) {
|
||||
suite.Run(t, new(ProcessingHandlerTestSuite))
|
||||
}
|
||||
|
Reference in New Issue
Block a user