httpheaders.go

 1// Package httpheaders provides shared User-Agent resolution for all HTTP-based providers.
 2package httpheaders
 3
 4import "strings"
 5
 6// DefaultUserAgent returns the default User-Agent string for the SDK.
 7// The result is "Charm Fantasy/<version>".
 8func DefaultUserAgent(version string) string {
 9	return "Charm Fantasy/" + version
10}
11
12// ResolveHeaders returns a new header map with User-Agent resolved according to precedence:
13//  1. explicitUA (highest — set via WithUserAgent)
14//  2. existing User-Agent key in headers (case-insensitive — set via WithHeaders)
15//  3. defaultUA (lowest — generated default)
16//
17// The input map is never mutated.
18func ResolveHeaders(headers map[string]string, explicitUA, defaultUA string) map[string]string {
19	out := make(map[string]string, len(headers)+1)
20	var uaKeys []string
21
22	for k, v := range headers {
23		out[k] = v
24		if strings.EqualFold(k, "User-Agent") {
25			uaKeys = append(uaKeys, k)
26		}
27	}
28
29	switch {
30	case explicitUA != "":
31		for _, k := range uaKeys {
32			delete(out, k)
33		}
34		out["User-Agent"] = explicitUA
35	case len(uaKeys) > 0:
36		// keep the header-map value as-is
37	default:
38		out["User-Agent"] = defaultUA
39	}
40
41	return out
42}
43
44// CallUserAgent resolves the User-Agent for a single API call. It returns the
45// resolved UA string and true if a per-call override should be applied, or
46// empty string and false if the client-level UA should be used as-is.
47func CallUserAgent(callUA string) (string, bool) {
48	if callUA != "" {
49		return callUA, true
50	}
51	return "", false
52}