From 8971a36bd4edb1d83f4007f00bea1b7ab38ad4ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kaczmarek?= Date: Sat, 31 Aug 2024 11:55:27 +0000 Subject: [PATCH 01/10] Add GPC extension handling to exchange.go and request_wrapper.go 2748 --- exchange/exchange.go | 14 +++++++++++++ openrtb_ext/request_wrapper.go | 38 +++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/exchange/exchange.go b/exchange/exchange.go index 5c27b0d3c5a..832dbf22916 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -329,6 +329,20 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog return nil, err } + regExt, err := r.BidRequestWrapper.GetRegExt() + if err != nil { + return nil, err + } + + gpcValue := regExt.GetGPC() + if gpcValue == nil { + // Im not sure if GlobalPrivacyControlHeader is a correct header + if r.GlobalPrivacyControlHeader == "1" { + gpc := "1" + regExt.SetGPC(&gpc) + } + } + // rebuild/resync the request in the request wrapper. if err := r.BidRequestWrapper.RebuildRequest(); err != nil { return nil, err diff --git a/openrtb_ext/request_wrapper.go b/openrtb_ext/request_wrapper.go index 27c20e98f35..098ff4b2612 100644 --- a/openrtb_ext/request_wrapper.go +++ b/openrtb_ext/request_wrapper.go @@ -61,6 +61,7 @@ const ( schainKey = "schain" us_privacyKey = "us_privacy" cdepKey = "cdep" + gpcKey = "gpc" ) // LenImp returns the number of impressions without causing the creation of ImpWrapper objects. @@ -1201,6 +1202,8 @@ type RegExt struct { dsaDirty bool gdpr *int8 gdprDirty bool + gpc *string + gpcDirty bool usPrivacy string usPrivacyDirty bool } @@ -1244,6 +1247,13 @@ func (re *RegExt) unmarshal(extJson json.RawMessage) error { } } + gpcJson, hasGPC := re.ext[gpcKey] + if hasGPC && gpcJson != nil { + if err := jsonutil.Unmarshal(gpcJson, &re.gpc); err != nil { + return err + } + } + return nil } @@ -1287,6 +1297,19 @@ func (re *RegExt) marshal() (json.RawMessage, error) { re.usPrivacyDirty = false } + if re.gpcDirty { + if re.gpc != nil { + rawjson, err := jsonutil.Marshal(re.gpc) + if err != nil { + return nil, err + } + re.ext[gpcKey] = rawjson + } else { + delete(re.ext, gpcKey) + } + re.gpcDirty = false + } + re.extDirty = false if len(re.ext) == 0 { return nil, nil @@ -1295,7 +1318,7 @@ func (re *RegExt) marshal() (json.RawMessage, error) { } func (re *RegExt) Dirty() bool { - return re.extDirty || re.dsaDirty || re.gdprDirty || re.usPrivacyDirty + return re.extDirty || re.dsaDirty || re.gdprDirty || re.usPrivacyDirty || re.gpcDirty } func (re *RegExt) GetExt() map[string]json.RawMessage { @@ -1337,6 +1360,19 @@ func (re *RegExt) SetGDPR(gdpr *int8) { re.gdprDirty = true } +func (re *RegExt) GetGPC() *string { + if re.gpc == nil { + return nil + } + GPC := *re.gpc + return &GPC +} + +func (re *RegExt) SetGPC(GPC *string) { + re.gpc = GPC + re.gdprDirty = true +} + func (re *RegExt) GetUSPrivacy() string { uSPrivacy := re.usPrivacy return uSPrivacy From 58aab7c77f7bda3a9b60a5f211cbdf0d9bc06b23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kaczmarek?= Date: Wed, 4 Sep 2024 14:02:50 +0000 Subject: [PATCH 02/10] example --- endpoints/openrtb2/auction.go | 25 ++++++++++++++++ endpoints/openrtb2/auction_test.go | 48 ++++++++++++++++++++++++++++++ exchange/exchange.go | 14 --------- 3 files changed, 73 insertions(+), 14 deletions(-) diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 57d9e73a27d..b820b976c33 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -1497,6 +1497,11 @@ func (deps *endpointDeps) setFieldsImplicitly(httpReq *http.Request, r *openrtb_ setAuctionTypeImplicitly(r) + err := setGPCImplicitly(httpReq, r) + if err != nil { + return []error{err} + } + errs := setSecBrowsingTopicsImplicitly(httpReq, r, account) return errs } @@ -1516,6 +1521,26 @@ func setAuctionTypeImplicitly(r *openrtb_ext.RequestWrapper) { } } +func setGPCImplicitly(httpReq *http.Request, r *openrtb_ext.RequestWrapper) error { + secGPC := httpReq.Header.Get("Sec-GPC") + fmt.Printf("Sec-GPC Header: %s\n", secGPC) + + if secGPC != "1" { + return nil + } + + regExt, err := r.GetRegExt() + if err != nil { + return err + } + + gpc := "1" + regExt.SetGPC(&gpc) + fmt.Printf("GPC set to: %s\n", *regExt.GetGPC()) + + return nil +} + // setSecBrowsingTopicsImplicitly updates user.data with data from request header 'Sec-Browsing-Topics' func setSecBrowsingTopicsImplicitly(httpReq *http.Request, r *openrtb_ext.RequestWrapper, account *config.Account) []error { secBrowsingTopics := httpReq.Header.Get(secBrowsingTopics) diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 717609e23d9..4f98177e126 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -5618,6 +5618,54 @@ func TestValidateOrFillCookieDeprecation(t *testing.T) { } } +func TestSetGPCImplicitly(t *testing.T) { + testCases := []struct { + description string + headerValue string + expectedGPC string + expectError bool + }{ + { + description: "Sec-GPC header set to '1', GPC should be set to '1'", + headerValue: "1", + expectedGPC: "1", + expectError: false, + }, + } + + for _, test := range testCases { + t.Run(test.description, func(t *testing.T) { + // Tworzenie przykładowego HTTP requesta + httpReq := &http.Request{ + Header: http.Header{ + "Sec-GPC": []string{test.headerValue}, + }, + } + + // Inicjalizacja request wrappera + r := &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{}, // Dodaj tutaj poprawną strukturę + } + + // Wywołanie setGPCImplicitly + err := setGPCImplicitly(httpReq, r) + if (err != nil) != test.expectError { + t.Errorf("Unexpected error state: got %v, expected error: %v", err, test.expectError) + } + + // Sprawdzanie, czy GPC zostało ustawione + regExt, _ := r.GetRegExt() + gpcValue := regExt.GetGPC() + + if gpcValue != nil && *gpcValue != test.expectedGPC { + t.Errorf("Expected GPC %v, but got %v", test.expectedGPC, *gpcValue) + } else if gpcValue == nil && test.expectedGPC != "" { + t.Errorf("Expected GPC to be set, but it was nil") + } + }) + } +} + func TestValidateRequestCookieDeprecation(t *testing.T) { testCases := []struct { diff --git a/exchange/exchange.go b/exchange/exchange.go index 832dbf22916..5c27b0d3c5a 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -329,20 +329,6 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog return nil, err } - regExt, err := r.BidRequestWrapper.GetRegExt() - if err != nil { - return nil, err - } - - gpcValue := regExt.GetGPC() - if gpcValue == nil { - // Im not sure if GlobalPrivacyControlHeader is a correct header - if r.GlobalPrivacyControlHeader == "1" { - gpc := "1" - regExt.SetGPC(&gpc) - } - } - // rebuild/resync the request in the request wrapper. if err := r.BidRequestWrapper.RebuildRequest(); err != nil { return nil, err From b7692d793c4b2c321f09d2d701fb946a4f4786f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kaczmarek?= Date: Wed, 4 Sep 2024 14:08:03 +0000 Subject: [PATCH 03/10] example --- endpoints/openrtb2/auction_test.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 4f98177e126..292635861a8 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -5635,25 +5635,21 @@ func TestSetGPCImplicitly(t *testing.T) { for _, test := range testCases { t.Run(test.description, func(t *testing.T) { - // Tworzenie przykładowego HTTP requesta httpReq := &http.Request{ Header: http.Header{ "Sec-GPC": []string{test.headerValue}, }, } - // Inicjalizacja request wrappera r := &openrtb_ext.RequestWrapper{ - BidRequest: &openrtb2.BidRequest{}, // Dodaj tutaj poprawną strukturę + BidRequest: &openrtb2.BidRequest{}, // what I should add here??? } - // Wywołanie setGPCImplicitly err := setGPCImplicitly(httpReq, r) if (err != nil) != test.expectError { t.Errorf("Unexpected error state: got %v, expected error: %v", err, test.expectError) } - // Sprawdzanie, czy GPC zostało ustawione regExt, _ := r.GetRegExt() gpcValue := regExt.GetGPC() From a2b7cf101578db3f85054a791cade9270705b318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kaczmarek?= Date: Thu, 5 Sep 2024 08:58:54 +0000 Subject: [PATCH 04/10] fix bugs --- endpoints/openrtb2/auction.go | 25 ++++++++++++++---- endpoints/openrtb2/auction_test.go | 41 ++++++++++++++++++------------ 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index b820b976c33..02f5a5efef8 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -63,10 +63,11 @@ const observeBrowsingTopics = "Observe-Browsing-Topics" const observeBrowsingTopicsValue = "?1" var ( - dntKey string = http.CanonicalHeaderKey("DNT") - dntDisabled int8 = 0 - dntEnabled int8 = 1 - notAmp int8 = 0 + dntKey string = http.CanonicalHeaderKey("DNT") + secGPCHdrKey string = http.CanonicalHeaderKey("Sec-GPC") + dntDisabled int8 = 0 + dntEnabled int8 = 1 + notAmp int8 = 0 ) var accountIdSearchPath = [...]struct { @@ -1522,7 +1523,7 @@ func setAuctionTypeImplicitly(r *openrtb_ext.RequestWrapper) { } func setGPCImplicitly(httpReq *http.Request, r *openrtb_ext.RequestWrapper) error { - secGPC := httpReq.Header.Get("Sec-GPC") + secGPC := httpReq.Header.Get(secGPCHdrKey) fmt.Printf("Sec-GPC Header: %s\n", secGPC) if secGPC != "1" { @@ -1538,6 +1539,20 @@ func setGPCImplicitly(httpReq *http.Request, r *openrtb_ext.RequestWrapper) erro regExt.SetGPC(&gpc) fmt.Printf("GPC set to: %s\n", *regExt.GetGPC()) + // Ręczna aktualizacja pola Regs.Ext + regExtBytes, err := json.Marshal(regExt) + if err != nil { + return err + } + + // Debugging - sprawdzenie, co jest w regExtBytes + fmt.Printf("Zawartość regExtBytes przed przypisaniem: %s\n", string(regExtBytes)) + + r.BidRequest.Regs.Ext = regExtBytes // Zaktualizowanie pola Regs.Ext + + // Debugging - sprawdzenie, co jest w r.BidRequest.Regs.Ext + fmt.Printf("Zaktualizowane Regs.Ext: %s\n", string(r.BidRequest.Regs.Ext)) + return nil } diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 292635861a8..7ff24d5fb59 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -5620,16 +5620,24 @@ func TestValidateOrFillCookieDeprecation(t *testing.T) { func TestSetGPCImplicitly(t *testing.T) { testCases := []struct { - description string - headerValue string - expectedGPC string - expectError bool + description string + headerValue string + expectedGPC string + expectError bool + regs *openrtb2.Regs + expectedRegs *openrtb2.Regs }{ { description: "Sec-GPC header set to '1', GPC should be set to '1'", headerValue: "1", expectedGPC: "1", expectError: false, + regs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{"gpc":"1"}`), + }, }, } @@ -5637,27 +5645,28 @@ func TestSetGPCImplicitly(t *testing.T) { t.Run(test.description, func(t *testing.T) { httpReq := &http.Request{ Header: http.Header{ - "Sec-GPC": []string{test.headerValue}, + http.CanonicalHeaderKey("Sec-GPC"): []string{test.headerValue}, }, } r := &openrtb_ext.RequestWrapper{ - BidRequest: &openrtb2.BidRequest{}, // what I should add here??? + BidRequest: &openrtb2.BidRequest{ + Regs: test.regs, + }, } + // Wywołanie funkcji testowanej err := setGPCImplicitly(httpReq, r) - if (err != nil) != test.expectError { - t.Errorf("Unexpected error state: got %v, expected error: %v", err, test.expectError) - } - - regExt, _ := r.GetRegExt() - gpcValue := regExt.GetGPC() - if gpcValue != nil && *gpcValue != test.expectedGPC { - t.Errorf("Expected GPC %v, but got %v", test.expectedGPC, *gpcValue) - } else if gpcValue == nil && test.expectedGPC != "" { - t.Errorf("Expected GPC to be set, but it was nil") + // Weryfikacja błędu + if test.expectError { + assert.Error(t, err) + } else { + assert.NoError(t, err) } + + // Weryfikacja JSON + assert.JSONEq(t, string(test.expectedRegs.Ext), string(r.BidRequest.Regs.Ext)) }) } } From c7fbfe1c709acc68600c7573917fc969cb5387d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kaczmarek?= Date: Fri, 6 Sep 2024 13:14:06 +0000 Subject: [PATCH 05/10] fix comments --- endpoints/openrtb2/auction.go | 15 --------- endpoints/openrtb2/auction_test.go | 49 +++++++++++++++++++++++++----- openrtb_ext/request_wrapper.go | 6 ++-- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 02f5a5efef8..68f3cf8c6a1 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -1537,21 +1537,6 @@ func setGPCImplicitly(httpReq *http.Request, r *openrtb_ext.RequestWrapper) erro gpc := "1" regExt.SetGPC(&gpc) - fmt.Printf("GPC set to: %s\n", *regExt.GetGPC()) - - // Ręczna aktualizacja pola Regs.Ext - regExtBytes, err := json.Marshal(regExt) - if err != nil { - return err - } - - // Debugging - sprawdzenie, co jest w regExtBytes - fmt.Printf("Zawartość regExtBytes przed przypisaniem: %s\n", string(regExtBytes)) - - r.BidRequest.Regs.Ext = regExtBytes // Zaktualizowanie pola Regs.Ext - - // Debugging - sprawdzenie, co jest w r.BidRequest.Regs.Ext - fmt.Printf("Zaktualizowane Regs.Ext: %s\n", string(r.BidRequest.Regs.Ext)) return nil } diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 7ff24d5fb59..5aed5b11513 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -5621,15 +5621,15 @@ func TestValidateOrFillCookieDeprecation(t *testing.T) { func TestSetGPCImplicitly(t *testing.T) { testCases := []struct { description string - headerValue string + header string expectedGPC string expectError bool regs *openrtb2.Regs expectedRegs *openrtb2.Regs }{ { - description: "Sec-GPC header set to '1', GPC should be set to '1'", - headerValue: "1", + description: "regs_ext_gpc_not_set_and_header_is_1", + header: "1", expectedGPC: "1", expectError: false, regs: &openrtb2.Regs{ @@ -5639,13 +5639,49 @@ func TestSetGPCImplicitly(t *testing.T) { Ext: []byte(`{"gpc":"1"}`), }, }, + { + description: "sec_gpc_header_not_set_gpc_should_not_be_modified", + header: "", + expectedGPC: "", + expectError: false, + regs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + }, + { + description: "sec_gpc_header_set_to_2_gpc_should_not_be_modified", + header: "2", + expectedGPC: "", + expectError: false, + regs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + }, + { + description: "sec_gpc_header_set_to_1_and_regs_ext_contains_other_data", + header: "1", + expectedGPC: "1", + expectError: false, + regs: &openrtb2.Regs{ + Ext: []byte(`{"some_other_field":"some_value"}`), + }, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{"some_other_field":"some_value","gpc":"1"}`), + }, + }, } for _, test := range testCases { t.Run(test.description, func(t *testing.T) { httpReq := &http.Request{ Header: http.Header{ - http.CanonicalHeaderKey("Sec-GPC"): []string{test.headerValue}, + http.CanonicalHeaderKey("Sec-GPC"): []string{test.header}, }, } @@ -5655,17 +5691,14 @@ func TestSetGPCImplicitly(t *testing.T) { }, } - // Wywołanie funkcji testowanej err := setGPCImplicitly(httpReq, r) - // Weryfikacja błędu if test.expectError { assert.Error(t, err) } else { assert.NoError(t, err) } - - // Weryfikacja JSON + assert.NoError(t, r.RebuildRequest()) assert.JSONEq(t, string(test.expectedRegs.Ext), string(r.BidRequest.Regs.Ext)) }) } diff --git a/openrtb_ext/request_wrapper.go b/openrtb_ext/request_wrapper.go index 098ff4b2612..2de058e3878 100644 --- a/openrtb_ext/request_wrapper.go +++ b/openrtb_ext/request_wrapper.go @@ -1368,9 +1368,9 @@ func (re *RegExt) GetGPC() *string { return &GPC } -func (re *RegExt) SetGPC(GPC *string) { - re.gpc = GPC - re.gdprDirty = true +func (re *RegExt) SetGPC(gpc *string) { + re.gpc = gpc + re.gpcDirty = true } func (re *RegExt) GetUSPrivacy() string { From f713ff13e17dc4456050ae082eb266e9d6e4ecd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kaczmarek?= Date: Wed, 11 Sep 2024 14:48:05 +0000 Subject: [PATCH 06/10] fix comments --- endpoints/openrtb2/auction.go | 17 +++--- endpoints/openrtb2/auction_test.go | 88 ++++++++++++++++++++++++++---- openrtb_ext/request_wrapper.go | 4 +- 3 files changed, 90 insertions(+), 19 deletions(-) diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 68f3cf8c6a1..1b5a9a4b5b1 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -63,11 +63,11 @@ const observeBrowsingTopics = "Observe-Browsing-Topics" const observeBrowsingTopicsValue = "?1" var ( - dntKey string = http.CanonicalHeaderKey("DNT") - secGPCHdrKey string = http.CanonicalHeaderKey("Sec-GPC") - dntDisabled int8 = 0 - dntEnabled int8 = 1 - notAmp int8 = 0 + dntKey string = http.CanonicalHeaderKey("DNT") + secGPCKey string = http.CanonicalHeaderKey("Sec-GPC") + dntDisabled int8 = 0 + dntEnabled int8 = 1 + notAmp int8 = 0 ) var accountIdSearchPath = [...]struct { @@ -1523,8 +1523,7 @@ func setAuctionTypeImplicitly(r *openrtb_ext.RequestWrapper) { } func setGPCImplicitly(httpReq *http.Request, r *openrtb_ext.RequestWrapper) error { - secGPC := httpReq.Header.Get(secGPCHdrKey) - fmt.Printf("Sec-GPC Header: %s\n", secGPC) + secGPC := httpReq.Header.Get(secGPCKey) if secGPC != "1" { return nil @@ -1535,6 +1534,10 @@ func setGPCImplicitly(httpReq *http.Request, r *openrtb_ext.RequestWrapper) erro return err } + if regExt.GetGPC() != nil { + return nil + } + gpc := "1" regExt.SetGPC(&gpc) diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 5aed5b11513..1ae1e6933d7 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -5622,19 +5622,17 @@ func TestSetGPCImplicitly(t *testing.T) { testCases := []struct { description string header string - expectedGPC string - expectError bool regs *openrtb2.Regs + expectError bool expectedRegs *openrtb2.Regs }{ { description: "regs_ext_gpc_not_set_and_header_is_1", header: "1", - expectedGPC: "1", - expectError: false, regs: &openrtb2.Regs{ Ext: []byte(`{}`), }, + expectError: false, expectedRegs: &openrtb2.Regs{ Ext: []byte(`{"gpc":"1"}`), }, @@ -5642,11 +5640,10 @@ func TestSetGPCImplicitly(t *testing.T) { { description: "sec_gpc_header_not_set_gpc_should_not_be_modified", header: "", - expectedGPC: "", - expectError: false, regs: &openrtb2.Regs{ Ext: []byte(`{}`), }, + expectError: false, expectedRegs: &openrtb2.Regs{ Ext: []byte(`{}`), }, @@ -5654,11 +5651,10 @@ func TestSetGPCImplicitly(t *testing.T) { { description: "sec_gpc_header_set_to_2_gpc_should_not_be_modified", header: "2", - expectedGPC: "", - expectError: false, regs: &openrtb2.Regs{ Ext: []byte(`{}`), }, + expectError: false, expectedRegs: &openrtb2.Regs{ Ext: []byte(`{}`), }, @@ -5666,15 +5662,87 @@ func TestSetGPCImplicitly(t *testing.T) { { description: "sec_gpc_header_set_to_1_and_regs_ext_contains_other_data", header: "1", - expectedGPC: "1", - expectError: false, regs: &openrtb2.Regs{ Ext: []byte(`{"some_other_field":"some_value"}`), }, + expectError: false, expectedRegs: &openrtb2.Regs{ Ext: []byte(`{"some_other_field":"some_value","gpc":"1"}`), }, }, + { + description: "regs_ext_gpc_not_set_and_header_not_set", + header: "", + regs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + }, + { + description: "regs_ext_gpc_not_set_and_header_not_1", + header: "0", + regs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + }, + { + description: "regs_ext_gpc_is_1_and_header_is_1", + header: "1", + regs: &openrtb2.Regs{ + Ext: []byte(`{"gpc":"1"}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{"gpc":"1"}`), + }, + }, + { + description: "regs_ext_gpc_is_1_and_header_not_1", + header: "0", + regs: &openrtb2.Regs{ + Ext: []byte(`{"gpc":"1"}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{"gpc":"1"}`), + }, + }, + { + description: "regs_ext_other_data_and_header_is_1", + header: "1", + regs: &openrtb2.Regs{ + Ext: []byte(`{"other":"value"}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{"other":"value","gpc":"1"}`), + }, + }, + { + description: "regs_nil_and_header_is_1", + header: "1", + regs: nil, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{"gpc":"1"}`), + }, + }, + { + description: "regs_nil_and_header_not_set", + header: "", + regs: nil, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + }, } for _, test := range testCases { diff --git a/openrtb_ext/request_wrapper.go b/openrtb_ext/request_wrapper.go index 2de058e3878..a73cfc9241c 100644 --- a/openrtb_ext/request_wrapper.go +++ b/openrtb_ext/request_wrapper.go @@ -1364,8 +1364,8 @@ func (re *RegExt) GetGPC() *string { if re.gpc == nil { return nil } - GPC := *re.gpc - return &GPC + gpc := *re.gpc + return &gpc } func (re *RegExt) SetGPC(gpc *string) { From 5fba3db03a438cdc354af04b1c30fcf41bffebc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kaczmarek?= Date: Thu, 12 Sep 2024 11:48:11 +0000 Subject: [PATCH 07/10] fix regs_nil_and_header_not_set test --- endpoints/openrtb2/auction.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 1b5a9a4b5b1..f7ee0905528 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -1526,6 +1526,11 @@ func setGPCImplicitly(httpReq *http.Request, r *openrtb_ext.RequestWrapper) erro secGPC := httpReq.Header.Get(secGPCKey) if secGPC != "1" { + if r.BidRequest != nil && r.BidRequest.Regs == nil { + r.BidRequest.Regs = &openrtb2.Regs{ + Ext: []byte(`{}`), + } + } return nil } From f8e7977b7d7332f340a65e603fdbaa506ee07d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kaczmarek?= Date: Thu, 12 Sep 2024 14:17:27 +0000 Subject: [PATCH 08/10] checking validation --- endpoints/openrtb2/auction.go | 5 ----- endpoints/openrtb2/auction_test.go | 9 --------- 2 files changed, 14 deletions(-) diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index f7ee0905528..1b5a9a4b5b1 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -1526,11 +1526,6 @@ func setGPCImplicitly(httpReq *http.Request, r *openrtb_ext.RequestWrapper) erro secGPC := httpReq.Header.Get(secGPCKey) if secGPC != "1" { - if r.BidRequest != nil && r.BidRequest.Regs == nil { - r.BidRequest.Regs = &openrtb2.Regs{ - Ext: []byte(`{}`), - } - } return nil } diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 1ae1e6933d7..aca85efb96c 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -5734,15 +5734,6 @@ func TestSetGPCImplicitly(t *testing.T) { Ext: []byte(`{"gpc":"1"}`), }, }, - { - description: "regs_nil_and_header_not_set", - header: "", - regs: nil, - expectError: false, - expectedRegs: &openrtb2.Regs{ - Ext: []byte(`{}`), - }, - }, } for _, test := range testCases { From b5acce35b770d0af7c92a8eda02850f29d9c33fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kaczmarek?= Date: Mon, 16 Sep 2024 13:30:05 +0000 Subject: [PATCH 09/10] fix comments --- endpoints/openrtb2/auction_test.go | 26 +++++++++++++++++++++++++- openrtb_ext/request_wrapper_test.go | 16 ++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index aca85efb96c..3f8cdc668f9 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -5734,6 +5734,24 @@ func TestSetGPCImplicitly(t *testing.T) { Ext: []byte(`{"gpc":"1"}`), }, }, + { + description: "regs_nil_and_header_not_set", + header: "", + regs: nil, + expectError: false, + expectedRegs: nil, + }, + { + description: "regs_ext_is_nil_and_header_not_set", + header: "", + regs: &openrtb2.Regs{ + Ext: nil, + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: nil, + }, + }, } for _, test := range testCases { @@ -5758,7 +5776,13 @@ func TestSetGPCImplicitly(t *testing.T) { assert.NoError(t, err) } assert.NoError(t, r.RebuildRequest()) - assert.JSONEq(t, string(test.expectedRegs.Ext), string(r.BidRequest.Regs.Ext)) + if test.expectedRegs == nil { + assert.Nil(t, r.BidRequest.Regs) + } else if test.expectedRegs.Ext == nil { + assert.Nil(t, r.BidRequest.Regs.Ext) + } else { + assert.JSONEq(t, string(test.expectedRegs.Ext), string(r.BidRequest.Regs.Ext)) + } }) } } diff --git a/openrtb_ext/request_wrapper_test.go b/openrtb_ext/request_wrapper_test.go index 7b21531e02e..19caa8ce390 100644 --- a/openrtb_ext/request_wrapper_test.go +++ b/openrtb_ext/request_wrapper_test.go @@ -2194,6 +2194,7 @@ func TestRegExtUnmarshal(t *testing.T) { extJson json.RawMessage expectDSA *ExtRegsDSA expectGDPR *int8 + expectGPC *string expectUSPrivacy string expectError bool }{ @@ -2253,6 +2254,21 @@ func TestRegExtUnmarshal(t *testing.T) { expectGDPR: ptrutil.ToPtr[int8](0), expectError: true, }, + // GPC + { + name: "valid_gpc_json", + regExt: &RegExt{}, + extJson: json.RawMessage(`{"gpc":"some_value"}`), + expectGPC: ptrutil.ToPtr("some_value"), + expectError: false, + }, + { + name: "malformed_gpc_json", + regExt: &RegExt{}, + extJson: json.RawMessage(`{"gpc":nill}`), + expectGPC: nil, + expectError: true, + }, // us_privacy { name: "valid_usprivacy_json", From bff49e248ced113d8799522a122e175718d21713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kaczmarek?= Date: Tue, 17 Sep 2024 08:52:43 +0000 Subject: [PATCH 10/10] additional test in request_wrapper_test --- openrtb_ext/request_wrapper_test.go | 39 +++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/openrtb_ext/request_wrapper_test.go b/openrtb_ext/request_wrapper_test.go index 19caa8ce390..c7892b964af 100644 --- a/openrtb_ext/request_wrapper_test.go +++ b/openrtb_ext/request_wrapper_test.go @@ -2174,6 +2174,30 @@ func TestRebuildRegExt(t *testing.T) { regExt: RegExt{usPrivacy: "", usPrivacyDirty: true}, expectedRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{}}, }, + { + name: "req_regs_gpc_populated_-_not_dirty_-_no_change", + request: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"a"}`)}}, + regExt: RegExt{}, + expectedRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"a"}`)}}, + }, + { + name: "req_regs_gpc_populated_-_dirty_and_different-_change", + request: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"a"}`)}}, + regExt: RegExt{gpc: &strB, gpcDirty: true}, + expectedRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"b"}`)}}, + }, + { + name: "req_regs_gpc_populated_-_dirty_and_same_-_no_change", + request: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"a"}`)}}, + regExt: RegExt{gpc: &strA, gpcDirty: true}, + expectedRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"a"}`)}}, + }, + { + name: "req_regs_gpc_populated_-_dirty_and_nil_-_cleared", + request: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"a"}`)}}, + regExt: RegExt{gpc: nil, gpcDirty: true}, + expectedRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{}}, + }, } for _, tt := range tests { @@ -2364,3 +2388,18 @@ func TestRegExtGetGDPRSetGDPR(t *testing.T) { assert.Equal(t, regExtGDPR, gdpr) assert.NotSame(t, regExtGDPR, gdpr) } + +func TestRegExtGetGPCSetGPC(t *testing.T) { + regExt := &RegExt{} + regExtGPC := regExt.GetGPC() + assert.Nil(t, regExtGPC) + assert.False(t, regExt.Dirty()) + + gpc := ptrutil.ToPtr("Gpc") + regExt.SetGPC(gpc) + assert.True(t, regExt.Dirty()) + + regExtGPC = regExt.GetGPC() + assert.Equal(t, regExtGPC, gpc) + assert.NotSame(t, regExtGPC, gpc) +}