Răsfoiți Sursa

transport.Common relies on config

Viktor Sokolov 1 săptămână în urmă
părinte
comite
cac952bfbe

Fișier diff suprimat deoarece este prea mare
+ 507 - 513
config/config.go


+ 5 - 4
fetcher/transport/azure/azure.go

@@ -22,10 +22,11 @@ import (
 )
 
 type transport struct {
-	client *azblob.Client
+	client      *azblob.Client
+	qsSeparator string
 }
 
-func New(config *Config, trans *http.Transport) (http.RoundTripper, error) {
+func New(config *Config, trans *http.Transport, sep string) (http.RoundTripper, error) {
 	if err := config.Validate(); err != nil {
 		return nil, err
 	}
@@ -73,11 +74,11 @@ func New(config *Config, trans *http.Transport) (http.RoundTripper, error) {
 		return nil, err
 	}
 
-	return transport{client}, nil
+	return transport{client, sep}, nil
 }
 
 func (t transport) RoundTrip(req *http.Request) (*http.Response, error) {
-	container, key, _ := common.GetBucketAndKey(req.URL)
+	container, key, _ := common.GetBucketAndKey(req.URL, t.qsSeparator)
 
 	if len(container) == 0 || len(key) == 0 {
 		body := strings.NewReader("Invalid ABS URL: container name or object key is empty")

+ 2 - 2
fetcher/transport/azure/azure_test.go

@@ -47,11 +47,11 @@ func (s *AzureTestSuite) SetupSuite() {
 	tc := generichttp.NewDefaultConfig()
 	tc.IgnoreSslVerification = true
 
-	trans, gerr := generichttp.New(false, &tc)
+	trans, gerr := generichttp.New(false, &tc, "?")
 	s.Require().NoError(gerr)
 
 	var err error
-	s.transport, err = New(&config, trans)
+	s.transport, err = New(&config, trans, "?")
 	s.Require().NoError(err)
 }
 

+ 3 - 5
fetcher/transport/common/common.go

@@ -3,8 +3,6 @@ package common
 import (
 	"net/url"
 	"strings"
-
-	"github.com/imgproxy/imgproxy/v3/config"
 )
 
 func EscapeURL(u string) string {
@@ -28,7 +26,7 @@ func EscapeURL(u string) string {
 	return u
 }
 
-func GetBucketAndKey(u *url.URL) (bucket, key, query string) {
+func GetBucketAndKey(u *url.URL, sep string) (bucket, key, query string) {
 	bucket = u.Host
 
 	// We can't use u.Path here because `url.Parse` unescapes the original URL's path.
@@ -60,8 +58,8 @@ func GetBucketAndKey(u *url.URL) (bucket, key, query string) {
 	// Since we replaced `?` with `%3F` in `EscapeURL`, `url.Parse` will treat query
 	// string as a part of the path.
 	// Also, query string separator may be different from `?`, so we can't rely on `url.URL.RawQuery`.
-	if len(config.SourceURLQuerySeparator) > 0 {
-		key, query, _ = strings.Cut(key, config.SourceURLQuerySeparator)
+	if len(sep) > 0 {
+		key, query, _ = strings.Cut(key, sep)
 	}
 
 	return

+ 28 - 14
fetcher/transport/config.go

@@ -4,6 +4,7 @@ package transport
 
 import (
 	"errors"
+	"os"
 
 	"github.com/imgproxy/imgproxy/v3/ensure"
 	"github.com/imgproxy/imgproxy/v3/env"
@@ -16,10 +17,11 @@ import (
 )
 
 var (
-	IMGPROXY_USE_ABS   = env.Describe("IMGPROXY_USE_ABS", "boolean")
-	IMGPROXY_USE_GCS   = env.Describe("IMGPROXY_GCS_ENABLED", "boolean")
-	IMGPROXY_USE_S3    = env.Describe("IMGPROXY_USE_S3", "boolean")
-	IMGPROXY_USE_SWIFT = env.Describe("IMGPROXY_USE_SWIFT", "boolean")
+	IMGPROXY_USE_ABS                    = env.Describe("IMGPROXY_USE_ABS", "boolean")
+	IMGPROXY_USE_GCS                    = env.Describe("IMGPROXY_GCS_ENABLED", "boolean")
+	IMGPROXY_USE_S3                     = env.Describe("IMGPROXY_USE_S3", "boolean")
+	IMGPROXY_USE_SWIFT                  = env.Describe("IMGPROXY_USE_SWIFT", "boolean")
+	IMGPROXY_SOURCE_URL_QUERY_SEPARATOR = env.Describe("IMGPROXY_SOURCE_URL_QUERY_SEPARATOR", "string")
 )
 
 // Config represents configuration of the transport package
@@ -39,21 +41,27 @@ type Config struct {
 
 	SwiftEnabled bool
 	Swift        swift.Config
+
+	// query string separator (see docs). Unfortunately, we'll have to pass this
+	// to each transport which needs it as the consturctor parameter. Otherwise,
+	// we would have to add it to each transport config struct.
+	SourceURLQuerySeparator string
 }
 
 // NewDefaultConfig returns a new default transport configuration
 func NewDefaultConfig() Config {
 	return Config{
-		HTTP:         generichttp.NewDefaultConfig(),
-		Local:        fs.NewDefaultConfig(),
-		ABSEnabled:   false,
-		ABS:          azure.NewDefaultConfig(),
-		GCSEnabled:   false,
-		GCS:          gcs.NewDefaultConfig(),
-		S3Enabled:    false,
-		S3:           s3.NewDefaultConfig(),
-		SwiftEnabled: false,
-		Swift:        swift.NewDefaultConfig(),
+		HTTP:                    generichttp.NewDefaultConfig(),
+		Local:                   fs.NewDefaultConfig(),
+		ABSEnabled:              false,
+		ABS:                     azure.NewDefaultConfig(),
+		GCSEnabled:              false,
+		GCS:                     gcs.NewDefaultConfig(),
+		S3Enabled:               false,
+		S3:                      s3.NewDefaultConfig(),
+		SwiftEnabled:            false,
+		Swift:                   swift.NewDefaultConfig(),
+		SourceURLQuerySeparator: "?", // default is ?, but can be overriden with empty
 	}
 }
 
@@ -81,6 +89,12 @@ func LoadConfigFromEnv(c *Config) (*Config, error) {
 		env.Bool(&c.SwiftEnabled, IMGPROXY_USE_SWIFT),
 	)
 
+	// empty value is a valid value for this separator, we can't rely on env.String,
+	// which skips empty values
+	if s, ok := os.LookupEnv(IMGPROXY_SOURCE_URL_QUERY_SEPARATOR.Name); ok {
+		c.SourceURLQuerySeparator = s
+	}
+
 	return c, err
 }
 

+ 5 - 4
fetcher/transport/fs/fs.go

@@ -20,21 +20,22 @@ import (
 )
 
 type transport struct {
-	fs http.Dir
+	fs          http.Dir
+	qsSeparator string
 }
 
-func New(config *Config) (transport, error) {
+func New(config *Config, sep string) (transport, error) {
 	if err := config.Validate(); err != nil {
 		return transport{}, err
 	}
 
-	return transport{fs: http.Dir(config.Root)}, nil
+	return transport{fs: http.Dir(config.Root), qsSeparator: sep}, nil
 }
 
 func (t transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
 	header := make(http.Header)
 
-	_, path, _ := common.GetBucketAndKey(req.URL)
+	_, path, _ := common.GetBucketAndKey(req.URL, t.qsSeparator)
 	path = "/" + path
 
 	f, err := t.fs.Open(path)

+ 1 - 1
fetcher/transport/fs/fs_test.go

@@ -31,7 +31,7 @@ func (s *FsTestSuite) SetupSuite() {
 
 	s.etag = BuildEtag("/test1.png", fi)
 	s.modTime = fi.ModTime()
-	s.transport, _ = New(&Config{Root: fsRoot})
+	s.transport, _ = New(&Config{Root: fsRoot}, "?")
 }
 
 func (s *FsTestSuite) TestRoundTripWithETagEnabled() {

+ 5 - 4
fetcher/transport/gcs/gcs.go

@@ -25,7 +25,8 @@ import (
 var noAuth bool = false
 
 type transport struct {
-	client *storage.Client
+	client      *storage.Client
+	qsSeparator string
 }
 
 func buildHTTPClient(config *Config, trans *http.Transport, opts ...option.ClientOption) (*http.Client, error) {
@@ -41,7 +42,7 @@ func buildHTTPClient(config *Config, trans *http.Transport, opts ...option.Clien
 	return &http.Client{Transport: htrans}, nil
 }
 
-func New(config *Config, trans *http.Transport) (http.RoundTripper, error) {
+func New(config *Config, trans *http.Transport, sep string) (http.RoundTripper, error) {
 	var client *storage.Client
 
 	opts := []option.ClientOption{
@@ -72,11 +73,11 @@ func New(config *Config, trans *http.Transport) (http.RoundTripper, error) {
 		return nil, ierrors.Wrap(err, 0, ierrors.WithPrefix("Can't create GCS client"))
 	}
 
-	return transport{client}, nil
+	return transport{client, sep}, nil
 }
 
 func (t transport) RoundTrip(req *http.Request) (*http.Response, error) {
-	bucket, key, query := common.GetBucketAndKey(req.URL)
+	bucket, key, query := common.GetBucketAndKey(req.URL, t.qsSeparator)
 
 	if len(bucket) == 0 || len(key) == 0 {
 		body := strings.NewReader("Invalid GCS URL: bucket name or object key is empty")

+ 2 - 2
fetcher/transport/gcs/gcs_test.go

@@ -74,10 +74,10 @@ func (s *GCSTestSuite) SetupSuite() {
 	tc := generichttp.NewDefaultConfig()
 	tc.IgnoreSslVerification = true
 
-	trans, gerr := generichttp.New(false, &tc)
+	trans, gerr := generichttp.New(false, &tc, "?")
 	s.Require().NoError(gerr)
 
-	s.transport, err = New(&config, trans)
+	s.transport, err = New(&config, trans, "?")
 	s.Require().NoError(err)
 }
 

+ 1 - 1
fetcher/transport/generichttp/generic_http.go

@@ -12,7 +12,7 @@ import (
 	"golang.org/x/net/http2"
 )
 
-func New(verifyNetworks bool, config *Config) (*http.Transport, error) {
+func New(verifyNetworks bool, config *Config, sep string) (*http.Transport, error) {
 	if err := config.Validate(); err != nil {
 		return nil, err
 	}

+ 5 - 3
fetcher/transport/s3/s3.go

@@ -41,10 +41,11 @@ type transport struct {
 
 	mu sync.RWMutex
 
-	config *Config
+	config      *Config
+	qsSeparator string
 }
 
-func New(config *Config, trans *http.Transport) (http.RoundTripper, error) {
+func New(config *Config, trans *http.Transport, sep string) (http.RoundTripper, error) {
 	if err := config.Validate(); err != nil {
 		return nil, err
 	}
@@ -102,11 +103,12 @@ func New(config *Config, trans *http.Transport) (http.RoundTripper, error) {
 		clientsByRegion: map[string]s3Client{conf.Region: client},
 		clientsByBucket: make(map[string]s3Client),
 		config:          config,
+		qsSeparator:     sep,
 	}, nil
 }
 
 func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
-	bucket, key, query := common.GetBucketAndKey(req.URL)
+	bucket, key, query := common.GetBucketAndKey(req.URL, t.qsSeparator)
 
 	if len(bucket) == 0 || len(key) == 0 {
 		body := strings.NewReader("Invalid S3 URL: bucket name or object key is empty")

+ 2 - 2
fetcher/transport/s3/s3_test.go

@@ -42,11 +42,11 @@ func (s *S3TestSuite) SetupSuite() {
 	tc := generichttp.NewDefaultConfig()
 	tc.IgnoreSslVerification = true
 
-	trans, gerr := generichttp.New(false, &tc)
+	trans, gerr := generichttp.New(false, &tc, "?")
 	s.Require().NoError(gerr)
 
 	var err error
-	s.transport, err = New(&config, trans)
+	s.transport, err = New(&config, trans, "?")
 	s.Require().NoError(err)
 
 	err = backend.CreateBucket("test")

+ 5 - 4
fetcher/transport/swift/swift.go

@@ -15,10 +15,11 @@ import (
 )
 
 type transport struct {
-	con *swift.Connection
+	con         *swift.Connection
+	qsSeparator string
 }
 
-func New(config *Config, trans *http.Transport) (http.RoundTripper, error) {
+func New(config *Config, trans *http.Transport, sep string) (http.RoundTripper, error) {
 	if err := config.Validate(); err != nil {
 		return nil, err
 	}
@@ -43,11 +44,11 @@ func New(config *Config, trans *http.Transport) (http.RoundTripper, error) {
 		return nil, ierrors.Wrap(err, 0, ierrors.WithPrefix("swift authentication error"))
 	}
 
-	return transport{con: c}, nil
+	return transport{con: c, qsSeparator: sep}, nil
 }
 
 func (t transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
-	container, objectName, _ := common.GetBucketAndKey(req.URL)
+	container, objectName, _ := common.GetBucketAndKey(req.URL, t.qsSeparator)
 
 	if len(container) == 0 || len(objectName) == 0 {
 		body := strings.NewReader("Invalid Swift URL: container name or object name is empty")

+ 2 - 2
fetcher/transport/swift/swift_test.go

@@ -41,11 +41,11 @@ func (s *SwiftTestSuite) SetupSuite() {
 	tc := generichttp.NewDefaultConfig()
 	tc.IgnoreSslVerification = true
 
-	trans, gerr := generichttp.New(false, &tc)
+	trans, gerr := generichttp.New(false, &tc, "?")
 	s.Require().NoError(gerr)
 
 	var err error
-	s.transport, err = New(&config, trans)
+	s.transport, err = New(&config, trans, "?")
 	s.Require().NoError(err, "failed to initialize swift transport")
 }
 

+ 9 - 7
fetcher/transport/transport.go

@@ -27,7 +27,7 @@ func New(config *Config) (*Transport, error) {
 		return nil, err
 	}
 
-	transport, err := generichttp.New(true, &config.HTTP)
+	transport, err := generichttp.New(true, &config.HTTP, config.SourceURLQuerySeparator)
 	if err != nil {
 		return nil, err
 	}
@@ -71,13 +71,15 @@ func (t *Transport) IsProtocolRegistered(scheme string) bool {
 
 // RegisterAllProtocols registers all enabled protocols in the given transport
 func (t *Transport) registerAllProtocols() error {
-	transp, err := generichttp.New(false, &t.config.HTTP)
+	sep := t.config.SourceURLQuerySeparator // shortcut
+
+	transp, err := generichttp.New(false, &t.config.HTTP, sep)
 	if err != nil {
 		return err
 	}
 
 	if t.config.Local.Root != "" {
-		p, err := fsTransport.New(&t.config.Local)
+		p, err := fsTransport.New(&t.config.Local, sep)
 		if err != nil {
 			return err
 		}
@@ -85,7 +87,7 @@ func (t *Transport) registerAllProtocols() error {
 	}
 
 	if t.config.S3Enabled {
-		tr, err := s3Transport.New(&t.config.S3, transp)
+		tr, err := s3Transport.New(&t.config.S3, transp, sep)
 		if err != nil {
 			return err
 		}
@@ -93,7 +95,7 @@ func (t *Transport) registerAllProtocols() error {
 	}
 
 	if t.config.GCSEnabled {
-		tr, err := gcsTransport.New(&t.config.GCS, transp)
+		tr, err := gcsTransport.New(&t.config.GCS, transp, sep)
 		if err != nil {
 			return err
 		}
@@ -101,7 +103,7 @@ func (t *Transport) registerAllProtocols() error {
 	}
 
 	if t.config.ABSEnabled {
-		tr, err := azureTransport.New(&t.config.ABS, transp)
+		tr, err := azureTransport.New(&t.config.ABS, transp, sep)
 		if err != nil {
 			return err
 		}
@@ -109,7 +111,7 @@ func (t *Transport) registerAllProtocols() error {
 	}
 
 	if t.config.SwiftEnabled {
-		tr, err := swiftTransport.New(&t.config.Swift, transp)
+		tr, err := swiftTransport.New(&t.config.Swift, transp, sep)
 		if err != nil {
 			return err
 		}

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff