Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ORTB 2.4 schain support #2108

Merged
merged 10 commits into from
Jan 13, 2022
3 changes: 2 additions & 1 deletion endpoints/openrtb2/auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/prebid/prebid-server/prebid_cache_client"
"github.com/prebid/prebid-server/privacy/ccpa"
"github.com/prebid/prebid-server/privacy/lmt"
"github.com/prebid/prebid-server/schain"
"github.com/prebid/prebid-server/stored_requests"
"github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher"
"github.com/prebid/prebid-server/usersync"
Expand Down Expand Up @@ -595,7 +596,7 @@ func (deps *endpointDeps) validateBidAdjustmentFactors(adjustmentFactors map[str
}

func validateSChains(sChains []*openrtb_ext.ExtRequestPrebidSChain) error {
_, err := exchange.BidderToPrebidSChains(sChains)
_, err := schain.BidderToPrebidSChains(sChains)
return err
}

Expand Down
85 changes: 26 additions & 59 deletions exchange/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/prebid/prebid-server/privacy"
"github.com/prebid/prebid-server/privacy/ccpa"
"github.com/prebid/prebid-server/privacy/lmt"
"github.com/prebid/prebid-server/schain"
)

var integrationTypeMap = map[metrics.RequestType]config.IntegrationType{
Expand All @@ -31,23 +32,6 @@ var integrationTypeMap = map[metrics.RequestType]config.IntegrationType{

const unknownBidder string = ""

func BidderToPrebidSChains(sChains []*openrtb_ext.ExtRequestPrebidSChain) (map[string]*openrtb_ext.ExtRequestPrebidSChainSChain, error) {
Copy link
Collaborator Author

@bsardo bsardo Dec 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function was copied to schain/schain.go.

bidderToSChains := make(map[string]*openrtb_ext.ExtRequestPrebidSChainSChain)

for _, schainWrapper := range sChains {
for _, bidder := range schainWrapper.Bidders {
if _, present := bidderToSChains[bidder]; present {
return nil, fmt.Errorf("request.ext.prebid.schains contains multiple schains for bidder %s; "+
"it must contain no more than one per bidder.", bidder)
} else {
bidderToSChains[bidder] = &schainWrapper.SChain
}
}
}

return bidderToSChains, nil
}

// cleanOpenRTBRequests splits the input request into requests which are sanitized for each bidder. Intended behavior is:
//
// 1. BidRequest.Imp[].Ext will only contain the "prebid" field and a "bidder" field which has the params for the intended Bidder.
Expand Down Expand Up @@ -210,6 +194,22 @@ func extractLMT(orig *openrtb2.BidRequest, privacyConfig config.Privacy) privacy
}
}

func unpackSourceExt(bidRequest *openrtb2.BidRequest) (*openrtb_ext.ExtSource, error) {
var sourceExt *openrtb_ext.ExtSource

if bidRequest.Source == nil || bidRequest.Source.Ext == nil {
return nil, nil
}

if len(bidRequest.Source.Ext) > 0 {
err := json.Unmarshal(bidRequest.Source.Ext, &sourceExt)
if err != nil {
return nil, fmt.Errorf("Error decoding Request.source.ext: %s", err.Error())
}
}
return sourceExt, nil
}

func getAuctionBidderRequests(req AuctionRequest,
requestExt *openrtb_ext.ExtRequest,
bidderToSyncerKey map[string]string,
Expand All @@ -228,14 +228,14 @@ func getAuctionBidderRequests(req AuctionRequest,
return nil, []error{err}
}

var sChainsByBidder map[string]*openrtb_ext.ExtRequestPrebidSChainSChain
requestSourceExt, err := unpackSourceExt(req.BidRequest)
if err != nil {
return nil, []error{err}
}

// Quick extra wrapper until RequestWrapper makes its way into CleanRequests
if requestExt != nil {
sChainsByBidder, err = BidderToPrebidSChains(requestExt.Prebid.SChains)
if err != nil {
return nil, []error{err}
}
sChainWriter, err := schain.NewSChainWriter(requestExt, requestSourceExt)
if err != nil {
return nil, []error{err}
}

var errs []error
Expand All @@ -245,7 +245,7 @@ func getAuctionBidderRequests(req AuctionRequest,
reqCopy := *req.BidRequest
reqCopy.Imp = imps

prepareSource(&reqCopy, bidder, sChainsByBidder)
sChainWriter.Write(&reqCopy, bidder)

if len(bidderParamsInReqExt) != 0 {

Expand Down Expand Up @@ -315,43 +315,10 @@ func getExtJson(req *openrtb2.BidRequest, unpackedExt *openrtb_ext.ExtRequest) (

extCopy := *unpackedExt
extCopy.Prebid.SChains = nil
extCopy.SChain = nil
return json.Marshal(extCopy)
}

func prepareSource(req *openrtb2.BidRequest, bidder string, sChainsByBidder map[string]*openrtb_ext.ExtRequestPrebidSChainSChain) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic has been moved to the schain writer implementation Write methods.

const sChainWildCard = "*"
var selectedSChain *openrtb_ext.ExtRequestPrebidSChainSChain

wildCardSChain := sChainsByBidder[sChainWildCard]
bidderSChain := sChainsByBidder[bidder]

// source should not be modified
if bidderSChain == nil && wildCardSChain == nil {
return
}

if bidderSChain != nil {
selectedSChain = bidderSChain
} else {
selectedSChain = wildCardSChain
}

// set source
if req.Source == nil {
req.Source = &openrtb2.Source{}
} else {
sourceCopy := *req.Source
req.Source = &sourceCopy
}
schain := openrtb_ext.ExtRequestPrebidSChain{
SChain: *selectedSChain,
}
sourceExt, err := json.Marshal(schain)
if err == nil {
req.Source.Ext = sourceExt
}
}

// extractBuyerUIDs parses the values from user.ext.prebid.buyeruids, and then deletes those values from the ext.
// This prevents a Bidder from using these values to figure out who else is involved in the Auction.
func extractBuyerUIDs(user *openrtb2.User) (map[string]string, error) {
Expand Down
Loading