func (s *Session) ClientConfig(service string, cfgs ...*aws.Config) client.Config {
	s = s.Copy(cfgs...)
	region := aws.StringValue(s.Config.Region)
	resolved, err := s.resolveEndpoint(service, region, s.Config)
	if err != nil && s.Config.Logger != nil {
		s.Config.Logger.Log(fmt.Sprintf(
			"ERROR: unable to resolve endpoint for service %q, region %q, err: %v",
			service, region, err))
	}
	return client.Config{
		Config:             s.Config,
		Handlers:           s.Handlers,
		Endpoint:           resolved.URL,
		SigningRegion:      resolved.SigningRegion,
		SigningNameDerived: resolved.SigningNameDerived,
		SigningName:        resolved.SigningName,
	}
}
ClientConfig satisfies the client.ConfigProvider interface and is used to
configure the service client instances. Passing the Session to the service
client's constructor (New) will use this method to configure the client.
package session
import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"time"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/client"
	"github.com/aws/aws-sdk-go/aws/corehandlers"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/csm"
	"github.com/aws/aws-sdk-go/aws/defaults"
	"github.com/aws/aws-sdk-go/aws/endpoints"
	"github.com/aws/aws-sdk-go/aws/request"
)
const (
	ErrCodeSharedConfig = "SharedConfigErr"
)
var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only source profile or credential source can be specified, not both", nil)
var ErrSharedConfigECSContainerEnvVarEmpty = awserr.New(ErrCodeSharedConfig, "EcsContainer was specified as the credential_source, but 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI' was not set", nil)
var ErrSharedConfigInvalidCredSource = awserr.New(ErrCodeSharedConfig, "credential source values must be EcsContainer, Ec2InstanceMetadata, or Environment", nil)
type Session struct {
	Config   *aws.Config
	Handlers request.Handlers
}
func New(cfgs ...*aws.Config) *Session {
	envCfg, envErr := loadEnvConfig()
	if envCfg.EnableSharedConfig {
		var cfg aws.Config
		cfg.MergeIn(cfgs...)
		s, err := NewSessionWithOptions(Options{
			Config:            cfg,
			SharedConfigState: SharedConfigEnable,
		})
		if err != nil {
			msg := "failed to create session with AWS_SDK_LOAD_CONFIG enabled. " +
				"Use session.NewSession to handle errors occurring during session creation."
			s = &Session{Config: defaults.Config()}
			s.logDeprecatedNewSessionError(msg, err, cfgs)
		}
		return s
	}
	s := deprecatedNewSession(cfgs...)
	if envErr != nil {
		msg := "failed to load env config"
		s.logDeprecatedNewSessionError(msg, envErr, cfgs)
	}
	if csmCfg, err := loadCSMConfig(envCfg, []string{}); err != nil {
		if l := s.Config.Logger; l != nil {
			l.Log(fmt.Sprintf("ERROR: failed to load CSM configuration, %v", err))
		}
	} else if csmCfg.Enabled {
		err := enableCSM(&s.Handlers, csmCfg, s.Config.Logger)
		if err != nil {
			msg := "failed to enable CSM"
			s.logDeprecatedNewSessionError(msg, err, cfgs)
		}
	}
	return s
}
func NewSession(cfgs ...*aws.Config) (*Session, error) {
	opts := Options{}
	opts.Config.MergeIn(cfgs...)
	return NewSessionWithOptions(opts)
}
type SharedConfigState int
const (
	SharedConfigStateFromEnv SharedConfigState = iota
	SharedConfigDisable
	SharedConfigEnable
)
type Options struct {
	Config aws.Config
	Profile string
	SharedConfigState SharedConfigState
	SharedConfigFiles []string
	AssumeRoleTokenProvider func() (string, error)
	AssumeRoleDuration time.Duration
	CustomCABundle io.Reader
	Handlers request.Handlers
}
func NewSessionWithOptions(opts Options) (*Session, error) {
	var envCfg envConfig
	var err error
	if opts.SharedConfigState == SharedConfigEnable {
		envCfg, err = loadSharedEnvConfig()
		if err != nil {
			return nil, fmt.Errorf("failed to load shared config, %v", err)
		}
	} else {
		envCfg, err = loadEnvConfig()
		if err != nil {
			return nil, fmt.Errorf("failed to load environment config, %v", err)
		}
	}
	if len(opts.Profile) != 0 {
		envCfg.Profile = opts.Profile
	}
	switch opts.SharedConfigState {
	case SharedConfigDisable:
		envCfg.EnableSharedConfig = false
	case SharedConfigEnable:
		envCfg.EnableSharedConfig = true
	}
	if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil {
		f, err := os.Open(envCfg.CustomCABundle)
		if err != nil {
			return nil, awserr.New("LoadCustomCABundleError",
				"failed to open custom CA bundle PEM file", err)
		}
		defer f.Close()
		opts.CustomCABundle = f
	}
	return newSession(opts, envCfg, &opts.Config)
}
func Must(sess *Session, err error) *Session {
	if err != nil {
		panic(err)
	}
	return sess
}
func deprecatedNewSession(cfgs ...*aws.Config) *Session {
	cfg := defaults.Config()
	handlers := defaults.Handlers()
	cfg.MergeIn(cfgs...)
	if cfg.EndpointResolver == nil {
		cfg.EndpointResolver = endpoints.DefaultResolver()
	}
	cfg.Credentials = defaults.CredChain(cfg, handlers)
	cfg.MergeIn(cfgs...)
	s := &Session{
		Config:   cfg,
		Handlers: handlers,
	}
	initHandlers(s)
	return s
}
func enableCSM(handlers *request.Handlers, cfg csmConfig, logger aws.Logger) error {
	if logger != nil {
		logger.Log("Enabling CSM")
	}
	r, err := csm.Start(cfg.ClientID, csm.AddressWithDefaults(cfg.Host, cfg.Port))
	if err != nil {
		return err
	}
	r.InjectHandlers(handlers)
	return nil
}
func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) {
	cfg := defaults.Config()
	handlers := opts.Handlers
	if handlers.IsEmpty() {
		handlers = defaults.Handlers()
	}
	userCfg := &aws.Config{}
	userCfg.MergeIn(cfgs...)
	cfg.MergeIn(userCfg)
	var cfgFiles []string
	if opts.SharedConfigFiles != nil {
		cfgFiles = opts.SharedConfigFiles
	} else {
		cfgFiles = []string{envCfg.SharedConfigFile, envCfg.SharedCredentialsFile}
		if !envCfg.EnableSharedConfig {
			cfgFiles = cfgFiles[1:]
		}
	}
	sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles, envCfg.EnableSharedConfig)
	if err != nil {
		if len(envCfg.Profile) == 0 && !envCfg.EnableSharedConfig && (envCfg.Creds.HasKeys() || userCfg.Credentials != nil) {
		} else if _, ok := err.(SharedConfigProfileNotExistsError); !ok {
			return nil, err
		}
	}
	if err := mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers, opts); err != nil {
		return nil, err
	}
	s := &Session{
		Config:   cfg,
		Handlers: handlers,
	}
	initHandlers(s)
	if csmCfg, err := loadCSMConfig(envCfg, cfgFiles); err != nil {
		if l := s.Config.Logger; l != nil {
			l.Log(fmt.Sprintf("ERROR: failed to load CSM configuration, %v", err))
		}
	} else if csmCfg.Enabled {
		err = enableCSM(&s.Handlers, csmCfg, s.Config.Logger)
		if err != nil {
			return nil, err
		}
	}
	if opts.CustomCABundle != nil {
		if err := loadCustomCABundle(s, opts.CustomCABundle); err != nil {
			return nil, err
		}
	}
	return s, nil
}
type csmConfig struct {
	Enabled  bool
	Host     string
	Port     string
	ClientID string
}
var csmProfileName = "aws_csm"
func loadCSMConfig(envCfg envConfig, cfgFiles []string) (csmConfig, error) {
	if envCfg.CSMEnabled != nil {
		if *envCfg.CSMEnabled {
			return csmConfig{
				Enabled:  true,
				ClientID: envCfg.CSMClientID,
				Host:     envCfg.CSMHost,
				Port:     envCfg.CSMPort,
			}, nil
		}
		return csmConfig{}, nil
	}
	sharedCfg, err := loadSharedConfig(csmProfileName, cfgFiles, false)
	if err != nil {
		if _, ok := err.(SharedConfigProfileNotExistsError); !ok {
			return csmConfig{}, err
		}
	}
	if sharedCfg.CSMEnabled != nil && *sharedCfg.CSMEnabled == true {
		return csmConfig{
			Enabled:  true,
			ClientID: sharedCfg.CSMClientID,
			Host:     sharedCfg.CSMHost,
			Port:     sharedCfg.CSMPort,
		}, nil
	}
	return csmConfig{}, nil
}
func loadCustomCABundle(s *Session, bundle io.Reader) error {
	var t *http.Transport
	switch v := s.Config.HTTPClient.Transport.(type) {
	case *http.Transport:
		t = v
	default:
		if s.Config.HTTPClient.Transport != nil {
			return awserr.New("LoadCustomCABundleError",
				"unable to load custom CA bundle, HTTPClient's transport unsupported type", nil)
		}
	}
	if t == nil {
		t = getCABundleTransport()
	}
	p, err := loadCertPool(bundle)
	if err != nil {
		return err
	}
	if t.TLSClientConfig == nil {
		t.TLSClientConfig = &tls.Config{}
	}
	t.TLSClientConfig.RootCAs = p
	s.Config.HTTPClient.Transport = t
	return nil
}
func loadCertPool(r io.Reader) (*x509.CertPool, error) {
	b, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, awserr.New("LoadCustomCABundleError",
			"failed to read custom CA bundle PEM file", err)
	}
	p := x509.NewCertPool()
	if !p.AppendCertsFromPEM(b) {
		return nil, awserr.New("LoadCustomCABundleError",
			"failed to load custom CA bundle PEM file", err)
	}
	return p, nil
}
func mergeConfigSrcs(cfg, userCfg *aws.Config,
	envCfg envConfig, sharedCfg sharedConfig,
	handlers request.Handlers,
	sessOpts Options,
) error {
	if len(aws.StringValue(cfg.Region)) == 0 {
		if len(envCfg.Region) > 0 {
			cfg.WithRegion(envCfg.Region)
		} else if envCfg.EnableSharedConfig && len(sharedCfg.Region) > 0 {
			cfg.WithRegion(sharedCfg.Region)
		}
	}
	if cfg.EnableEndpointDiscovery == nil {
		if envCfg.EnableEndpointDiscovery != nil {
			cfg.WithEndpointDiscovery(*envCfg.EnableEndpointDiscovery)
		} else if envCfg.EnableSharedConfig && sharedCfg.EnableEndpointDiscovery != nil {
			cfg.WithEndpointDiscovery(*sharedCfg.EnableEndpointDiscovery)
		}
	}
	mergeSTSRegionalEndpointConfig(cfg, []endpoints.STSRegionalEndpoint{
		userCfg.STSRegionalEndpoint,
		envCfg.STSRegionalEndpoint,
		sharedCfg.STSRegionalEndpoint,
		endpoints.LegacySTSEndpoint,
	})
	mergeS3UsEast1RegionalEndpointConfig(cfg, []endpoints.S3UsEast1RegionalEndpoint{
		userCfg.S3UsEast1RegionalEndpoint,
		envCfg.S3UsEast1RegionalEndpoint,
		sharedCfg.S3UsEast1RegionalEndpoint,
		endpoints.LegacyS3UsEast1Endpoint,
	})
	if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
		creds, err := resolveCredentials(cfg, envCfg, sharedCfg, handlers, sessOpts)
		if err != nil {
			return err
		}
		cfg.Credentials = creds
	}
	return nil
}
func mergeSTSRegionalEndpointConfig(cfg *aws.Config, values []endpoints.STSRegionalEndpoint) {
	for _, v := range values {
		if v != endpoints.UnsetSTSEndpoint {
			cfg.STSRegionalEndpoint = v
			break
		}
	}
}
func mergeS3UsEast1RegionalEndpointConfig(cfg *aws.Config, values []endpoints.S3UsEast1RegionalEndpoint) {
	for _, v := range values {
		if v != endpoints.UnsetS3UsEast1Endpoint {
			cfg.S3UsEast1RegionalEndpoint = v
			break
		}
	}
}
func initHandlers(s *Session) {
	s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler)
	if !aws.BoolValue(s.Config.DisableParamValidation) {
		s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler)
	}
}
func (s *Session) Copy(cfgs ...*aws.Config) *Session {
	newSession := &Session{
		Config:   s.Config.Copy(cfgs...),
		Handlers: s.Handlers.Copy(),
	}
	initHandlers(newSession)
	return newSession
}