Просмотр исходного кода

NewDefaultConfig returns value, not pointer; Nested configs are defined as value

DarthSim 1 месяц назад
Родитель
Сommit
ac03563506

+ 8 - 9
auximageprovider/static_config.go

@@ -1,6 +1,9 @@
 package auximageprovider
 
-import "github.com/imgproxy/imgproxy/v3/config"
+import (
+	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
+)
 
 // StaticConfig holds the configuration for the auxiliary image provider
 type StaticConfig struct {
@@ -10,8 +13,8 @@ type StaticConfig struct {
 }
 
 // NewDefaultStaticConfig creates a new default configuration for the auxiliary image provider
-func NewDefaultStaticConfig() *StaticConfig {
-	return &StaticConfig{
+func NewDefaultStaticConfig() StaticConfig {
+	return StaticConfig{
 		Base64Data: "",
 		Path:       "",
 		URL:        "",
@@ -20,9 +23,7 @@ func NewDefaultStaticConfig() *StaticConfig {
 
 // LoadWatermarkStaticConfigFromEnv loads the watermark configuration from the environment
 func LoadWatermarkStaticConfigFromEnv(c *StaticConfig) (*StaticConfig, error) {
-	if c == nil {
-		c = NewDefaultStaticConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultStaticConfig)
 
 	c.Base64Data = config.WatermarkData
 	c.Path = config.WatermarkPath
@@ -33,9 +34,7 @@ func LoadWatermarkStaticConfigFromEnv(c *StaticConfig) (*StaticConfig, error) {
 
 // LoadFallbackStaticConfigFromEnv loads the fallback configuration from the environment
 func LoadFallbackStaticConfigFromEnv(c *StaticConfig) (*StaticConfig, error) {
-	if c == nil {
-		c = NewDefaultStaticConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultStaticConfig)
 
 	c.Base64Data = config.FallbackImageData
 	c.Path = config.FallbackImagePath

+ 2 - 2
auximageprovider/static_provider_test.go

@@ -169,11 +169,11 @@ func (s *ImageProviderTestSuite) TestNewProvider() {
 	}
 
 	trc := transport.NewDefaultConfig()
-	tr, err := transport.New(trc)
+	tr, err := transport.New(&trc)
 	s.Require().NoError(err)
 
 	fc := fetcher.NewDefaultConfig()
-	f, err := fetcher.New(tr, fc)
+	f, err := fetcher.New(tr, &fc)
 	s.Require().NoError(err)
 
 	idf := imagedata.NewFactory(f)

+ 15 - 0
ensure/ensure.go

@@ -0,0 +1,15 @@
+package ensure
+
+type EnsureFunc[T any] func() T
+
+// Ensure ensures that the returned value is not nil.
+// If the provided pointer is nil, the function calls the provided
+// EnsureFunc to obtain a new value.
+// Otherwise, it returns the original value.
+func Ensure[T any](val *T, f EnsureFunc[T]) *T {
+	if val == nil {
+		v := f()
+		return &v
+	}
+	return val
+}

+ 4 - 5
fetcher/config.go

@@ -5,6 +5,7 @@ import (
 	"time"
 
 	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
 	"github.com/imgproxy/imgproxy/v3/version"
 )
 
@@ -19,8 +20,8 @@ type Config struct {
 }
 
 // NewDefaultConfig returns a new Config instance with default values.
-func NewDefaultConfig() *Config {
-	return &Config{
+func NewDefaultConfig() Config {
+	return Config{
 		UserAgent:       "imgproxy/" + version.Version,
 		DownloadTimeout: 5 * time.Second,
 		MaxRedirects:    10,
@@ -29,9 +30,7 @@ func NewDefaultConfig() *Config {
 
 // LoadConfigFromEnv loads config variables from env
 func LoadConfigFromEnv(c *Config) (*Config, error) {
-	if c == nil {
-		c = NewDefaultConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultConfig)
 
 	c.UserAgent = config.UserAgent
 	c.DownloadTimeout = time.Duration(config.DownloadTimeout) * time.Second

+ 4 - 5
handlers/processing/config.go

@@ -5,6 +5,7 @@ import (
 	"net/http"
 
 	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
 )
 
 // Config represents handler config
@@ -20,8 +21,8 @@ type Config struct {
 }
 
 // NewDefaultConfig creates a new configuration with defaults
-func NewDefaultConfig() *Config {
-	return &Config{
+func NewDefaultConfig() Config {
+	return Config{
 		PathPrefix:              "",
 		CookiePassthrough:       false,
 		ReportDownloadingErrors: true,
@@ -35,9 +36,7 @@ func NewDefaultConfig() *Config {
 
 // LoadConfigFromEnv loads config from environment variables
 func LoadConfigFromEnv(c *Config) (*Config, error) {
-	if c == nil {
-		c = NewDefaultConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultConfig)
 
 	c.PathPrefix = config.PathPrefix
 	c.CookiePassthrough = config.CookiePassthrough

+ 4 - 5
handlers/stream/config.go

@@ -2,6 +2,7 @@ package stream
 
 import (
 	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
 	"github.com/imgproxy/imgproxy/v3/httpheaders"
 )
 
@@ -18,8 +19,8 @@ type Config struct {
 }
 
 // NewDefaultConfig returns a new Config instance with default values.
-func NewDefaultConfig() *Config {
-	return &Config{
+func NewDefaultConfig() Config {
+	return Config{
 		CookiePassthrough: false,
 		PassthroughRequestHeaders: []string{
 			httpheaders.IfNoneMatch,
@@ -40,9 +41,7 @@ func NewDefaultConfig() *Config {
 
 // LoadConfigFromEnv loads config variables from environment
 func LoadConfigFromEnv(c *Config) (*Config, error) {
-	if c == nil {
-		c = NewDefaultConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultConfig)
 
 	c.CookiePassthrough = config.CookiePassthrough
 

+ 12 - 12
handlers/stream/handler_test.go

@@ -57,16 +57,16 @@ func (s *HandlerTestSuite) SetupTest() {
 
 	fc := fetcher.NewDefaultConfig()
 
-	fetcher, err := fetcher.New(tr, fc)
+	fetcher, err := fetcher.New(tr, &fc)
 	s.Require().NoError(err)
 
 	cfg := NewDefaultConfig()
 
 	hwc := headerwriter.NewDefaultConfig()
-	hw, err := headerwriter.New(hwc)
+	hw, err := headerwriter.New(&hwc)
 	s.Require().NoError(err)
 
-	h, err := New(cfg, hw, fetcher)
+	h, err := New(&cfg, hw, fetcher)
 	s.Require().NoError(err)
 	s.handler = h
 }
@@ -358,7 +358,7 @@ func (s *HandlerTestSuite) TestHandlerCacheControl() {
 
 			fc := fetcher.NewDefaultConfig()
 
-			fetcher, err := fetcher.New(tr, fc)
+			fetcher, err := fetcher.New(tr, &fc)
 			s.Require().NoError(err)
 
 			cfg := NewDefaultConfig()
@@ -366,10 +366,10 @@ func (s *HandlerTestSuite) TestHandlerCacheControl() {
 			hwc.CacheControlPassthrough = tc.cacheControlPassthrough
 			hwc.DefaultTTL = 4242
 
-			hw, err := headerwriter.New(hwc)
+			hw, err := headerwriter.New(&hwc)
 			s.Require().NoError(err)
 
-			handler, err := New(cfg, hw, fetcher)
+			handler, err := New(&cfg, hw, fetcher)
 			s.Require().NoError(err)
 
 			req := httptest.NewRequest("GET", "/", nil)
@@ -454,17 +454,17 @@ func (s *HandlerTestSuite) TestHandlerCookiePassthrough() {
 	s.Require().NoError(err)
 
 	fc := fetcher.NewDefaultConfig()
-	fetcher, err := fetcher.New(tr, fc)
+	fetcher, err := fetcher.New(tr, &fc)
 	s.Require().NoError(err)
 
 	cfg := NewDefaultConfig()
 	cfg.CookiePassthrough = true
 
 	hwc := headerwriter.NewDefaultConfig()
-	hw, err := headerwriter.New(hwc)
+	hw, err := headerwriter.New(&hwc)
 	s.Require().NoError(err)
 
-	handler, err := New(cfg, hw, fetcher)
+	handler, err := New(&cfg, hw, fetcher)
 	s.Require().NoError(err)
 
 	data := s.readTestFile("test1.png")
@@ -514,7 +514,7 @@ func (s *HandlerTestSuite) TestHandlerCanonicalHeader() {
 		s.Require().NoError(err)
 
 		fc := fetcher.NewDefaultConfig()
-		fetcher, err := fetcher.New(tr, fc)
+		fetcher, err := fetcher.New(tr, &fc)
 		s.Require().NoError(err)
 
 		cfg := NewDefaultConfig()
@@ -522,10 +522,10 @@ func (s *HandlerTestSuite) TestHandlerCanonicalHeader() {
 
 		hwc.SetCanonicalHeader = sc
 
-		hw, err := headerwriter.New(hwc)
+		hw, err := headerwriter.New(&hwc)
 		s.Require().NoError(err)
 
-		handler, err := New(cfg, hw, fetcher)
+		handler, err := New(&cfg, hw, fetcher)
 		s.Require().NoError(err)
 
 		req := httptest.NewRequest("GET", "/", nil)

+ 4 - 5
headerwriter/config.go

@@ -4,6 +4,7 @@ import (
 	"fmt"
 
 	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
 )
 
 // Config is the package-local configuration
@@ -17,8 +18,8 @@ type Config struct {
 }
 
 // NewDefaultConfig returns a new Config instance with default values.
-func NewDefaultConfig() *Config {
-	return &Config{
+func NewDefaultConfig() Config {
+	return Config{
 		SetCanonicalHeader:      false,
 		DefaultTTL:              31536000,
 		FallbackImageTTL:        0,
@@ -30,9 +31,7 @@ func NewDefaultConfig() *Config {
 
 // LoadConfigFromEnv overrides configuration variables from environment
 func LoadConfigFromEnv(c *Config) (*Config, error) {
-	if c == nil {
-		c = NewDefaultConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultConfig)
 
 	c.SetCanonicalHeader = config.SetCanonicalHeader
 	c.DefaultTTL = config.TTL

+ 2 - 2
processing/processing_test.go

@@ -38,11 +38,11 @@ func (s *ProcessingTestSuite) SetupSuite() {
 	logrus.SetOutput(io.Discard)
 
 	trc := transport.NewDefaultConfig()
-	tr, err := transport.New(trc)
+	tr, err := transport.New(&trc)
 	s.Require().NoError(err)
 
 	fc := fetcher.NewDefaultConfig()
-	f, err := fetcher.New(tr, fc)
+	f, err := fetcher.New(tr, &fc)
 	s.Require().NoError(err)
 
 	s.idf = imagedata.NewFactory(f)

+ 1 - 1
processing_handler_test.go

@@ -53,7 +53,7 @@ func (s *ProcessingHandlerTestSuite) SetupSuite() {
 	logrus.SetOutput(io.Discard)
 
 	cfg := server.NewDefaultConfig()
-	r, err := server.NewRouter(cfg)
+	r, err := server.NewRouter(&cfg)
 	s.Require().NoError(err)
 
 	s.router = buildRouter(r)

+ 4 - 5
semaphores/config.go

@@ -5,6 +5,7 @@ import (
 	"runtime"
 
 	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
 )
 
 // Config represents handler config
@@ -14,8 +15,8 @@ type Config struct {
 }
 
 // NewDefaultConfig creates a new configuration with defaults
-func NewDefaultConfig() *Config {
-	return &Config{
+func NewDefaultConfig() Config {
+	return Config{
 		RequestsQueueSize: 0,
 		Workers:           runtime.GOMAXPROCS(0) * 2,
 	}
@@ -23,9 +24,7 @@ func NewDefaultConfig() *Config {
 
 // LoadConfigFromEnv loads config from environment variables
 func LoadConfigFromEnv(c *Config) (*Config, error) {
-	if c == nil {
-		c = NewDefaultConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultConfig)
 
 	c.RequestsQueueSize = config.RequestsQueueSize
 	c.Workers = config.Workers

+ 4 - 5
server/config.go

@@ -6,6 +6,7 @@ import (
 	"time"
 
 	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
 )
 
 const (
@@ -32,8 +33,8 @@ type Config struct {
 }
 
 // NewDefaultConfig returns default config values
-func NewDefaultConfig() *Config {
-	return &Config{
+func NewDefaultConfig() Config {
+	return Config{
 		Network:               "tcp",
 		Bind:                  ":8080",
 		PathPrefix:            "",
@@ -52,9 +53,7 @@ func NewDefaultConfig() *Config {
 
 // LoadConfigFromEnv overrides current values with environment variables
 func LoadConfigFromEnv(c *Config) (*Config, error) {
-	if c == nil {
-		c = NewDefaultConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultConfig)
 
 	c.Network = config.Network
 	c.Bind = config.Bind

+ 1 - 1
server/router_test.go

@@ -19,7 +19,7 @@ func (s *RouterTestSuite) SetupTest() {
 	c := NewDefaultConfig()
 
 	c.PathPrefix = "/api"
-	r, err := NewRouter(c)
+	r, err := NewRouter(&c)
 	s.Require().NoError(err)
 
 	s.router = r

+ 4 - 4
server/server_test.go

@@ -22,7 +22,7 @@ type ServerTestSuite struct {
 func (s *ServerTestSuite) SetupTest() {
 	c := NewDefaultConfig()
 
-	s.config = c
+	s.config = &c
 	s.config.Bind = "127.0.0.1:0" // Use port 0 for auto-assignment
 	r, err := NewRouter(s.config)
 	s.Require().NoError(err)
@@ -46,7 +46,7 @@ func (s *ServerTestSuite) TestStartServerWithInvalidBind() {
 	invalidConfig := NewDefaultConfig()
 	invalidConfig.Bind = "-1.-1.-1.-1" // Invalid address
 
-	r, err := NewRouter(invalidConfig)
+	r, err := NewRouter(&invalidConfig)
 	s.Require().NoError(err)
 
 	server, err := Start(cancelWrapper, r)
@@ -113,7 +113,7 @@ func (s *ServerTestSuite) TestWithCORS() {
 			config := NewDefaultConfig()
 			config.CORSAllowOrigin = tt.corsAllowOrigin
 
-			router, err := NewRouter(config)
+			router, err := NewRouter(&config)
 			s.Require().NoError(err)
 
 			wrappedHandler := router.WithCORS(s.mockHandler)
@@ -159,7 +159,7 @@ func (s *ServerTestSuite) TestWithSecret() {
 			config := NewDefaultConfig()
 			config.Secret = tt.secret
 
-			router, err := NewRouter(config)
+			router, err := NewRouter(&config)
 			s.Require().NoError(err)
 
 			wrappedHandler := router.WithSecret(s.mockHandler)

+ 2 - 2
svg/svg_test.go

@@ -23,11 +23,11 @@ func (s *SvgTestSuite) SetupSuite() {
 	config.Reset()
 
 	trc := transport.NewDefaultConfig()
-	tr, err := transport.New(trc)
+	tr, err := transport.New(&trc)
 	s.Require().NoError(err)
 
 	fc := fetcher.NewDefaultConfig()
-	f, err := fetcher.New(tr, fc)
+	f, err := fetcher.New(tr, &fc)
 	s.Require().NoError(err)
 
 	s.idf = imagedata.NewFactory(f)

+ 2 - 2
transport/azure/azure_test.go

@@ -49,11 +49,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)
 }
 

+ 4 - 5
transport/azure/config.go

@@ -4,6 +4,7 @@ import (
 	"fmt"
 
 	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
 )
 
 // Config holds the configuration for Azure Blob Storage transport
@@ -14,8 +15,8 @@ type Config struct {
 }
 
 // NewDefaultConfig returns a new default configuration for Azure Blob Storage transport
-func NewDefaultConfig() *Config {
-	return &Config{
+func NewDefaultConfig() Config {
+	return Config{
 		Name:     "",
 		Endpoint: "",
 		Key:      "",
@@ -24,9 +25,7 @@ func NewDefaultConfig() *Config {
 
 // LoadConfigFromEnv loads configuration from the global config package
 func LoadConfigFromEnv(c *Config) (*Config, error) {
-	if c == nil {
-		c = NewDefaultConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultConfig)
 
 	c.Name = config.ABSName
 	c.Endpoint = config.ABSEndpoint

+ 16 - 17
transport/config.go

@@ -4,6 +4,7 @@ package transport
 
 import (
 	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
 	"github.com/imgproxy/imgproxy/v3/transport/azure"
 	"github.com/imgproxy/imgproxy/v3/transport/fs"
 	"github.com/imgproxy/imgproxy/v3/transport/gcs"
@@ -14,26 +15,26 @@ import (
 
 // Config represents configuration of the transport package
 type Config struct {
-	HTTP *generichttp.Config
+	HTTP generichttp.Config
 
-	Local *fs.Config
+	Local fs.Config
 
 	ABSEnabled bool
-	ABS        *azure.Config
+	ABS        azure.Config
 
 	GCSEnabled bool
-	GCS        *gcs.Config
+	GCS        gcs.Config
 
 	S3Enabled bool
-	S3        *s3.Config
+	S3        s3.Config
 
 	SwiftEnabled bool
-	Swift        *swift.Config
+	Swift        swift.Config
 }
 
 // NewDefaultConfig returns a new default transport configuration
-func NewDefaultConfig() *Config {
-	return &Config{
+func NewDefaultConfig() Config {
+	return Config{
 		HTTP:         generichttp.NewDefaultConfig(),
 		Local:        fs.NewDefaultConfig(),
 		ABSEnabled:   false,
@@ -49,33 +50,31 @@ func NewDefaultConfig() *Config {
 
 // LoadConfigFromEnv loads transport configuration from environment variables
 func LoadConfigFromEnv(c *Config) (*Config, error) {
-	if c == nil {
-		c = NewDefaultConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultConfig)
 
 	var err error
 
-	if c.HTTP, err = generichttp.LoadConfigFromEnv(c.HTTP); err != nil {
+	if _, err = generichttp.LoadConfigFromEnv(&c.HTTP); err != nil {
 		return nil, err
 	}
 
-	if c.Local, err = fs.LoadConfigFromEnv(c.Local); err != nil {
+	if _, err = fs.LoadConfigFromEnv(&c.Local); err != nil {
 		return nil, err
 	}
 
-	if c.ABS, err = azure.LoadConfigFromEnv(c.ABS); err != nil {
+	if _, err = azure.LoadConfigFromEnv(&c.ABS); err != nil {
 		return nil, err
 	}
 
-	if c.GCS, err = gcs.LoadConfigFromEnv(c.GCS); err != nil {
+	if _, err = gcs.LoadConfigFromEnv(&c.GCS); err != nil {
 		return nil, err
 	}
 
-	if c.S3, err = s3.LoadConfigFromEnv(c.S3); err != nil {
+	if _, err = s3.LoadConfigFromEnv(&c.S3); err != nil {
 		return nil, err
 	}
 
-	if c.Swift, err = swift.LoadConfigFromEnv(c.Swift); err != nil {
+	if _, err = swift.LoadConfigFromEnv(&c.Swift); err != nil {
 		return nil, err
 	}
 

+ 4 - 5
transport/fs/config.go

@@ -6,6 +6,7 @@ import (
 	"os"
 
 	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
 )
 
 // Config holds the configuration for local file system transport
@@ -14,17 +15,15 @@ type Config struct {
 }
 
 // NewDefaultConfig returns a new default configuration for local file system transport
-func NewDefaultConfig() *Config {
-	return &Config{
+func NewDefaultConfig() Config {
+	return Config{
 		Root: "",
 	}
 }
 
 // LoadConfigFromEnv loads configuration from the global config package
 func LoadConfigFromEnv(c *Config) (*Config, error) {
-	if c == nil {
-		c = NewDefaultConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultConfig)
 
 	c.Root = config.LocalFileSystemRoot
 

+ 7 - 6
transport/gcs/config.go

@@ -1,6 +1,9 @@
 package gcs
 
-import "github.com/imgproxy/imgproxy/v3/config"
+import (
+	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
+)
 
 // Config holds the configuration for Google Cloud Storage transport
 type Config struct {
@@ -9,8 +12,8 @@ type Config struct {
 }
 
 // NewDefaultConfig returns a new default configuration for Google Cloud Storage transport
-func NewDefaultConfig() *Config {
-	return &Config{
+func NewDefaultConfig() Config {
+	return Config{
 		Key:      "",
 		Endpoint: "",
 	}
@@ -18,9 +21,7 @@ func NewDefaultConfig() *Config {
 
 // LoadConfigFromEnv loads configuration from the global config package
 func LoadConfigFromEnv(c *Config) (*Config, error) {
-	if c == nil {
-		c = NewDefaultConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultConfig)
 
 	c.Key = config.GCSKey
 	c.Endpoint = config.GCSEndpoint

+ 2 - 2
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)
 }
 

+ 4 - 5
transport/generichttp/config.go

@@ -5,6 +5,7 @@ import (
 	"time"
 
 	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
 )
 
 // Config holds the configuration for the generic HTTP transport
@@ -14,8 +15,8 @@ type Config struct {
 }
 
 // NewDefaultConfig returns a new default configuration for the generic HTTP transport
-func NewDefaultConfig() *Config {
-	return &Config{
+func NewDefaultConfig() Config {
+	return Config{
 		ClientKeepAliveTimeout: 90 * time.Second,
 		IgnoreSslVerification:  false,
 	}
@@ -23,9 +24,7 @@ func NewDefaultConfig() *Config {
 
 // LoadConfigFromEnv loads configuration from the global config package
 func LoadConfigFromEnv(c *Config) (*Config, error) {
-	if c == nil {
-		c = NewDefaultConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultConfig)
 
 	c.ClientKeepAliveTimeout = time.Duration(config.ClientKeepAliveTimeout) * time.Second
 	c.IgnoreSslVerification = config.IgnoreSslVerification

+ 7 - 6
transport/s3/config.go

@@ -1,6 +1,9 @@
 package s3
 
-import "github.com/imgproxy/imgproxy/v3/config"
+import (
+	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
+)
 
 // Config holds the configuration for S3 transport
 type Config struct {
@@ -13,8 +16,8 @@ type Config struct {
 }
 
 // NewDefaultConfig returns a new default configuration for S3 transport
-func NewDefaultConfig() *Config {
-	return &Config{
+func NewDefaultConfig() Config {
+	return Config{
 		Region:                  "",
 		Endpoint:                "",
 		EndpointUsePathStyle:    true,
@@ -26,9 +29,7 @@ func NewDefaultConfig() *Config {
 
 // LoadConfigFromEnv loads configuration from the global config package
 func LoadConfigFromEnv(c *Config) (*Config, error) {
-	if c == nil {
-		c = NewDefaultConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultConfig)
 
 	c.Region = config.S3Region
 	c.Endpoint = config.S3Endpoint

+ 2 - 2
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")

+ 4 - 5
transport/swift/config.go

@@ -4,6 +4,7 @@ import (
 	"time"
 
 	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ensure"
 )
 
 // Config holds the configuration for Swift transport
@@ -19,8 +20,8 @@ type Config struct {
 }
 
 // NewDefaultConfig returns a new default configuration for Swift transport
-func NewDefaultConfig() *Config {
-	return &Config{
+func NewDefaultConfig() Config {
+	return Config{
 		Username:       "",
 		APIKey:         "",
 		AuthURL:        "",
@@ -34,9 +35,7 @@ func NewDefaultConfig() *Config {
 
 // LoadConfigFromEnv loads configuration from the global config package
 func LoadConfigFromEnv(c *Config) (*Config, error) {
-	if c == nil {
-		c = NewDefaultConfig()
-	}
+	c = ensure.Ensure(c, NewDefaultConfig)
 
 	c.Username = config.SwiftUsername
 	c.APIKey = config.SwiftAPIKey

+ 3 - 3
transport/swift/swift_test.go

@@ -36,16 +36,16 @@ func (s *SwiftTestSuite) SetupSuite() {
 	config.APIKey = swifttest.TEST_ACCOUNT
 	config.AuthVersion = 1
 
-	s.setupTestFile(config)
+	s.setupTestFile(&config)
 
 	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")
 }
 

+ 7 - 7
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)
 	if err != nil {
 		return nil, err
 	}
@@ -71,17 +71,17 @@ 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)
+	transp, err := generichttp.New(false, &t.config.HTTP)
 	if err != nil {
 		return err
 	}
 
 	if t.config.Local.Root != "" {
-		t.RegisterProtocol("local", fsTransport.New(t.config.Local))
+		t.RegisterProtocol("local", fsTransport.New(&t.config.Local))
 	}
 
 	if t.config.S3Enabled {
-		if tr, err := s3Transport.New(t.config.S3, transp); err != nil {
+		if tr, err := s3Transport.New(&t.config.S3, transp); err != nil {
 			return err
 		} else {
 			t.RegisterProtocol("s3", tr)
@@ -89,7 +89,7 @@ func (t *Transport) registerAllProtocols() error {
 	}
 
 	if t.config.GCSEnabled {
-		if tr, err := gcsTransport.New(t.config.GCS, transp); err != nil {
+		if tr, err := gcsTransport.New(&t.config.GCS, transp); err != nil {
 			return err
 		} else {
 			t.RegisterProtocol("gs", tr)
@@ -97,7 +97,7 @@ func (t *Transport) registerAllProtocols() error {
 	}
 
 	if t.config.ABSEnabled {
-		if tr, err := azureTransport.New(t.config.ABS, transp); err != nil {
+		if tr, err := azureTransport.New(&t.config.ABS, transp); err != nil {
 			return err
 		} else {
 			t.RegisterProtocol("abs", tr)
@@ -105,7 +105,7 @@ func (t *Transport) registerAllProtocols() error {
 	}
 
 	if t.config.SwiftEnabled {
-		if tr, err := swiftTransport.New(t.config.Swift, transp); err != nil {
+		if tr, err := swiftTransport.New(&t.config.Swift, transp); err != nil {
 			return err
 		} else {
 			t.RegisterProtocol("swift", tr)