mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-01-03 10:43:58 +02:00
282 lines
7.3 KiB
Go
282 lines
7.3 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/imgproxy/imgproxy/v2/config"
|
|
"github.com/imgproxy/imgproxy/v2/imagemeta"
|
|
"github.com/imgproxy/imgproxy/v2/imagetype"
|
|
"github.com/imgproxy/imgproxy/v2/router"
|
|
"github.com/imgproxy/imgproxy/v2/vips"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/suite"
|
|
)
|
|
|
|
type ProcessingHandlerTestSuite struct {
|
|
suite.Suite
|
|
|
|
router *router.Router
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) SetupSuite() {
|
|
config.Reset()
|
|
|
|
wd, err := os.Getwd()
|
|
assert.Nil(s.T(), err)
|
|
|
|
config.LocalFileSystemRoot = filepath.Join(wd, "/testdata")
|
|
|
|
logrus.SetOutput(ioutil.Discard)
|
|
|
|
initialize()
|
|
|
|
s.router = buildRouter()
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TeardownSuite() {
|
|
shutdown()
|
|
logrus.SetOutput(os.Stdout)
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) SetupTest() {
|
|
// We don't need config.LocalFileSystemRoot anymore as it is used
|
|
// only during initialization
|
|
config.Reset()
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) send(path string, header ...http.Header) *httptest.ResponseRecorder {
|
|
req := httptest.NewRequest(http.MethodGet, path, nil)
|
|
rw := httptest.NewRecorder()
|
|
|
|
if len(header) > 0 {
|
|
req.Header = header[0]
|
|
}
|
|
|
|
s.router.ServeHTTP(rw, req)
|
|
|
|
return rw
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) readTestFile(name string) []byte {
|
|
wd, err := os.Getwd()
|
|
assert.Nil(s.T(), err)
|
|
|
|
data, err := ioutil.ReadFile(filepath.Join(wd, "testdata", name))
|
|
assert.Nil(s.T(), err)
|
|
|
|
return data
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) readBody(res *http.Response) []byte {
|
|
data, err := ioutil.ReadAll(res.Body)
|
|
assert.Nil(s.T(), err)
|
|
return data
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestRequest() {
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/local:///test1.png")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 200, res.StatusCode)
|
|
assert.Equal(s.T(), "image/png", res.Header.Get("Content-Type"))
|
|
|
|
meta, err := imagemeta.DecodeMeta(res.Body)
|
|
|
|
assert.Nil(s.T(), err)
|
|
assert.Equal(s.T(), imagetype.PNG, meta.Format())
|
|
assert.Equal(s.T(), 4, meta.Width())
|
|
assert.Equal(s.T(), 4, meta.Height())
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestSignatureValidationFailure() {
|
|
config.Keys = [][]byte{[]byte("test-key")}
|
|
config.Salts = [][]byte{[]byte("test-salt")}
|
|
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/local:///test1.png")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 403, res.StatusCode)
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestSignatureValidationSuccess() {
|
|
config.Keys = [][]byte{[]byte("test-key")}
|
|
config.Salts = [][]byte{[]byte("test-salt")}
|
|
|
|
rw := s.send("/My9d3xq_PYpVHsPrCyww0Kh1w5KZeZhIlWhsa4az1TI/rs:fill:4:4/plain/local:///test1.png")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 200, res.StatusCode)
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestSourceValidationFailure() {
|
|
config.AllowedSources = []string{"https://"}
|
|
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/local:///test1.png")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 404, res.StatusCode)
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestSourceValidationSuccess() {
|
|
config.AllowedSources = []string{"local:///"}
|
|
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/local:///test1.png")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 200, res.StatusCode)
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestSourceFormatNotSupported() {
|
|
vips.DisableLoadSupport(imagetype.PNG)
|
|
defer vips.ResetLoadSupport()
|
|
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/local:///test1.png")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 422, res.StatusCode)
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestResultingFormatNotSupported() {
|
|
vips.DisableSaveSupport(imagetype.PNG)
|
|
defer vips.ResetSaveSupport()
|
|
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/local:///test1.png@png")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 422, res.StatusCode)
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestSkipProcessingConfig() {
|
|
config.SkipProcessingFormats = []imagetype.Type{imagetype.PNG}
|
|
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/local:///test1.png")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 200, res.StatusCode)
|
|
|
|
actual := s.readBody(res)
|
|
expected := s.readTestFile("test1.png")
|
|
|
|
assert.True(s.T(), bytes.Equal(expected, actual))
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestSkipProcessingPO() {
|
|
rw := s.send("/unsafe/rs:fill:4:4/skp:png/plain/local:///test1.png")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 200, res.StatusCode)
|
|
|
|
actual := s.readBody(res)
|
|
expected := s.readTestFile("test1.png")
|
|
|
|
assert.True(s.T(), bytes.Equal(expected, actual))
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestSkipProcessingSameFormat() {
|
|
config.SkipProcessingFormats = []imagetype.Type{imagetype.PNG}
|
|
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/local:///test1.png@png")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 200, res.StatusCode)
|
|
|
|
actual := s.readBody(res)
|
|
expected := s.readTestFile("test1.png")
|
|
|
|
assert.True(s.T(), bytes.Equal(expected, actual))
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestSkipProcessingDifferentFormat() {
|
|
config.SkipProcessingFormats = []imagetype.Type{imagetype.PNG}
|
|
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/local:///test1.png@jpg")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 200, res.StatusCode)
|
|
|
|
actual := s.readBody(res)
|
|
expected := s.readTestFile("test1.png")
|
|
|
|
assert.False(s.T(), bytes.Equal(expected, actual))
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestSkipProcessingSVG() {
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/local:///test1.svg")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 200, res.StatusCode)
|
|
|
|
actual := s.readBody(res)
|
|
expected := s.readTestFile("test1.svg")
|
|
|
|
assert.True(s.T(), bytes.Equal(expected, actual))
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestNotSkipProcessingSVGToJPG() {
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/local:///test1.svg@jpg")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 200, res.StatusCode)
|
|
|
|
actual := s.readBody(res)
|
|
expected := s.readTestFile("test1.svg")
|
|
|
|
assert.False(s.T(), bytes.Equal(expected, actual))
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestErrorSavingToSVG() {
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/local:///test1.png@svg")
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), 422, res.StatusCode)
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestCacheControlPassthrough() {
|
|
config.CacheControlPassthrough = true
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
|
data := s.readTestFile("test1.png")
|
|
rw.Header().Set("Cache-Control", "fake-cache-control")
|
|
rw.Header().Set("Expires", "fake-expires")
|
|
rw.WriteHeader(200)
|
|
rw.Write(data)
|
|
}))
|
|
defer ts.Close()
|
|
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/" + ts.URL)
|
|
res := rw.Result()
|
|
|
|
assert.Equal(s.T(), "fake-cache-control", res.Header.Get("Cache-Control"))
|
|
assert.Equal(s.T(), "fake-expires", res.Header.Get("Expires"))
|
|
}
|
|
|
|
func (s *ProcessingHandlerTestSuite) TestCacheControlPassthroughDisabled() {
|
|
config.CacheControlPassthrough = false
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
|
data := s.readTestFile("test1.png")
|
|
rw.Header().Set("Cache-Control", "fake-cache-control")
|
|
rw.Header().Set("Expires", "fake-expires")
|
|
rw.WriteHeader(200)
|
|
rw.Write(data)
|
|
}))
|
|
defer ts.Close()
|
|
|
|
rw := s.send("/unsafe/rs:fill:4:4/plain/" + ts.URL)
|
|
res := rw.Result()
|
|
|
|
assert.NotEqual(s.T(), "fake-cache-control", res.Header.Get("Cache-Control"))
|
|
assert.NotEqual(s.T(), "fake-expires", res.Header.Get("Expires"))
|
|
}
|
|
|
|
func TestProcessingHandler(t *testing.T) {
|
|
suite.Run(t, new(ProcessingHandlerTestSuite))
|
|
}
|