diff --git a/adapters/adform/adform_test.go b/adapters/adform/adform_test.go index 4b959253179..f957251c3ad 100644 --- a/adapters/adform/adform_test.go +++ b/adapters/adform/adform_test.go @@ -193,7 +193,7 @@ func preparePrebidRequest(serverUrl string, t *testing.T) *pbs.PBSRequest { prebidHttpRequest.Header.Add("Referer", adformTestData.referrer) prebidHttpRequest.Header.Add("X-Real-IP", adformTestData.deviceIP) - pbsCookie := usersync.ParsePBSCookieFromRequest(prebidHttpRequest, &config.Cookie{}) + pbsCookie := usersync.ParsePBSCookieFromRequest(prebidHttpRequest, &config.HostCookie{}) pbsCookie.TrySync("adform", adformTestData.buyerUID) fakeWriter := httptest.NewRecorder() pbsCookie.SetCookieOnResponse(fakeWriter, "", time.Minute) @@ -203,7 +203,7 @@ func preparePrebidRequest(serverUrl string, t *testing.T) *pbs.PBSRequest { r, err := pbs.ParsePBSRequest(prebidHttpRequest, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, cacheClient, &pbs.HostCookieSettings{}) + }, cacheClient, &config.HostCookie{}) if err != nil { t.Fatalf("ParsePBSRequest failed: %v", err) } diff --git a/adapters/appnexus/appnexus_test.go b/adapters/appnexus/appnexus_test.go index 07bb387d1a1..3ac7c20f5b3 100644 --- a/adapters/appnexus/appnexus_test.go +++ b/adapters/appnexus/appnexus_test.go @@ -360,19 +360,19 @@ func TestAppNexusBasicResponse(t *testing.T) { req.Header.Add("User-Agent", andata.deviceUA) req.Header.Add("X-Real-IP", andata.deviceIP) - pc := usersync.ParsePBSCookieFromRequest(req, &config.Cookie{}) + pc := usersync.ParsePBSCookieFromRequest(req, &config.HostCookie{}) pc.TrySync("adnxs", andata.buyerUID) fakewriter := httptest.NewRecorder() pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour) req.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie")) cacheClient, _ := dummycache.New() - hcs := pbs.HostCookieSettings{} + hcc := config.HostCookie{} pbReq, err := pbs.ParsePBSRequest(req, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, cacheClient, &hcs) + }, cacheClient, &hcc) if err != nil { t.Fatalf("ParsePBSRequest failed: %v", err) } diff --git a/adapters/audienceNetwork/facebook_test.go b/adapters/audienceNetwork/facebook_test.go index 0962ac76658..4e577fcca5e 100644 --- a/adapters/audienceNetwork/facebook_test.go +++ b/adapters/audienceNetwork/facebook_test.go @@ -206,19 +206,19 @@ func GenerateBidRequestForTestData(fbdata bidInfo, url string) (*pbs.PBSRequest, req.Header.Add("User-Agent", fbdata.deviceUA) req.Header.Add("X-Real-IP", fbdata.deviceIP) - pc := usersync.ParsePBSCookieFromRequest(req, &config.Cookie{}) + pc := usersync.ParsePBSCookieFromRequest(req, &config.HostCookie{}) pc.TrySync("audienceNetwork", fbdata.buyerUID) fakewriter := httptest.NewRecorder() pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour) req.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie")) cacheClient, _ := dummycache.New() - hcs := pbs.HostCookieSettings{} + hcc := config.HostCookie{} pbReq, err := pbs.ParsePBSRequest(req, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, cacheClient, &hcs) + }, cacheClient, &hcc) return pbReq, err } diff --git a/adapters/conversant/conversant_test.go b/adapters/conversant/conversant_test.go index 6072ebe1a1c..5b32f6a0f86 100644 --- a/adapters/conversant/conversant_test.go +++ b/adapters/conversant/conversant_test.go @@ -613,12 +613,12 @@ func ParseRequest(req *pbs.PBSRequest) (*pbs.PBSRequest, error) { httpReq.Header.Set("Cookie", cookie.ToHTTPCookie(90*24*time.Hour).String()) httpReq.Header.Add("Referer", "http://example.com") cache, _ := dummycache.New() - hcs := pbs.HostCookieSettings{} + hcc := config.HostCookie{} parsedReq, err := pbs.ParsePBSRequest(httpReq, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, cache, &hcs) + }, cache, &hcc) return parsedReq, err } diff --git a/adapters/lifestreet/lifestreet_test.go b/adapters/lifestreet/lifestreet_test.go index 41f3a63edef..141d36ad09f 100644 --- a/adapters/lifestreet/lifestreet_test.go +++ b/adapters/lifestreet/lifestreet_test.go @@ -225,17 +225,17 @@ func TestLifestreetBasicResponse(t *testing.T) { req.Header.Add("Referer", lsdata.referrer) req.Header.Add("X-Real-IP", lsdata.deviceIP) - pc := usersync.ParsePBSCookieFromRequest(req, &config.Cookie{}) + pc := usersync.ParsePBSCookieFromRequest(req, &config.HostCookie{}) fakewriter := httptest.NewRecorder() pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour) req.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie")) cacheClient, _ := dummycache.New() - hcs := pbs.HostCookieSettings{} + hcc := config.HostCookie{} pbReq, err := pbs.ParsePBSRequest(req, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, cacheClient, &hcs) + }, cacheClient, &hcc) if err != nil { t.Fatalf("ParsePBSRequest failed: %v", err) } diff --git a/adapters/pubmatic/pubmatic_test.go b/adapters/pubmatic/pubmatic_test.go index 771554a8e95..ebc3d430346 100644 --- a/adapters/pubmatic/pubmatic_test.go +++ b/adapters/pubmatic/pubmatic_test.go @@ -626,19 +626,19 @@ func TestPubmaticSampleRequest(t *testing.T) { httpReq := httptest.NewRequest("POST", server.URL, body) httpReq.Header.Add("Referer", "http://test.com/sports") - pc := usersync.ParsePBSCookieFromRequest(httpReq, &config.Cookie{}) + pc := usersync.ParsePBSCookieFromRequest(httpReq, &config.HostCookie{}) pc.TrySync("pubmatic", "12345") fakewriter := httptest.NewRecorder() pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour) httpReq.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie")) cacheClient, _ := dummycache.New() - hcs := pbs.HostCookieSettings{} + hcc := config.HostCookie{} _, err = pbs.ParsePBSRequest(httpReq, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, cacheClient, &hcs) + }, cacheClient, &hcc) if err != nil { t.Fatalf("Error when parsing request: %v", err) } diff --git a/adapters/pulsepoint/pulsepoint_test.go b/adapters/pulsepoint/pulsepoint_test.go index 78061e1c5aa..71c0406a7ae 100644 --- a/adapters/pulsepoint/pulsepoint_test.go +++ b/adapters/pulsepoint/pulsepoint_test.go @@ -223,14 +223,14 @@ func SampleRequest(numberOfImpressions int, t *testing.T) *pbs.PBSRequest { // setup a http request httpReq := httptest.NewRequest("POST", CreateService(adapterstest.BidOnTags("")).Server.URL, body) httpReq.Header.Add("Referer", "http://news.pub/topnews") - pc := usersync.ParsePBSCookieFromRequest(httpReq, &config.Cookie{}) + pc := usersync.ParsePBSCookieFromRequest(httpReq, &config.HostCookie{}) pc.TrySync("pulsepoint", "pulsepointUser123") fakewriter := httptest.NewRecorder() pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour) httpReq.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie")) // parse the http request cacheClient, _ := dummycache.New() - hcs := pbs.HostCookieSettings{} + hcs := config.HostCookie{} parsedReq, err := pbs.ParsePBSRequest(httpReq, &config.AuctionTimeouts{ Default: 2000, diff --git a/adapters/rubicon/rubicon_test.go b/adapters/rubicon/rubicon_test.go index 4e8d64d475d..94f6fcf9989 100644 --- a/adapters/rubicon/rubicon_test.go +++ b/adapters/rubicon/rubicon_test.go @@ -946,19 +946,19 @@ func CreatePrebidRequest(server *httptest.Server, t *testing.T) (an *RubiconAdap req.Header.Add("User-Agent", rubidata.deviceUA) req.Header.Add("X-Real-IP", rubidata.deviceIP) - pc := usersync.ParsePBSCookieFromRequest(req, &config.Cookie{}) + pc := usersync.ParsePBSCookieFromRequest(req, &config.HostCookie{}) pc.TrySync("rubicon", rubidata.buyerUID) fakewriter := httptest.NewRecorder() pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour) req.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie")) cacheClient, _ := dummycache.New() - hcs := pbs.HostCookieSettings{} + hcc := config.HostCookie{} pbReq, err = pbs.ParsePBSRequest(req, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, cacheClient, &hcs) + }, cacheClient, &hcc) pbReq.IsDebug = true if err != nil { t.Fatalf("ParsePBSRequest failed: %v", err) diff --git a/adapters/sovrn/sovrn_test.go b/adapters/sovrn/sovrn_test.go index bba3f18c2d7..bd501236666 100644 --- a/adapters/sovrn/sovrn_test.go +++ b/adapters/sovrn/sovrn_test.go @@ -183,19 +183,19 @@ func SampleSovrnRequest(numberOfImpressions int, t *testing.T) *pbs.PBSRequest { httpReq.Header.Add("Referer", testUrl) httpReq.Header.Add("User-Agent", testUserAgent) httpReq.Header.Add("X-Forwarded-For", testIp) - pc := usersync.ParsePBSCookieFromRequest(httpReq, &config.Cookie{}) + pc := usersync.ParsePBSCookieFromRequest(httpReq, &config.HostCookie{}) pc.TrySync("sovrn", testSovrnUserId) fakewriter := httptest.NewRecorder() pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour) httpReq.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie")) // parse the http request cacheClient, _ := dummycache.New() - hcs := pbs.HostCookieSettings{} + hcc := config.HostCookie{} parsedReq, err := pbs.ParsePBSRequest(httpReq, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, cacheClient, &hcs) + }, cacheClient, &hcc) if err != nil { t.Fatalf("Error when parsing request: %v", err) } diff --git a/config/config.go b/config/config.go index adca8449a2a..d39d579698c 100644 --- a/config/config.go +++ b/config/config.go @@ -137,6 +137,10 @@ type HostCookie struct { TTL int64 `mapstructure:"ttl_days"` } +func (cfg *HostCookie) TTLDuration() time.Duration { + return time.Duration(cfg.TTL) * time.Hour * 24 +} + type Adapter struct { Endpoint string `mapstructure:"endpoint"` // Required UserSyncURL string `mapstructure:"usersync_url"` diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index 5e38d15de74..b2ebb2649dd 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -20,10 +20,10 @@ import ( "github.com/prebid/prebid-server/usersync" ) -func NewCookieSyncEndpoint(syncers map[openrtb_ext.BidderName]usersync.Usersyncer, optOutCookie *config.Cookie, syncPermissions gdpr.Permissions, metrics pbsmetrics.MetricsEngine, pbsAnalytics analytics.PBSAnalyticsModule) httprouter.Handle { +func NewCookieSyncEndpoint(syncers map[openrtb_ext.BidderName]usersync.Usersyncer, hostCookie *config.HostCookie, syncPermissions gdpr.Permissions, metrics pbsmetrics.MetricsEngine, pbsAnalytics analytics.PBSAnalyticsModule) httprouter.Handle { deps := &cookieSyncDeps{ syncers: syncers, - optOutCookie: optOutCookie, + hostCookie: hostCookie, syncPermissions: syncPermissions, metrics: metrics, pbsAnalytics: pbsAnalytics, @@ -33,7 +33,7 @@ func NewCookieSyncEndpoint(syncers map[openrtb_ext.BidderName]usersync.Usersynce type cookieSyncDeps struct { syncers map[openrtb_ext.BidderName]usersync.Usersyncer - optOutCookie *config.Cookie + hostCookie *config.HostCookie syncPermissions gdpr.Permissions metrics pbsmetrics.MetricsEngine pbsAnalytics analytics.PBSAnalyticsModule @@ -50,7 +50,7 @@ func (deps *cookieSyncDeps) Endpoint(w http.ResponseWriter, r *http.Request, _ h defer deps.pbsAnalytics.LogCookieSyncObject(&co) deps.metrics.RecordCookieSync(pbsmetrics.Labels{}) - userSyncCookie := usersync.ParsePBSCookieFromRequest(r, deps.optOutCookie) + userSyncCookie := usersync.ParsePBSCookieFromRequest(r, deps.hostCookie) if !userSyncCookie.AllowSyncs() { http.Error(w, "User has opted out", http.StatusUnauthorized) co.Status = http.StatusUnauthorized diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 03441d613c2..b9b4aa6b10d 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -103,7 +103,7 @@ func doPost(body string, existingSyncs map[string]string, gdprHostConsent bool, } func testableEndpoint(perms gdpr.Permissions) httprouter.Handle { - return NewCookieSyncEndpoint(syncersForTest(), &config.Cookie{}, perms, &metricsConf.DummyMetricsEngine{}, analyticsConf.NewPBSAnalytics(&config.Analytics{})) + return NewCookieSyncEndpoint(syncersForTest(), &config.HostCookie{}, perms, &metricsConf.DummyMetricsEngine{}, analyticsConf.NewPBSAnalytics(&config.Analytics{})) } func syncersForTest() map[openrtb_ext.BidderName]usersync.Usersyncer { diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 7a36c558a38..1b269a11384 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -111,7 +111,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h } defer cancel() - usersyncs := usersync.ParsePBSCookieFromRequest(r, &(deps.cfg.HostCookie.OptOutCookie)) + usersyncs := usersync.ParsePBSCookieFromRequest(r, &(deps.cfg.HostCookie)) if req.App != nil { labels.Source = pbsmetrics.DemandApp } else { diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index f019baeb95f..c19e55fbf8a 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -106,7 +106,7 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http } defer cancel() - usersyncs := usersync.ParsePBSCookieFromRequest(r, &(deps.cfg.HostCookie.OptOutCookie)) + usersyncs := usersync.ParsePBSCookieFromRequest(r, &(deps.cfg.HostCookie)) if req.App != nil { labels.Source = pbsmetrics.DemandApp } else { diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 882834d14c8..6a17592bd09 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -24,7 +24,7 @@ func NewSetUIDEndpoint(cfg config.HostCookie, perms gdpr.Permissions, pbsanalyti defer pbsanalytics.LogSetUIDObject(&so) - pc := usersync.ParsePBSCookieFromRequest(r, &cfg.OptOutCookie) + pc := usersync.ParsePBSCookieFromRequest(r, &cfg) if !pc.AllowSyncs() { w.WriteHeader(http.StatusUnauthorized) metrics.RecordUserIDSet(pbsmetrics.UserLabels{Action: pbsmetrics.RequestActionOptOut}) diff --git a/pbs/pbsrequest.go b/pbs/pbsrequest.go index 2ed7efded4e..a68cc7a5860 100644 --- a/pbs/pbsrequest.go +++ b/pbs/pbsrequest.go @@ -218,7 +218,7 @@ func ParseMediaTypes(types []string) []MediaType { return mtypes } -func ParsePBSRequest(r *http.Request, cfg *config.AuctionTimeouts, cache cache.Cache, hostCookieSettings *HostCookieSettings) (*PBSRequest, error) { +func ParsePBSRequest(r *http.Request, cfg *config.AuctionTimeouts, cache cache.Cache, hostCookieConfig *config.HostCookie) (*PBSRequest, error) { defer r.Body.Close() pbsReq := &PBSRequest{} @@ -263,14 +263,7 @@ func ParsePBSRequest(r *http.Request, cfg *config.AuctionTimeouts, cache cache.C // use client-side data for web requests if pbsReq.App == nil { - pbsReq.Cookie = usersync.ParsePBSCookieFromRequest(r, &(hostCookieSettings.OptOutCookie)) - - // Host has right to leverage private cookie store for user ID - if uid, _, _ := pbsReq.Cookie.GetUID(hostCookieSettings.Family); uid == "" && hostCookieSettings.CookieName != "" { - if hostCookie, err := r.Cookie(hostCookieSettings.CookieName); err == nil { - pbsReq.Cookie.TrySync(hostCookieSettings.Family, hostCookie.Value) - } - } + pbsReq.Cookie = usersync.ParsePBSCookieFromRequest(r, hostCookieConfig) pbsReq.Device.UA = r.Header.Get("User-Agent") diff --git a/pbs/pbsrequest_test.go b/pbs/pbsrequest_test.go index 70882b48741..92122cc7d2f 100644 --- a/pbs/pbsrequest_test.go +++ b/pbs/pbsrequest_test.go @@ -73,12 +73,12 @@ func TestParseSimpleRequest(t *testing.T) { r := httptest.NewRequest("POST", "/auction", bytes.NewBuffer(body)) r.Header.Add("Referer", "http://nytimes.com/cool.html") d, _ := dummycache.New() - hcs := HostCookieSettings{} + hcc := config.HostCookie{} pbs_req, err := ParsePBSRequest(r, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, d, &hcs) + }, d, &hcc) if err != nil { t.Fatalf("Parse simple request failed: %v", err) } @@ -156,14 +156,14 @@ func TestHeaderParsing(t *testing.T) { r.Header.Add("Referer", "http://nytimes.com/cool.html") r.Header.Add("User-Agent", "Mozilla/") d, _ := dummycache.New() - hcs := HostCookieSettings{} + hcc := config.HostCookie{} d.Config().Set("dummy", dummyConfig) pbs_req, err := ParsePBSRequest(r, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, d, &hcs) + }, d, &hcc) if err != nil { t.Fatalf("Parse simple request failed") } @@ -241,14 +241,14 @@ func TestParseConfig(t *testing.T) { r := httptest.NewRequest("POST", "/auction", bytes.NewBuffer(body)) r.Header.Add("Referer", "http://nytimes.com/cool.html") d, _ := dummycache.New() - hcs := HostCookieSettings{} + hcc := config.HostCookie{} d.Config().Set("dummy", dummyConfig) pbs_req, err := ParsePBSRequest(r, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, d, &hcs) + }, d, &hcc) if err != nil { t.Fatalf("Parse simple request failed: %v", err) } @@ -327,12 +327,12 @@ func TestParseMobileRequestFirstVersion(t *testing.T) { `) r := httptest.NewRequest("POST", "/auction", bytes.NewBuffer(body)) d, _ := dummycache.New() - hcs := HostCookieSettings{} + hcc := config.HostCookie{} pbs_req, err := ParsePBSRequest(r, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, d, &hcs) + }, d, &hcc) if err != nil { t.Fatalf("Parse simple request failed: %v", err) } @@ -426,12 +426,12 @@ func TestParseMobileRequest(t *testing.T) { `) r := httptest.NewRequest("POST", "/auction", bytes.NewBuffer(body)) d, _ := dummycache.New() - hcs := HostCookieSettings{} + hcc := config.HostCookie{} pbs_req, err := ParsePBSRequest(r, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, d, &hcs) + }, d, &hcc) if err != nil { t.Fatalf("Parse simple request failed: %v", err) } @@ -529,12 +529,12 @@ func TestParseMalformedMobileRequest(t *testing.T) { `) r := httptest.NewRequest("POST", "/auction", bytes.NewBuffer(body)) d, _ := dummycache.New() - hcs := HostCookieSettings{} + hcc := config.HostCookie{} pbs_req, err := ParsePBSRequest(r, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, d, &hcs) + }, d, &hcc) if err != nil { t.Fatalf("Parse simple request failed: %v", err) } @@ -636,12 +636,12 @@ func TestParseRequestWithInstl(t *testing.T) { `) r := httptest.NewRequest("POST", "/auction", bytes.NewBuffer(body)) d, _ := dummycache.New() - hcs := HostCookieSettings{} + hcc := config.HostCookie{} pbs_req, err := ParsePBSRequest(r, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, d, &hcs) + }, d, &hcc) if err != nil { t.Fatalf("Parse simple request failed: %v", err) } @@ -692,7 +692,7 @@ func doTimeoutTest(t *testing.T, expected int, requested int, max uint64, def ui }`, requested) r := httptest.NewRequest("POST", "/auction", strings.NewReader(body)) d, _ := dummycache.New() - parsed, err := ParsePBSRequest(r, cfg, d, &HostCookieSettings{}) + parsed, err := ParsePBSRequest(r, cfg, d, &config.HostCookie{}) if err != nil { t.Fatalf("Unexpected err: %v", err) } @@ -728,7 +728,7 @@ func TestParsePBSRequestUsesHostCookie(t *testing.T) { } r.AddCookie(&http.Cookie{Name: "key", Value: "testcookie"}) d, _ := dummycache.New() - hcs := HostCookieSettings{ + hcc := config.HostCookie{ CookieName: "key", Family: "family", OptOutCookie: config.Cookie{ @@ -740,7 +740,7 @@ func TestParsePBSRequestUsesHostCookie(t *testing.T) { pbs_req, err2 := ParsePBSRequest(r, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, d, &hcs) + }, d, &hcc) if err2 != nil { t.Fatalf("Parse simple request failed %v", err2) } diff --git a/pbs/usersync.go b/pbs/usersync.go index 25808639c05..0e560a501da 100644 --- a/pbs/usersync.go +++ b/pbs/usersync.go @@ -27,16 +27,6 @@ const ( USERSYNC_SUCCESS = "usersync.%s.sets" ) -type HostCookieSettings struct { - Domain string - Family string - CookieName string - OptOutURL string - OptInURL string - OptOutCookie config.Cookie - TTL time.Duration -} - // uidWithExpiry bundles the UID with an Expiration date. // After the expiration, the UID is no longer valid. type uidWithExpiry struct { @@ -47,11 +37,11 @@ type uidWithExpiry struct { } type UserSyncDeps struct { - ExternalUrl string - RecaptchaSecret string - HostCookieSettings *HostCookieSettings - MetricsEngine pbsmetrics.MetricsEngine - PBSAnalytics analytics.PBSAnalyticsModule + ExternalUrl string + RecaptchaSecret string + HostCookieConfig *config.HostCookie + MetricsEngine pbsmetrics.MetricsEngine + PBSAnalytics analytics.PBSAnalyticsModule } // pbsCookieJson defines the JSON contract for the cookie data's storage format. @@ -66,8 +56,8 @@ type pbsCookieJson struct { } func (deps *UserSyncDeps) GetUIDs(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { - pc := usersync.ParsePBSCookieFromRequest(r, &deps.HostCookieSettings.OptOutCookie) - pc.SetCookieOnResponse(w, deps.HostCookieSettings.Domain, deps.HostCookieSettings.TTL) + pc := usersync.ParsePBSCookieFromRequest(r, deps.HostCookieConfig) + pc.SetCookieOnResponse(w, deps.HostCookieConfig.Domain, deps.HostCookieConfig.TTLDuration()) json.NewEncoder(w).Encode(pc) return } @@ -120,13 +110,13 @@ func (deps *UserSyncDeps) OptOut(w http.ResponseWriter, r *http.Request, _ httpr return } - pc := usersync.ParsePBSCookieFromRequest(r, &deps.HostCookieSettings.OptOutCookie) + pc := usersync.ParsePBSCookieFromRequest(r, deps.HostCookieConfig) pc.SetPreference(optout == "") - pc.SetCookieOnResponse(w, deps.HostCookieSettings.Domain, deps.HostCookieSettings.TTL) + pc.SetCookieOnResponse(w, deps.HostCookieConfig.Domain, deps.HostCookieConfig.TTLDuration()) if optout == "" { - http.Redirect(w, r, deps.HostCookieSettings.OptInURL, 301) + http.Redirect(w, r, deps.HostCookieConfig.OptInURL, 301) } else { - http.Redirect(w, r, deps.HostCookieSettings.OptOutURL, 301) + http.Redirect(w, r, deps.HostCookieConfig.OptOutURL, 301) } } diff --git a/pbs_light.go b/pbs_light.go index fd699a9076a..772dc2b7ef8 100644 --- a/pbs_light.go +++ b/pbs_light.go @@ -69,8 +69,6 @@ import ( // See issue #559 var Rev string -var hostCookieSettings pbs.HostCookieSettings - var exchanges map[string]adapters.Adapter var dataCache cache.Cache var reqSchema *gojsonschema.Schema @@ -146,7 +144,7 @@ func (deps *auctionDeps) auction(w http.ResponseWriter, r *http.Request, _ httpr } } - pbs_req, err := pbs.ParsePBSRequest(r, &deps.cfg.AuctionTimeouts, dataCache, &hostCookieSettings) + pbs_req, err := pbs.ParsePBSRequest(r, &deps.cfg.AuctionTimeouts, dataCache, &(deps.cfg.HostCookie)) // Defer here because we need pbs_req defined. defer func() { if pbs_req == nil { @@ -743,28 +741,18 @@ func serve(revision string, cfg *config.Configuration) error { router.GET("/info/bidders", infoEndpoints.NewBiddersEndpoint()) router.GET("/info/bidders/:bidderName", infoEndpoints.NewBidderDetailsEndpoint("./static/bidder-info", openrtb_ext.BidderList())) router.GET("/bidders/params", NewJsonDirectoryServer(paramsValidator)) - router.POST("/cookie_sync", endpoints.NewCookieSyncEndpoint(syncers, &(hostCookieSettings.OptOutCookie), gdprPerms, metricsEngine, pbsAnalytics)) + router.POST("/cookie_sync", endpoints.NewCookieSyncEndpoint(syncers, &(cfg.HostCookie), gdprPerms, metricsEngine, pbsAnalytics)) router.POST("/validate", validate) router.GET("/status", endpoints.NewStatusEndpoint(cfg.StatusResponse)) router.GET("/", serveIndex) router.ServeFiles("/static/*filepath", http.Dir("static")) - hostCookieSettings = pbs.HostCookieSettings{ - Domain: cfg.HostCookie.Domain, - Family: cfg.HostCookie.Family, - CookieName: cfg.HostCookie.CookieName, - OptOutURL: cfg.HostCookie.OptOutURL, - OptInURL: cfg.HostCookie.OptInURL, - OptOutCookie: cfg.HostCookie.OptOutCookie, - TTL: time.Duration(cfg.HostCookie.TTL) * 24 * time.Hour, - } - userSyncDeps := &pbs.UserSyncDeps{ - HostCookieSettings: &hostCookieSettings, - ExternalUrl: cfg.ExternalURL, - RecaptchaSecret: cfg.RecaptchaSecret, - MetricsEngine: metricsEngine, - PBSAnalytics: pbsAnalytics, + HostCookieConfig: &(cfg.HostCookie), + ExternalUrl: cfg.ExternalURL, + RecaptchaSecret: cfg.RecaptchaSecret, + MetricsEngine: metricsEngine, + PBSAnalytics: pbsAnalytics, } router.GET("/getuids", userSyncDeps.GetUIDs) diff --git a/pbs_light_test.go b/pbs_light_test.go index 26fffbb4368..9285086d1c2 100644 --- a/pbs_light_test.go +++ b/pbs_light_test.go @@ -73,12 +73,12 @@ func TestSortBidsAndAddKeywordsForMobile(t *testing.T) { `) r := httptest.NewRequest("POST", "/auction", bytes.NewBuffer(body)) d, _ := dummycache.New() - hcs := pbs.HostCookieSettings{} + hcc := config.HostCookie{} pbs_req, err := pbs.ParsePBSRequest(r, &config.AuctionTimeouts{ Default: 2000, Max: 2000, - }, d, &hcs) + }, d, &hcc) if err != nil { t.Errorf("Unexpected error on parsing %v", err) } diff --git a/usersync/cookie.go b/usersync/cookie.go index 0e0ee01e8b5..42e626a98a2 100644 --- a/usersync/cookie.go +++ b/usersync/cookie.go @@ -45,20 +45,29 @@ type uidWithExpiry struct { } // ParsePBSCookieFromRequest parses the UserSyncMap from an HTTP Request. -func ParsePBSCookieFromRequest(r *http.Request, configuredOptoutCookie *config.Cookie) *PBSCookie { - if configuredOptoutCookie.Name != "" { - optOutCookie, err1 := r.Cookie(configuredOptoutCookie.Name) - if err1 == nil && optOutCookie.Value == configuredOptoutCookie.Value { +func ParsePBSCookieFromRequest(r *http.Request, cookie *config.HostCookie) *PBSCookie { + if cookie.OptOutCookie.Name != "" { + optOutCookie, err1 := r.Cookie(cookie.OptOutCookie.Name) + if err1 == nil && optOutCookie.Value == cookie.OptOutCookie.Value { pc := NewPBSCookie() pc.SetPreference(false) return pc } } + var parsed *PBSCookie uidCookie, err2 := r.Cookie(UID_COOKIE_NAME) - if err2 != nil { - return NewPBSCookie() + if err2 == nil { + parsed = ParsePBSCookie(uidCookie) + } else { + parsed = NewPBSCookie() + } + // Fixes #582 + if uid, _, _ := parsed.GetUID(cookie.Family); uid == "" && cookie.CookieName != "" { + if hostCookie, err := r.Cookie(cookie.CookieName); err == nil { + parsed.TrySync(cookie.Family, hostCookie.Value) + } } - return ParsePBSCookie(uidCookie) + return parsed } // ParsePBSCookie parses the UserSync cookie from a raw HTTP cookie. diff --git a/usersync/cookie_test.go b/usersync/cookie_test.go index 6a6bb1b2edd..d81eb123c95 100644 --- a/usersync/cookie_test.go +++ b/usersync/cookie_test.go @@ -161,6 +161,24 @@ func TestParseNilSyncMap(t *testing.T) { ensureConsistency(t, parsed) } +func TestParseOtherCookie(t *testing.T) { + req := httptest.NewRequest("POST", "http://www.prebid.com", nil) + otherCookieName := "other" + id := "some-user-id" + req.AddCookie(&http.Cookie{ + Name: otherCookieName, + Value: id, + }) + parsed := ParsePBSCookieFromRequest(req, &config.HostCookie{ + Family: "adnxs", + CookieName: otherCookieName, + }) + val, _, _ := parsed.GetUID("adnxs") + if val != id { + t.Errorf("Bad cookie value. Expected %s, got %s", id, val) + } +} + func TestCookieReadWrite(t *testing.T) { cookie := &PBSCookie{ uids: map[string]uidWithExpiry{ @@ -334,5 +352,5 @@ func writeThenRead(cookie *PBSCookie) *PBSCookie { header := http.Header{} header.Add("Cookie", writtenCookie) request := http.Request{Header: header} - return ParsePBSCookieFromRequest(&request, &config.Cookie{}) + return ParsePBSCookieFromRequest(&request, &config.HostCookie{}) }