github.com/prebid/prebid-server/v2@v2.18.0/adapters/jixie/jixie.go (about) 1 package jixie 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "strings" 8 9 "github.com/prebid/openrtb/v20/openrtb2" 10 "github.com/prebid/prebid-server/v2/adapters" 11 "github.com/prebid/prebid-server/v2/config" 12 "github.com/prebid/prebid-server/v2/errortypes" 13 "github.com/prebid/prebid-server/v2/openrtb_ext" 14 ) 15 16 type adapter struct { 17 endpoint string 18 } 19 20 // Builder builds a new instance of the Jixie adapter for the given bidder with the given config. 21 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 22 bidder := &adapter{ 23 endpoint: config.Endpoint, 24 } 25 return bidder, nil 26 } 27 28 // Adding header fields to request header 29 func addHeaderIfNonEmpty(headers http.Header, headerName string, headerValue string) { 30 if len(headerValue) > 0 { 31 headers.Add(headerName, headerValue) 32 } 33 } 34 35 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 36 var errs = make([]error, 0) 37 38 data, err := json.Marshal(request) 39 if err != nil { 40 errs = append(errs, err) 41 return nil, errs 42 } 43 44 headers := http.Header{} 45 headers.Add("Content-Type", "application/json;charset=utf-8") 46 headers.Add("Accept", "application/json") 47 if request.Device != nil { 48 addHeaderIfNonEmpty(headers, "User-Agent", request.Device.UA) 49 addHeaderIfNonEmpty(headers, "X-Forwarded-For", request.Device.IP) 50 } 51 52 if request.Site != nil { 53 addHeaderIfNonEmpty(headers, "Referer", request.Site.Page) 54 } 55 56 return []*adapters.RequestData{{ 57 Method: "POST", 58 Uri: a.endpoint, 59 Body: data, 60 Headers: headers, 61 ImpIDs: openrtb_ext.GetImpIDs(request.Imp), 62 }}, errs 63 } 64 65 func containsAny(raw string, keys []string) bool { 66 lowerCased := strings.ToLower(raw) 67 for i := 0; i < len(keys); i++ { 68 if strings.Contains(lowerCased, keys[i]) { 69 return true 70 } 71 } 72 return false 73 74 } 75 76 func getBidType(bidAdm string) openrtb_ext.BidType { 77 if bidAdm != "" && containsAny(bidAdm, []string{"<?xml", "<vast"}) { 78 return openrtb_ext.BidTypeVideo 79 } 80 return openrtb_ext.BidTypeBanner 81 } 82 83 // MakeBids make the bids for the bid response. 84 func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { 85 86 if response.StatusCode == http.StatusNoContent { 87 // no bid response 88 return nil, nil 89 } 90 91 if response.StatusCode == http.StatusBadRequest { 92 return nil, []error{&errortypes.BadInput{ 93 Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), 94 }} 95 } 96 97 if response.StatusCode != http.StatusOK { 98 return nil, []error{&errortypes.BadServerResponse{ 99 Message: fmt.Sprintf("Invalid Status Returned: %d. Run with request.debug = 1 for more info", response.StatusCode), 100 }} 101 } 102 103 var bidResp openrtb2.BidResponse 104 105 if err := json.Unmarshal(response.Body, &bidResp); err != nil { 106 return nil, []error{&errortypes.BadServerResponse{ 107 Message: fmt.Sprintf("Unable to unpackage bid response. Error: %s", err.Error()), 108 }} 109 } 110 111 var bids []*adapters.TypedBid 112 113 for _, sb := range bidResp.SeatBid { 114 for i := range sb.Bid { 115 116 sb.Bid[i].ImpID = sb.Bid[i].ID 117 118 bids = append(bids, &adapters.TypedBid{ 119 Bid: &sb.Bid[i], 120 BidType: getBidType(sb.Bid[i].AdM), 121 }) 122 } 123 } 124 adsResp := adapters.NewBidderResponseWithBidsCapacity(len(bids)) 125 adsResp.Bids = bids 126 if bidResp.Cur != "" { 127 adsResp.Currency = bidResp.Cur 128 } else { 129 adsResp.Currency = "USD" 130 } 131 132 return adsResp, nil 133 134 }