github.com/prebid/prebid-server/v2@v2.18.0/openrtb_ext/multibid.go (about) 1 package openrtb_ext 2 3 import "fmt" 4 5 const DefaultBidLimit = 1 6 const MaxBidLimit = 9 7 8 func ValidateAndBuildExtMultiBid(prebid *ExtRequestPrebid) ([]*ExtMultiBid, []error) { 9 if prebid == nil || prebid.MultiBid == nil { 10 return nil, nil 11 } 12 13 var validationErrs, errs []error 14 var validatedMultiBids, newMultiBids []*ExtMultiBid //returning slice instead of map to keep the downstream req.Ext payload consistent 15 multiBidMap := make(map[string]struct{}) // map is needed temporarily for validate of duplicate entries, etc. 16 for _, multiBid := range prebid.MultiBid { 17 newMultiBids, errs = addMultiBid(multiBidMap, multiBid) 18 if len(errs) != 0 { 19 validationErrs = append(validationErrs, errs...) 20 } 21 if len(newMultiBids) != 0 { 22 validatedMultiBids = append(validatedMultiBids, newMultiBids...) 23 } 24 } 25 26 return validatedMultiBids, validationErrs 27 } 28 29 // Validate and add multiBid 30 func addMultiBid(multiBidMap map[string]struct{}, multiBid *ExtMultiBid) ([]*ExtMultiBid, []error) { 31 errs := make([]error, 0) 32 33 if multiBid.MaxBids == nil { 34 errs = append(errs, fmt.Errorf("maxBids not defined for %v", *multiBid)) 35 return nil, errs 36 } 37 38 if *multiBid.MaxBids < DefaultBidLimit { 39 errs = append(errs, fmt.Errorf("invalid maxBids value, using minimum %d limit for %v", DefaultBidLimit, *multiBid)) 40 *multiBid.MaxBids = DefaultBidLimit 41 } 42 43 if *multiBid.MaxBids > MaxBidLimit { 44 errs = append(errs, fmt.Errorf("invalid maxBids value, using maximum %d limit for %v", MaxBidLimit, *multiBid)) 45 *multiBid.MaxBids = MaxBidLimit 46 } 47 48 var validatedMultiBids []*ExtMultiBid 49 if multiBid.Bidder != "" { 50 if _, ok := multiBidMap[multiBid.Bidder]; ok { 51 errs = append(errs, fmt.Errorf("multiBid already defined for %s, ignoring this instance %v", multiBid.Bidder, *multiBid)) 52 return nil, errs 53 } 54 55 if multiBid.Bidders != nil { 56 errs = append(errs, fmt.Errorf("ignoring bidders from %v", *multiBid)) 57 multiBid.Bidders = nil 58 } 59 multiBidMap[multiBid.Bidder] = struct{}{} 60 validatedMultiBids = append(validatedMultiBids, multiBid) 61 } else if len(multiBid.Bidders) > 0 { 62 var bidders []string 63 for _, bidder := range multiBid.Bidders { 64 if _, ok := multiBidMap[bidder]; ok { 65 errs = append(errs, fmt.Errorf("multiBid already defined for %s, ignoring this instance %v", bidder, *multiBid)) 66 continue 67 } 68 multiBidMap[bidder] = struct{}{} 69 bidders = append(bidders, bidder) 70 } 71 if multiBid.TargetBidderCodePrefix != "" { 72 errs = append(errs, fmt.Errorf("ignoring targetbiddercodeprefix for %v", *multiBid)) 73 multiBid.TargetBidderCodePrefix = "" 74 } 75 if len(bidders) != 0 { 76 validatedMultiBids = append(validatedMultiBids, &ExtMultiBid{ 77 MaxBids: multiBid.MaxBids, 78 Bidders: bidders, 79 }) 80 } 81 } else { 82 errs = append(errs, fmt.Errorf("bidder(s) not specified for %v", *multiBid)) 83 } 84 return validatedMultiBids, errs 85 }