github.com/prebid/prebid-server/v2@v2.18.0/schain/schainwriter.go (about) 1 package schain 2 3 import ( 4 "github.com/prebid/openrtb/v20/openrtb2" 5 "github.com/prebid/prebid-server/v2/openrtb_ext" 6 "github.com/prebid/prebid-server/v2/util/jsonutil" 7 ) 8 9 // NewSChainWriter creates an ORTB 2.5 schain writer instance 10 func NewSChainWriter(reqExt *openrtb_ext.ExtRequest, hostSChainNode *openrtb2.SupplyChainNode) (*SChainWriter, error) { 11 if !extPrebidSChainExists(reqExt) { 12 return &SChainWriter{hostSChainNode: hostSChainNode}, nil 13 } 14 15 sChainsByBidder, err := BidderToPrebidSChains(reqExt.Prebid.SChains) 16 if err != nil { 17 return nil, err 18 } 19 20 writer := SChainWriter{ 21 sChainsByBidder: sChainsByBidder, 22 hostSChainNode: hostSChainNode, 23 } 24 return &writer, nil 25 } 26 27 // SChainWriter is used to write the appropriate schain for a particular bidder defined in the ORTB 2.5 multi-schain 28 // location (req.ext.prebid.schain) to the ORTB 2.5 location (req.source.ext) 29 type SChainWriter struct { 30 sChainsByBidder map[string]*openrtb2.SupplyChain 31 hostSChainNode *openrtb2.SupplyChainNode 32 } 33 34 // Write selects an schain from the multi-schain ORTB 2.5 location (req.ext.prebid.schains) for the specified bidder 35 // and copies it to the ORTB 2.5 location (req.source.ext). If no schain exists for the bidder in the multi-schain 36 // location and no wildcard schain exists, the request is not modified. 37 func (w SChainWriter) Write(req *openrtb2.BidRequest, bidder string) { 38 const sChainWildCard = "*" 39 var selectedSChain *openrtb2.SupplyChain 40 41 wildCardSChain := w.sChainsByBidder[sChainWildCard] 42 bidderSChain := w.sChainsByBidder[bidder] 43 44 // source should not be modified 45 if bidderSChain == nil && wildCardSChain == nil && w.hostSChainNode == nil { 46 return 47 } 48 49 selectedSChain = &openrtb2.SupplyChain{Ver: "1.0"} 50 51 if bidderSChain != nil { 52 selectedSChain = bidderSChain 53 } else if wildCardSChain != nil { 54 selectedSChain = wildCardSChain 55 } 56 57 schain := openrtb_ext.ExtRequestPrebidSChain{ 58 SChain: *selectedSChain, 59 } 60 61 if req.Source == nil { 62 req.Source = &openrtb2.Source{} 63 } else { 64 sourceCopy := *req.Source 65 req.Source = &sourceCopy 66 } 67 68 if w.hostSChainNode != nil { 69 schain.SChain.Nodes = append(schain.SChain.Nodes, *w.hostSChainNode) 70 } 71 72 sourceExt, err := jsonutil.Marshal(schain) 73 if err == nil { 74 req.Source.Ext = sourceExt 75 } 76 } 77 78 // extPrebidSChainExists checks if an schain exists in the ORTB 2.5 req.ext.prebid.schain location 79 func extPrebidSChainExists(reqExt *openrtb_ext.ExtRequest) bool { 80 return reqExt != nil && reqExt.Prebid.SChains != nil 81 }