...

Source file src/github.com/launchdarkly/go-server-sdk/v6/client_context_from_config.go

Documentation: github.com/launchdarkly/go-server-sdk/v6

     1  package ldclient
     2  
     3  import (
     4  	"errors"
     5  	"regexp"
     6  
     7  	"github.com/launchdarkly/go-sdk-common/v3/ldlog"
     8  	"github.com/launchdarkly/go-server-sdk/v6/internal"
     9  	"github.com/launchdarkly/go-server-sdk/v6/ldcomponents"
    10  	"github.com/launchdarkly/go-server-sdk/v6/subsystems"
    11  )
    12  
    13  var validTagKeyOrValueRegex = regexp.MustCompile(`(?s)^[\w.-]*$`)
    14  
    15  func newClientContextFromConfig(
    16  	sdkKey string,
    17  	config Config,
    18  ) (*internal.ClientContextImpl, error) {
    19  	if !stringIsValidHTTPHeaderValue(sdkKey) {
    20  		// We want to fail fast in this case, because if we got as far as trying to make an HTTP request
    21  		// to LaunchDarkly with a malformed key, the Go HTTP client unfortunately would include the
    22  		// actual Authorization header value in its error message, which could end up in logs - and the
    23  		// value might be a real SDK key that just has (for instance) a newline at the end of it, so it
    24  		// would be sensitive information.
    25  		return nil, errors.New("SDK key contains invalid characters")
    26  	}
    27  
    28  	basicConfig := subsystems.BasicClientContext{
    29  		SDKKey:           sdkKey,
    30  		Offline:          config.Offline,
    31  		ServiceEndpoints: config.ServiceEndpoints,
    32  	}
    33  
    34  	loggingFactory := config.Logging
    35  	if loggingFactory == nil {
    36  		loggingFactory = ldcomponents.Logging()
    37  	}
    38  	logging, err := loggingFactory.Build(basicConfig)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	basicConfig.Logging = logging
    43  
    44  	basicConfig.ApplicationInfo.ApplicationID = validateTagValue(config.ApplicationInfo.ApplicationID,
    45  		"ApplicationID", logging.Loggers)
    46  	basicConfig.ApplicationInfo.ApplicationVersion = validateTagValue(config.ApplicationInfo.ApplicationVersion,
    47  		"ApplicationVersion", logging.Loggers)
    48  
    49  	httpFactory := config.HTTP
    50  	if httpFactory == nil {
    51  		httpFactory = ldcomponents.HTTPConfiguration()
    52  	}
    53  	http, err := httpFactory.Build(basicConfig)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  	basicConfig.HTTP = http
    58  
    59  	return &internal.ClientContextImpl{BasicClientContext: basicConfig}, nil
    60  }
    61  
    62  func stringIsValidHTTPHeaderValue(s string) bool {
    63  	for _, ch := range s {
    64  		if ch < 32 || ch > 127 {
    65  			return false
    66  		}
    67  	}
    68  	return true
    69  }
    70  
    71  func validateTagValue(value, name string, loggers ldlog.Loggers) string {
    72  	if value == "" {
    73  		return ""
    74  	}
    75  	if len(value) > 64 {
    76  		loggers.Warnf("Value of Config.ApplicationInfo.%s was longer than 64 characters and was discarded", name)
    77  		return ""
    78  	}
    79  	if !validTagKeyOrValueRegex.MatchString(value) {
    80  		loggers.Warnf("Value of Config.ApplicationInfo.%s contained invalid characters and was discarded", name)
    81  		return ""
    82  	}
    83  	return value
    84  }
    85  

View as plain text