Skip to content

Commit cda3f0f

Browse files
authored
Don't Load GVL v1 for TCF2 (+ TCF1 Cleanup) (#1693)
1 parent 42ab0d6 commit cda3f0f

File tree

3 files changed

+86
-187
lines changed

3 files changed

+86
-187
lines changed

gdpr/gdpr.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ func NewPermissions(ctx context.Context, cfg config.GDPR, vendorIDs map[openrtb_
4444
cfg: cfg,
4545
vendorIDs: vendorIDs,
4646
fetchVendorList: map[uint8]func(ctx context.Context, id uint16) (vendorlist.VendorList, error){
47-
tcf1SpecVersion: newVendorListFetcher(ctx, cfg, client, vendorListURLMaker, tcf1SpecVersion),
48-
tcf2SpecVersion: newVendorListFetcher(ctx, cfg, client, vendorListURLMaker, tcf2SpecVersion)},
47+
tcf1SpecVersion: newVendorListFetcherTCF1(cfg),
48+
tcf2SpecVersion: newVendorListFetcherTCF2(ctx, cfg, client, vendorListURLMaker)},
4949
}
5050

5151
if cfg.HostVendorID == 0 {

gdpr/vendorlist-fetching.go

Lines changed: 39 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -26,30 +26,40 @@ type saveVendors func(uint16, api.VendorList)
2626
//
2727
// Nothing in this file is exported. Public APIs can be found in gdpr.go
2828

29-
func newVendorListFetcher(initCtx context.Context, cfg config.GDPR, client *http.Client, urlMaker func(uint16, uint8) string, tcfSpecVersion uint8) func(ctx context.Context, id uint16) (vendorlist.VendorList, error) {
30-
var fallback api.VendorList
31-
32-
if tcfSpecVersion == tcf1SpecVersion && len(cfg.TCF1.FallbackGVLPath) == 0 {
33-
return func(ctx context.Context, vendorListVersion uint16) (vendorlist.VendorList, error) {
29+
func newVendorListFetcherTCF1(cfg config.GDPR) func(ctx context.Context, id uint16) (vendorlist.VendorList, error) {
30+
if len(cfg.TCF1.FallbackGVLPath) == 0 {
31+
return func(_ context.Context, vendorListVersion uint16) (vendorlist.VendorList, error) {
3432
return nil, makeVendorListNotFoundError(vendorListVersion)
3533
}
3634
}
3735

38-
if tcfSpecVersion == tcf1SpecVersion {
39-
fallback = loadFallbackGVL(cfg.TCF1.FallbackGVLPath)
36+
fallback := loadFallbackGVLForTCF1(cfg.TCF1.FallbackGVLPath)
37+
return func(_ context.Context, _ uint16) (vendorlist.VendorList, error) {
38+
return fallback, nil
39+
}
40+
}
4041

41-
return func(ctx context.Context, vendorListVersion uint16) (vendorlist.VendorList, error) {
42-
return fallback, nil
43-
}
42+
func loadFallbackGVLForTCF1(fallbackGVLPath string) vendorlist.VendorList {
43+
fallbackContents, err := ioutil.ReadFile(fallbackGVLPath)
44+
if err != nil {
45+
glog.Fatalf("Error reading from file %s: %v", fallbackGVLPath, err)
46+
}
47+
48+
fallback, err := vendorlist.ParseEagerly(fallbackContents)
49+
if err != nil {
50+
glog.Fatalf("Error processing default GVL from %s: %v", fallbackGVLPath, err)
4451
}
52+
return fallback
53+
}
4554

46-
cacheSave, cacheLoad := newVendorListCache(fallback)
55+
func newVendorListFetcherTCF2(initCtx context.Context, cfg config.GDPR, client *http.Client, urlMaker func(uint16) string) func(ctx context.Context, id uint16) (vendorlist.VendorList, error) {
56+
cacheSave, cacheLoad := newVendorListCache()
4757

4858
preloadContext, cancel := context.WithTimeout(initCtx, cfg.Timeouts.InitTimeout())
4959
defer cancel()
50-
preloadCache(preloadContext, client, urlMaker, cacheSave, tcfSpecVersion)
60+
preloadCache(preloadContext, client, urlMaker, cacheSave)
5161

52-
saveOneRateLimited := newOccasionalSaver(cfg.Timeouts.ActiveTimeout(), tcfSpecVersion)
62+
saveOneRateLimited := newOccasionalSaver(cfg.Timeouts.ActiveTimeout())
5363
return func(ctx context.Context, vendorListVersion uint16) (vendorlist.VendorList, error) {
5464
// Attempt To Load From Cache
5565
if list := cacheLoad(vendorListVersion); list != nil {
@@ -58,19 +68,14 @@ func newVendorListFetcher(initCtx context.Context, cfg config.GDPR, client *http
5868

5969
// Attempt To Download
6070
// - May not add to cache immediately.
61-
saveOneRateLimited(ctx, client, urlMaker(vendorListVersion, tcfSpecVersion), cacheSave)
71+
saveOneRateLimited(ctx, client, urlMaker(vendorListVersion), cacheSave)
6272

6373
// Attempt To Load From Cache Again
6474
// - May have been added by the call to saveOneRateLimited.
6575
if list := cacheLoad(vendorListVersion); list != nil {
6676
return list, nil
6777
}
6878

69-
// Attempt To Use Hardcoded Fallback
70-
if fallback != nil {
71-
return fallback, nil
72-
}
73-
7479
// Give Up
7580
return nil, makeVendorListNotFoundError(vendorListVersion)
7681
}
@@ -81,35 +86,32 @@ func makeVendorListNotFoundError(vendorListVersion uint16) error {
8186
}
8287

8388
// preloadCache saves all the known versions of the vendor list for future use.
84-
func preloadCache(ctx context.Context, client *http.Client, urlMaker func(uint16, uint8) string, saver saveVendors, tcfSpecVersion uint8) {
85-
latestVersion := saveOne(ctx, client, urlMaker(0, tcfSpecVersion), saver, tcfSpecVersion)
89+
func preloadCache(ctx context.Context, client *http.Client, urlMaker func(uint16) string, saver saveVendors) {
90+
latestVersion := saveOne(ctx, client, urlMaker(0), saver)
8691

87-
for i := uint16(1); i < latestVersion; i++ {
88-
saveOne(ctx, client, urlMaker(i, tcfSpecVersion), saver, tcfSpecVersion)
92+
// The GVL for TCF2 has no vendors defined in its first version. It's very unlikely to be used, so don't preload it.
93+
firstVersionToLoad := uint16(2)
94+
95+
for i := firstVersionToLoad; i < latestVersion; i++ {
96+
saveOne(ctx, client, urlMaker(i), saver)
8997
}
9098
}
9199

92100
// Make a URL which can be used to fetch a given version of the Global Vendor List. If the version is 0,
93101
// this will fetch the latest version.
94-
func vendorListURLMaker(vendorListVersion uint16, tcfSpecVersion uint8) string {
95-
if tcfSpecVersion == tcf2SpecVersion {
96-
if vendorListVersion == 0 {
97-
return "https://vendor-list.consensu.org/v2/vendor-list.json"
98-
}
99-
return "https://vendor-list.consensu.org/v2/archives/vendor-list-v" + strconv.Itoa(int(vendorListVersion)) + ".json"
100-
}
102+
func vendorListURLMaker(vendorListVersion uint16) string {
101103
if vendorListVersion == 0 {
102-
return "https://vendor-list.consensu.org/vendorlist.json"
104+
return "https://vendor-list.consensu.org/v2/vendor-list.json"
103105
}
104-
return "https://vendor-list.consensu.org/v-" + strconv.Itoa(int(vendorListVersion)) + "/vendorlist.json"
106+
return "https://vendor-list.consensu.org/v2/archives/vendor-list-v" + strconv.Itoa(int(vendorListVersion)) + ".json"
105107
}
106108

107109
// newOccasionalSaver returns a wrapped version of saveOne() which only activates every few minutes.
108110
//
109111
// The goal here is to update quickly when new versions of the VendorList are released, but not wreck
110112
// server performance if a bad CMP starts sending us malformed consent strings that advertize a version
111113
// that doesn't exist yet.
112-
func newOccasionalSaver(timeout time.Duration, tcfSpecVersion uint8) func(ctx context.Context, client *http.Client, url string, saver saveVendors) {
114+
func newOccasionalSaver(timeout time.Duration) func(ctx context.Context, client *http.Client, url string, saver saveVendors) {
113115
lastSaved := &atomic.Value{}
114116
lastSaved.Store(time.Time{})
115117

@@ -120,13 +122,13 @@ func newOccasionalSaver(timeout time.Duration, tcfSpecVersion uint8) func(ctx co
120122
if timeSinceLastSave.Minutes() > 10 {
121123
withTimeout, cancel := context.WithTimeout(ctx, timeout)
122124
defer cancel()
123-
saveOne(withTimeout, client, url, saver, tcfSpecVersion)
125+
saveOne(withTimeout, client, url, saver)
124126
lastSaved.Store(now)
125127
}
126128
}
127129
}
128130

129-
func saveOne(ctx context.Context, client *http.Client, url string, saver saveVendors, tcfSpecVersion uint8) uint16 {
131+
func saveOne(ctx context.Context, client *http.Client, url string, saver saveVendors) uint16 {
130132
req, err := http.NewRequest("GET", url, nil)
131133
if err != nil {
132134
glog.Errorf("Failed to build GET %s request. Cookie syncs may be affected: %v", url, err)
@@ -150,11 +152,7 @@ func saveOne(ctx context.Context, client *http.Client, url string, saver saveVen
150152
return 0
151153
}
152154
var newList api.VendorList
153-
if tcfSpecVersion == tcf2SpecVersion {
154-
newList, err = vendorlist2.ParseEagerly(respBody)
155-
} else {
156-
newList, err = vendorlist.ParseEagerly(respBody)
157-
}
155+
newList, err = vendorlist2.ParseEagerly(respBody)
158156
if err != nil {
159157
glog.Errorf("GET %s returned malformed JSON. Cookie syncs may be affected. Error was %v. Body was %s", url, err, string(respBody))
160158
return 0
@@ -164,7 +162,7 @@ func saveOne(ctx context.Context, client *http.Client, url string, saver saveVen
164162
return newList.Version()
165163
}
166164

167-
func newVendorListCache(fallbackVL api.VendorList) (save func(vendorListVersion uint16, list api.VendorList), load func(vendorListVersion uint16) api.VendorList) {
165+
func newVendorListCache() (save func(vendorListVersion uint16, list api.VendorList), load func(vendorListVersion uint16) api.VendorList) {
168166
cache := &sync.Map{}
169167

170168
save = func(vendorListVersion uint16, list api.VendorList) {
@@ -180,16 +178,3 @@ func newVendorListCache(fallbackVL api.VendorList) (save func(vendorListVersion
180178
}
181179
return
182180
}
183-
184-
func loadFallbackGVL(fallbackGVLPath string) vendorlist.VendorList {
185-
fallbackContents, err := ioutil.ReadFile(fallbackGVLPath)
186-
if err != nil {
187-
glog.Fatalf("Error reading from file %s: %v", fallbackGVLPath, err)
188-
}
189-
190-
fallback, err := vendorlist.ParseEagerly(fallbackContents)
191-
if err != nil {
192-
glog.Fatalf("Error processing default GVL from %s: %v", fallbackGVLPath, err)
193-
}
194-
return fallback
195-
}

0 commit comments

Comments
 (0)