func (s *metadataCredentialService) ecsCredHandler(w http.ResponseWriter, r *http.Request) {
	var creds *credentials.Credentials
	var err error
	cl := s.awsClient
	if cl == nil {
		cl, err = s.clientFactory.Get(s.awsConfig)
		if err != nil {
			s.handleAuthError(err, w)
			return
		}
	}
	if s.options.Path != r.URL.Path {
		parts := strings.Split(r.URL.Path, `/`)
		profile := parts[len(parts)-1]
		var cfg *config.AwsConfig
		cfg, cl, err = s.getConfigAndClient(profile)
		if err != nil {
			logger.Errorf("Client fetch: %v", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		if cfg.SamlProvider == "mock" {
			cl = s.awsClient
		}
	}
	creds, err = cl.Credentials()
	if err != nil {
		s.handleAuthError(err, w)
		return
	}
	ecsCreds, _ := creds.ECS()  
	logger.Debugf("ECS CREDS: %s", ecsCreds)
	w.Header().Set("Content-Type", "application/json")
	_, _ = w.Write(ecsCreds)
}
Extend the behavior of the ECS credential endpoint so it accepts additional path elements beyond the
base path configured for the handler.  Any extra path information is interpreted as a profile name
for fetching credentials.  The "standard" behavior still works as expected, and calls to the base path
will return credentials for the profile specified at startup, or the profile configured via the /profile
endpoint.  But now something like: http://127.0.0.1:54321/credentials/my_profile will get credentials
for 'my_profile', instead of the "global" profile.  This will enable folks to set the
AWS_CONTAINER_CREDENTIALS_FULL_URI environment variable to context-specific profiles without needing to
run dedicated services for each profile.
package metadata
import (
	"context"
	"embed"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/aws/smithy-go/logging"
	"github.com/mmmorris1975/aws-runas/client"
	"github.com/mmmorris1975/aws-runas/config"
	"github.com/mmmorris1975/aws-runas/credentials"
	"github.com/mmmorris1975/aws-runas/credentials/helpers"
	"github.com/mmmorris1975/aws-runas/shared"
	"github.com/syndtr/gocapability/capability"
	"io"
	"net"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"os/signal"
	"runtime"
	"strings"
	"sync"
	"syscall"
	"text/template"
)
const (
	DefaultEcsCredPath = "/credentials"
	DefaultEc2ImdsAddr = "169.254.169.254"
	DefaultEc2ImdsCidr = DefaultEc2ImdsAddr + "/22"
	imdsv2TtlHdr = "X-Aws-Ec2-Metadata-Token-Ttl-Seconds"
	imdsTokenPath    = "/latest/api/token"  
	ec2CredPath      = "/latest/meta-data/iam/security-credentials/"
	authPath         = "/auth"
	mfaPath          = "/mfa"
	profilePath      = "/profile"
	newProfilePath   = "/profile/custom"
	listRolesPath    = "/list-roles"
	listProfilesPath = "/list-profiles"
	refreshPath      = "/refresh"
)
var (
	logger shared.Logger = new(shared.DefaultLogger)
	content embed.FS
	mu sync.Mutex  
	indexHtml, siteCss, favicon []byte
)
type Options struct {
	Path        string
	Profile     string
	Logger      shared.Logger
	AwsLogLevel logging.Classification
	Headless    bool
}
type metadataCredentialService struct {
	options        *Options
	awsClient      client.AwsClient
	awsConfig      *config.AwsConfig
	configResolver config.Resolver
	clientFactory  *client.Factory
	clientOptions  *client.Options
	listener       net.Listener
}
func NewMetadataCredentialService(addr string, opts *Options) (*metadataCredentialService, error) {
	mcs := new(metadataCredentialService)
	mcs.options = opts
	if opts.Logger != nil {
		logger = opts.Logger
	}
	mcs.configResolver = config.DefaultResolver.WithLogger(logger)
	mcs.clientOptions = client.DefaultOptions
	mcs.clientOptions.Logger = logger
	mcs.clientOptions.AwsLogLevel = opts.AwsLogLevel
	var err error
	if strings.HasPrefix(addr, DefaultEc2ImdsAddr) && os.Getuid() != 0 && runtime.GOOS == "linux" {
		logger.Debugf("enabling Linux capabilities")
		if err = linuxSetCap(); err != nil {
			return nil, err
		}
	}
	mcs.listener, err = configureListener(addr)
	if err != nil {
		return nil, err
	}
	indexHtml, err = content.ReadFile("templates/index.html")
	if err != nil {
		return nil, err
	}
	siteCss, err = content.ReadFile("templates/site.css")
	if err != nil {
		return nil, err
	}
	favicon, err = content.ReadFile("templates/favicon.ico")
	if err != nil {
		return nil, err
	}
	return mcs, nil
}
func (s *metadataCredentialService) Addr() net.Addr {
	return s.listener.Addr()
}
func (s *metadataCredentialService) Run() error {
	s.clientFactory = client.NewClientFactory(s.configResolver, s.clientOptions)
	mux := http.NewServeMux()
	mux.HandleFunc("/", logHandler(s.rootHandler))
	mux.HandleFunc(authPath, logHandler(s.authHandler))
	mux.HandleFunc(mfaPath, logHandler(s.mfaHandler))
	mux.HandleFunc(profilePath, logHandler(s.profileHandler))
	mux.HandleFunc(listRolesPath, logHandler(s.listRolesHandler))
	mux.HandleFunc(refreshPath, logHandler(s.refreshHandler))
	mux.HandleFunc(imdsTokenPath, logHandler(s.imdsV2TokenHandler))
	mux.HandleFunc(ec2CredPath, logHandler(s.ec2CredHandler))
	mux.HandleFunc(newProfilePath, logHandler(s.customProfileHandler))
	mux.HandleFunc(listProfilesPath, logHandler(s.listProfilesHandler))
	if len(s.options.Path) > 0 {
		mux.HandleFunc(s.options.Path, logHandler(s.ecsCredHandler))
		mux.HandleFunc(s.options.Path+`/`, logHandler(s.ecsCredHandler))
		logger.Infof("ECS credential endpoint set to http://%s%s", s.Addr().String(), s.options.Path)
		logger.Infof("Set the AWS_CONTAINER_CREDENTIALS_FULL_URI environment variable with the above value to allow programs to use it")
	} else if !strings.HasPrefix(s.listener.Addr().String(), DefaultEc2ImdsAddr) {
		logger.Infof("EC2 metadata endpoint set to http://%s/", s.Addr().String())
		logger.Infof("Set the AWS_EC2_METADATA_SERVICE_ENDPOINT environment variable with the above value to allow programs to use it")
	}
	if len(s.options.Profile) > 0 {
		r, _ := http.NewRequestWithContext(context.Background(), http.MethodPost, profilePath,
			strings.NewReader(s.options.Profile))
		s.profileHandler(httptest.NewRecorder(), r)
		logger.Infof("Using initial profile '%s'", s.options.Profile)
	} else {
		logger.Infof("Access the web interface at http://%s and select a profile to begin", s.Addr().String())
	}
	if !s.options.Headless {
		s.clientOptions.MfaInputProvider = func() (string, error) {
			return "", NewWebMfaRequiredError()
		}
		s.clientOptions.CredentialInputProvider = func(_ string, _ string) (string, string, error) {
			return "", "", NewWebAuthenticationError()
		}
	}
	srv := new(http.Server)
	srv.Handler = mux
	defer cleanup(srv, s.listener)
	installSigHandler(srv, s.listener)
	return srv.Serve(s.listener)
}
func (s *metadataCredentialService) RunNoApi(cl client.AwsClient, cfg *config.AwsConfig, readyCh chan<- bool) error {
	s.clientOptions.MfaInputProvider = helpers.NewMfaTokenProvider(os.Stdin).ReadInput
	s.clientOptions.CredentialInputProvider = helpers.NewUserPasswordInputProvider(os.Stdin).ReadInput
	s.clientFactory = client.NewClientFactory(s.configResolver, s.clientOptions)
	s.awsClient = cl
	s.awsConfig = cfg
	mux := http.NewServeMux()
	mux.HandleFunc(profilePath, s.profileHandler)
	mux.HandleFunc(imdsTokenPath, s.imdsV2TokenHandler)
	mux.HandleFunc(ec2CredPath, s.ec2CredHandler)
	if len(s.options.Path) > 0 {
		mux.HandleFunc(s.options.Path, s.ecsCredHandler)
		mux.HandleFunc(s.options.Path+`/`, s.ecsCredHandler)
		logger.Debugf("ECS credential endpoint set to http://%s%s", s.Addr().String(), s.options.Path)
	} else if !strings.HasPrefix(s.listener.Addr().String(), DefaultEc2ImdsAddr) {
		logger.Debugf("EC2 metadata endpoint set to http://%s/", s.Addr().String())
	}
	srv := new(http.Server)
	srv.Handler = mux
	defer cleanup(srv, s.listener)
	if readyCh != nil {
		readyCh <- true
	}
	return srv.Serve(s.listener)
}
func (s *metadataCredentialService) rootHandler(w http.ResponseWriter, r *http.Request) {
	switch r.URL.Path {
	case "/", "/index.html", "/index.htm":
		w.Header().Set("Content-Type", "text/html")
		_, _ = w.Write(indexHtml)
	case "/site.js":
		params := map[string]string{
			"profile_ep":  profilePath,
			"roles_ep":    listRolesPath,
			"auth_ep":     authPath,
			"mfa_ep":      mfaPath,
			"custom_ep":   newProfilePath,
			"profiles_ep": listProfilesPath,
			"refresh_ep":  refreshPath,
		}
		tmpl := template.Must(template.ParseFS(content, "templates/site.js"))
		w.Header().Set("Content-Type", "application/javascript")
		if err := tmpl.Execute(w, params); err != nil {
			logger.Errorf("error executing template: %v", err)
		}
	case "/site.css":
		w.Header().Set("Content-Type", "text/css")
		_, _ = w.Write(siteCss)
	case "/favicon.ico":
		w.Header().Set("Content-Type", "image/png")
		_, _ = w.Write(favicon)
	default:
		http.NotFound(w, r)
	}
}
func (s *metadataCredentialService) profileHandler(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	if r.Method == http.MethodPost {
		buf := make([]byte, 256)  
		n, err := r.Body.Read(buf)
		if err != nil && !errors.Is(err, io.EOF) {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		profile := string(buf[:n])
		s.awsConfig, s.awsClient, err = s.getConfigAndClient(profile)
		if err != nil {
			s.handleAuthError(err, w)
			return
		}
		if _, err = s.awsClient.Credentials(); err != nil {
			s.handleAuthError(err, w)
			return
		}
		logger.Debugf("updated profile to %s", s.awsConfig.ProfileName)
	} else {
		if s.awsConfig == nil || len(s.awsConfig.ProfileName) < 1 {
			http.Error(w, "profile not set", http.StatusInternalServerError)
			return
		}
		logger.Debugf("profile: %s", s.awsConfig.ProfileName)
	}
	_, _ = w.Write(marshalProfile(s.awsConfig))
}
func marshalProfile(cfg *config.AwsConfig) []byte {
	authUrl := cfg.SamlUrl
	username := cfg.SamlUsername
	if len(cfg.WebIdentityClientId) > 0 {
		authUrl = cfg.WebIdentityUrl
		username = cfg.WebIdentityUsername
	}
	profile := map[string]string{
		"role_arn":     cfg.RoleArn,
		"external_id":  cfg.ExternalId,
		"auth_url":     authUrl,
		"username":     username,
		"jump_role":    cfg.JumpRoleArn,
		"client_id":    cfg.WebIdentityClientId,
		"redirect_uri": cfg.WebIdentityRedirectUri,
	}
	if cfg.SourceProfile() != nil {
		profile["source_profile"] = cfg.SourceProfile().ProfileName
	}
	j, _ := json.Marshal(profile)
	return j
}
func (s *metadataCredentialService) imdsV2TokenHandler(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	if r.Method == http.MethodPut && len(r.Header.Get(imdsv2TtlHdr)) > 0 {
		w.Header().Set("Content-Type", "text/plain")
		w.Header().Set(imdsv2TtlHdr, r.Header.Get(imdsv2TtlHdr))
		_, _ = w.Write([]byte("IamNOTaRealBoy!"))
		return
	}
	http.Error(w, "Not Implemented", http.StatusMethodNotAllowed)
}
func (s *metadataCredentialService) ec2CredHandler(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	p := strings.Split(r.URL.Path, "/")[1:]
	if len(p[len(p)-1]) < 1 {
		_, _ = w.Write([]byte(s.awsConfig.ProfileName))
	} else {
		creds, err := s.awsClient.Credentials()
		if err != nil {
			s.handleAuthError(err, w)
			return
		}
		ec2Creds, _ := creds.EC2()  
		logger.Debugf("EC2 CREDS: %s", ec2Creds)
		w.Header().Set("Content-Type", "application/json")
		_, _ = w.Write(ec2Creds)
	}
}