1package aws
2
3import (
4	"net/http"
5	"time"
6
7	"github.com/aws/aws-sdk-go/aws/credentials"
8	"github.com/aws/aws-sdk-go/aws/endpoints"
9)
10
11// UseServiceDefaultRetries instructs the config to use the service's own
12// default number of retries. This will be the default action if
13// Config.MaxRetries is nil also.
14const UseServiceDefaultRetries = -1
15
16// RequestRetryer is an alias for a type that implements the request.Retryer
17// interface.
18type RequestRetryer interface{}
19
20// A Config provides service configuration for service clients. By default,
21// all clients will use the defaults.DefaultConfig structure.
22//
23//     // Create Session with MaxRetries configuration to be shared by multiple
24//     // service clients.
25//     sess := session.Must(session.NewSession(&aws.Config{
26//         MaxRetries: aws.Int(3),
27//     }))
28//
29//     // Create S3 service client with a specific Region.
30//     svc := s3.New(sess, &aws.Config{
31//         Region: aws.String("us-west-2"),
32//     })
33type Config struct {
34	// Enables verbose error printing of all credential chain errors.
35	// Should be used when wanting to see all errors while attempting to
36	// retrieve credentials.
37	CredentialsChainVerboseErrors *bool
38
39	// The credentials object to use when signing requests. Defaults to a
40	// chain of credential providers to search for credentials in environment
41	// variables, shared credential file, and EC2 Instance Roles.
42	Credentials *credentials.Credentials
43
44	// An optional endpoint URL (hostname only or fully qualified URI)
45	// that overrides the default generated endpoint for a client. Set this
46	// to `nil` or the value to `""` to use the default generated endpoint.
47	//
48	// Note: You must still provide a `Region` value when specifying an
49	// endpoint for a client.
50	Endpoint *string
51
52	// The resolver to use for looking up endpoints for AWS service clients
53	// to use based on region.
54	EndpointResolver endpoints.Resolver
55
56	// EnforceShouldRetryCheck is used in the AfterRetryHandler to always call
57	// ShouldRetry regardless of whether or not if request.Retryable is set.
58	// This will utilize ShouldRetry method of custom retryers. If EnforceShouldRetryCheck
59	// is not set, then ShouldRetry will only be called if request.Retryable is nil.
60	// Proper handling of the request.Retryable field is important when setting this field.
61	EnforceShouldRetryCheck *bool
62
63	// The region to send requests to. This parameter is required and must
64	// be configured globally or on a per-client basis unless otherwise
65	// noted. A full list of regions is found in the "Regions and Endpoints"
66	// document.
67	//
68	// See http://docs.aws.amazon.com/general/latest/gr/rande.html for AWS
69	// Regions and Endpoints.
70	Region *string
71
72	// Set this to `true` to disable SSL when sending requests. Defaults
73	// to `false`.
74	DisableSSL *bool
75
76	// The HTTP client to use when sending requests. Defaults to
77	// `http.DefaultClient`.
78	HTTPClient *http.Client
79
80	// An integer value representing the logging level. The default log level
81	// is zero (LogOff), which represents no logging. To enable logging set
82	// to a LogLevel Value.
83	LogLevel *LogLevelType
84
85	// The logger writer interface to write logging messages to. Defaults to
86	// standard out.
87	Logger Logger
88
89	// The maximum number of times that a request will be retried for failures.
90	// Defaults to -1, which defers the max retry setting to the service
91	// specific configuration.
92	MaxRetries *int
93
94	// Retryer guides how HTTP requests should be retried in case of
95	// recoverable failures.
96	//
97	// When nil or the value does not implement the request.Retryer interface,
98	// the client.DefaultRetryer will be used.
99	//
100	// When both Retryer and MaxRetries are non-nil, the former is used and
101	// the latter ignored.
102	//
103	// To set the Retryer field in a type-safe manner and with chaining, use
104	// the request.WithRetryer helper function:
105	//
106	//   cfg := request.WithRetryer(aws.NewConfig(), myRetryer)
107	//
108	Retryer RequestRetryer
109
110	// Disables semantic parameter validation, which validates input for
111	// missing required fields and/or other semantic request input errors.
112	DisableParamValidation *bool
113
114	// Disables the computation of request and response checksums, e.g.,
115	// CRC32 checksums in Amazon DynamoDB.
116	DisableComputeChecksums *bool
117
118	// Set this to `true` to force the request to use path-style addressing,
119	// i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client
120	// will use virtual hosted bucket addressing when possible
121	// (`http://BUCKET.s3.amazonaws.com/KEY`).
122	//
123	// Note: This configuration option is specific to the Amazon S3 service.
124	//
125	// See http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html
126	// for Amazon S3: Virtual Hosting of Buckets
127	S3ForcePathStyle *bool
128
129	// Set this to `true` to disable the SDK adding the `Expect: 100-Continue`
130	// header to PUT requests over 2MB of content. 100-Continue instructs the
131	// HTTP client not to send the body until the service responds with a
132	// `continue` status. This is useful to prevent sending the request body
133	// until after the request is authenticated, and validated.
134	//
135	// http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html
136	//
137	// 100-Continue is only enabled for Go 1.6 and above. See `http.Transport`'s
138	// `ExpectContinueTimeout` for information on adjusting the continue wait
139	// timeout. https://golang.org/pkg/net/http/#Transport
140	//
141	// You should use this flag to disable 100-Continue if you experience issues
142	// with proxies or third party S3 compatible services.
143	S3Disable100Continue *bool
144
145	// Set this to `true` to enable S3 Accelerate feature. For all operations
146	// compatible with S3 Accelerate will use the accelerate endpoint for
147	// requests. Requests not compatible will fall back to normal S3 requests.
148	//
149	// The bucket must be enable for accelerate to be used with S3 client with
150	// accelerate enabled. If the bucket is not enabled for accelerate an error
151	// will be returned. The bucket name must be DNS compatible to also work
152	// with accelerate.
153	S3UseAccelerate *bool
154
155	// S3DisableContentMD5Validation config option is temporarily disabled,
156	// For S3 GetObject API calls, #1837.
157	//
158	// Set this to `true` to disable the S3 service client from automatically
159	// adding the ContentMD5 to S3 Object Put and Upload API calls. This option
160	// will also disable the SDK from performing object ContentMD5 validation
161	// on GetObject API calls.
162	S3DisableContentMD5Validation *bool
163
164	// Set this to `true` to have the S3 service client to use the region specified
165	// in the ARN, when an ARN is provided as an argument to a bucket parameter.
166	S3UseARNRegion *bool
167
168	// Set this to `true` to enable the SDK to unmarshal API response header maps to
169	// normalized lower case map keys.
170	//
171	// For example S3's X-Amz-Meta prefixed header will be unmarshaled to lower case
172	// Metadata member's map keys. The value of the header in the map is unaffected.
173	LowerCaseHeaderMaps *bool
174
175	// Set this to `true` to disable the EC2Metadata client from overriding the
176	// default http.Client's Timeout. This is helpful if you do not want the
177	// EC2Metadata client to create a new http.Client. This options is only
178	// meaningful if you're not already using a custom HTTP client with the
179	// SDK. Enabled by default.
180	//
181	// Must be set and provided to the session.NewSession() in order to disable
182	// the EC2Metadata overriding the timeout for default credentials chain.
183	//
184	// Example:
185	//    sess := session.Must(session.NewSession(aws.NewConfig()
186	//       .WithEC2MetadataDisableTimeoutOverride(true)))
187	//
188	//    svc := s3.New(sess)
189	//
190	EC2MetadataDisableTimeoutOverride *bool
191
192	// Instructs the endpoint to be generated for a service client to
193	// be the dual stack endpoint. The dual stack endpoint will support
194	// both IPv4 and IPv6 addressing.
195	//
196	// Setting this for a service which does not support dual stack will fail
197	// to make requests. It is not recommended to set this value on the session
198	// as it will apply to all service clients created with the session. Even
199	// services which don't support dual stack endpoints.
200	//
201	// If the Endpoint config value is also provided the UseDualStack flag
202	// will be ignored.
203	//
204	// Only supported with.
205	//
206	//     sess := session.Must(session.NewSession())
207	//
208	//     svc := s3.New(sess, &aws.Config{
209	//         UseDualStack: aws.Bool(true),
210	//     })
211	UseDualStack *bool
212
213	// SleepDelay is an override for the func the SDK will call when sleeping
214	// during the lifecycle of a request. Specifically this will be used for
215	// request delays. This value should only be used for testing. To adjust
216	// the delay of a request see the aws/client.DefaultRetryer and
217	// aws/request.Retryer.
218	//
219	// SleepDelay will prevent any Context from being used for canceling retry
220	// delay of an API operation. It is recommended to not use SleepDelay at all
221	// and specify a Retryer instead.
222	SleepDelay func(time.Duration)
223
224	// DisableRestProtocolURICleaning will not clean the URL path when making rest protocol requests.
225	// Will default to false. This would only be used for empty directory names in s3 requests.
226	//
227	// Example:
228	//    sess := session.Must(session.NewSession(&aws.Config{
229	//         DisableRestProtocolURICleaning: aws.Bool(true),
230	//    }))
231	//
232	//    svc := s3.New(sess)
233	//    out, err := svc.GetObject(&s3.GetObjectInput {
234	//    	Bucket: aws.String("bucketname"),
235	//    	Key: aws.String("//foo//bar//moo"),
236	//    })
237	DisableRestProtocolURICleaning *bool
238
239	// EnableEndpointDiscovery will allow for endpoint discovery on operations that
240	// have the definition in its model. By default, endpoint discovery is off.
241	// To use EndpointDiscovery, Endpoint should be unset or set to an empty string.
242	//
243	// Example:
244	//    sess := session.Must(session.NewSession(&aws.Config{
245	//         EnableEndpointDiscovery: aws.Bool(true),
246	//    }))
247	//
248	//    svc := s3.New(sess)
249	//    out, err := svc.GetObject(&s3.GetObjectInput {
250	//    	Bucket: aws.String("bucketname"),
251	//    	Key: aws.String("/foo/bar/moo"),
252	//    })
253	EnableEndpointDiscovery *bool
254
255	// DisableEndpointHostPrefix will disable the SDK's behavior of prefixing
256	// request endpoint hosts with modeled information.
257	//
258	// Disabling this feature is useful when you want to use local endpoints
259	// for testing that do not support the modeled host prefix pattern.
260	DisableEndpointHostPrefix *bool
261
262	// STSRegionalEndpoint will enable regional or legacy endpoint resolving
263	STSRegionalEndpoint endpoints.STSRegionalEndpoint
264
265	// S3UsEast1RegionalEndpoint will enable regional or legacy endpoint resolving
266	S3UsEast1RegionalEndpoint endpoints.S3UsEast1RegionalEndpoint
267}
268
269// NewConfig returns a new Config pointer that can be chained with builder
270// methods to set multiple configuration values inline without using pointers.
271//
272//     // Create Session with MaxRetries configuration to be shared by multiple
273//     // service clients.
274//     sess := session.Must(session.NewSession(aws.NewConfig().
275//         WithMaxRetries(3),
276//     ))
277//
278//     // Create S3 service client with a specific Region.
279//     svc := s3.New(sess, aws.NewConfig().
280//         WithRegion("us-west-2"),
281//     )
282func NewConfig() *Config {
283	return &Config{}
284}
285
286// WithCredentialsChainVerboseErrors sets a config verbose errors boolean and returning
287// a Config pointer.
288func (c *Config) WithCredentialsChainVerboseErrors(verboseErrs bool) *Config {
289	c.CredentialsChainVerboseErrors = &verboseErrs
290	return c
291}
292
293// WithCredentials sets a config Credentials value returning a Config pointer
294// for chaining.
295func (c *Config) WithCredentials(creds *credentials.Credentials) *Config {
296	c.Credentials = creds
297	return c
298}
299
300// WithEndpoint sets a config Endpoint value returning a Config pointer for
301// chaining.
302func (c *Config) WithEndpoint(endpoint string) *Config {
303	c.Endpoint = &endpoint
304	return c
305}
306
307// WithEndpointResolver sets a config EndpointResolver value returning a
308// Config pointer for chaining.
309func (c *Config) WithEndpointResolver(resolver endpoints.Resolver) *Config {
310	c.EndpointResolver = resolver
311	return c
312}
313
314// WithRegion sets a config Region value returning a Config pointer for
315// chaining.
316func (c *Config) WithRegion(region string) *Config {
317	c.Region = &region
318	return c
319}
320
321// WithDisableSSL sets a config DisableSSL value returning a Config pointer
322// for chaining.
323func (c *Config) WithDisableSSL(disable bool) *Config {
324	c.DisableSSL = &disable
325	return c
326}
327
328// WithHTTPClient sets a config HTTPClient value returning a Config pointer
329// for chaining.
330func (c *Config) WithHTTPClient(client *http.Client) *Config {
331	c.HTTPClient = client
332	return c
333}
334
335// WithMaxRetries sets a config MaxRetries value returning a Config pointer
336// for chaining.
337func (c *Config) WithMaxRetries(max int) *Config {
338	c.MaxRetries = &max
339	return c
340}
341
342// WithDisableParamValidation sets a config DisableParamValidation value
343// returning a Config pointer for chaining.
344func (c *Config) WithDisableParamValidation(disable bool) *Config {
345	c.DisableParamValidation = &disable
346	return c
347}
348
349// WithDisableComputeChecksums sets a config DisableComputeChecksums value
350// returning a Config pointer for chaining.
351func (c *Config) WithDisableComputeChecksums(disable bool) *Config {
352	c.DisableComputeChecksums = &disable
353	return c
354}
355
356// WithLogLevel sets a config LogLevel value returning a Config pointer for
357// chaining.
358func (c *Config) WithLogLevel(level LogLevelType) *Config {
359	c.LogLevel = &level
360	return c
361}
362
363// WithLogger sets a config Logger value returning a Config pointer for
364// chaining.
365func (c *Config) WithLogger(logger Logger) *Config {
366	c.Logger = logger
367	return c
368}
369
370// WithS3ForcePathStyle sets a config S3ForcePathStyle value returning a Config
371// pointer for chaining.
372func (c *Config) WithS3ForcePathStyle(force bool) *Config {
373	c.S3ForcePathStyle = &force
374	return c
375}
376
377// WithS3Disable100Continue sets a config S3Disable100Continue value returning
378// a Config pointer for chaining.
379func (c *Config) WithS3Disable100Continue(disable bool) *Config {
380	c.S3Disable100Continue = &disable
381	return c
382}
383
384// WithS3UseAccelerate sets a config S3UseAccelerate value returning a Config
385// pointer for chaining.
386func (c *Config) WithS3UseAccelerate(enable bool) *Config {
387	c.S3UseAccelerate = &enable
388	return c
389
390}
391
392// WithS3DisableContentMD5Validation sets a config
393// S3DisableContentMD5Validation value returning a Config pointer for chaining.
394func (c *Config) WithS3DisableContentMD5Validation(enable bool) *Config {
395	c.S3DisableContentMD5Validation = &enable
396	return c
397
398}
399
400// WithS3UseARNRegion sets a config S3UseARNRegion value and
401// returning a Config pointer for chaining
402func (c *Config) WithS3UseARNRegion(enable bool) *Config {
403	c.S3UseARNRegion = &enable
404	return c
405}
406
407// WithUseDualStack sets a config UseDualStack value returning a Config
408// pointer for chaining.
409func (c *Config) WithUseDualStack(enable bool) *Config {
410	c.UseDualStack = &enable
411	return c
412}
413
414// WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value
415// returning a Config pointer for chaining.
416func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config {
417	c.EC2MetadataDisableTimeoutOverride = &enable
418	return c
419}
420
421// WithSleepDelay overrides the function used to sleep while waiting for the
422// next retry. Defaults to time.Sleep.
423func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config {
424	c.SleepDelay = fn
425	return c
426}
427
428// WithEndpointDiscovery will set whether or not to use endpoint discovery.
429func (c *Config) WithEndpointDiscovery(t bool) *Config {
430	c.EnableEndpointDiscovery = &t
431	return c
432}
433
434// WithDisableEndpointHostPrefix will set whether or not to use modeled host prefix
435// when making requests.
436func (c *Config) WithDisableEndpointHostPrefix(t bool) *Config {
437	c.DisableEndpointHostPrefix = &t
438	return c
439}
440
441// WithSTSRegionalEndpoint will set whether or not to use regional endpoint flag
442// when resolving the endpoint for a service
443func (c *Config) WithSTSRegionalEndpoint(sre endpoints.STSRegionalEndpoint) *Config {
444	c.STSRegionalEndpoint = sre
445	return c
446}
447
448// WithS3UsEast1RegionalEndpoint will set whether or not to use regional endpoint flag
449// when resolving the endpoint for a service
450func (c *Config) WithS3UsEast1RegionalEndpoint(sre endpoints.S3UsEast1RegionalEndpoint) *Config {
451	c.S3UsEast1RegionalEndpoint = sre
452	return c
453}
454
455// WithLowerCaseHeaderMaps sets a config LowerCaseHeaderMaps value
456// returning a Config pointer for chaining.
457func (c *Config) WithLowerCaseHeaderMaps(t bool) *Config {
458	c.LowerCaseHeaderMaps = &t
459	return c
460}
461
462// WithDisableRestProtocolURICleaning sets a config DisableRestProtocolURICleaning value
463// returning a Config pointer for chaining.
464func (c *Config) WithDisableRestProtocolURICleaning(t bool) *Config {
465	c.DisableRestProtocolURICleaning = &t
466	return c
467}
468
469// MergeIn merges the passed in configs into the existing config object.
470func (c *Config) MergeIn(cfgs ...*Config) {
471	for _, other := range cfgs {
472		mergeInConfig(c, other)
473	}
474}
475
476func mergeInConfig(dst *Config, other *Config) {
477	if other == nil {
478		return
479	}
480
481	if other.CredentialsChainVerboseErrors != nil {
482		dst.CredentialsChainVerboseErrors = other.CredentialsChainVerboseErrors
483	}
484
485	if other.Credentials != nil {
486		dst.Credentials = other.Credentials
487	}
488
489	if other.Endpoint != nil {
490		dst.Endpoint = other.Endpoint
491	}
492
493	if other.EndpointResolver != nil {
494		dst.EndpointResolver = other.EndpointResolver
495	}
496
497	if other.Region != nil {
498		dst.Region = other.Region
499	}
500
501	if other.DisableSSL != nil {
502		dst.DisableSSL = other.DisableSSL
503	}
504
505	if other.HTTPClient != nil {
506		dst.HTTPClient = other.HTTPClient
507	}
508
509	if other.LogLevel != nil {
510		dst.LogLevel = other.LogLevel
511	}
512
513	if other.Logger != nil {
514		dst.Logger = other.Logger
515	}
516
517	if other.MaxRetries != nil {
518		dst.MaxRetries = other.MaxRetries
519	}
520
521	if other.Retryer != nil {
522		dst.Retryer = other.Retryer
523	}
524
525	if other.DisableParamValidation != nil {
526		dst.DisableParamValidation = other.DisableParamValidation
527	}
528
529	if other.DisableComputeChecksums != nil {
530		dst.DisableComputeChecksums = other.DisableComputeChecksums
531	}
532
533	if other.S3ForcePathStyle != nil {
534		dst.S3ForcePathStyle = other.S3ForcePathStyle
535	}
536
537	if other.S3Disable100Continue != nil {
538		dst.S3Disable100Continue = other.S3Disable100Continue
539	}
540
541	if other.S3UseAccelerate != nil {
542		dst.S3UseAccelerate = other.S3UseAccelerate
543	}
544
545	if other.S3DisableContentMD5Validation != nil {
546		dst.S3DisableContentMD5Validation = other.S3DisableContentMD5Validation
547	}
548
549	if other.S3UseARNRegion != nil {
550		dst.S3UseARNRegion = other.S3UseARNRegion
551	}
552
553	if other.UseDualStack != nil {
554		dst.UseDualStack = other.UseDualStack
555	}
556
557	if other.EC2MetadataDisableTimeoutOverride != nil {
558		dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride
559	}
560
561	if other.SleepDelay != nil {
562		dst.SleepDelay = other.SleepDelay
563	}
564
565	if other.DisableRestProtocolURICleaning != nil {
566		dst.DisableRestProtocolURICleaning = other.DisableRestProtocolURICleaning
567	}
568
569	if other.EnforceShouldRetryCheck != nil {
570		dst.EnforceShouldRetryCheck = other.EnforceShouldRetryCheck
571	}
572
573	if other.EnableEndpointDiscovery != nil {
574		dst.EnableEndpointDiscovery = other.EnableEndpointDiscovery
575	}
576
577	if other.DisableEndpointHostPrefix != nil {
578		dst.DisableEndpointHostPrefix = other.DisableEndpointHostPrefix
579	}
580
581	if other.STSRegionalEndpoint != endpoints.UnsetSTSEndpoint {
582		dst.STSRegionalEndpoint = other.STSRegionalEndpoint
583	}
584
585	if other.S3UsEast1RegionalEndpoint != endpoints.UnsetS3UsEast1Endpoint {
586		dst.S3UsEast1RegionalEndpoint = other.S3UsEast1RegionalEndpoint
587	}
588
589	if other.LowerCaseHeaderMaps != nil {
590		dst.LowerCaseHeaderMaps = other.LowerCaseHeaderMaps
591	}
592}
593
594// Copy will return a shallow copy of the Config object. If any additional
595// configurations are provided they will be merged into the new config returned.
596func (c *Config) Copy(cfgs ...*Config) *Config {
597	dst := &Config{}
598	dst.MergeIn(c)
599
600	for _, cfg := range cfgs {
601		dst.MergeIn(cfg)
602	}
603
604	return dst
605}
606