github.com/prebid/prebid-server@v0.275.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/v19/openrtb2" 10 "github.com/prebid/prebid-server/adapters" 11 "github.com/prebid/prebid-server/config" 12 "github.com/prebid/prebid-server/errortypes" 13 "github.com/prebid/prebid-server/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 }}, errs 62 } 63 64 func containsAny(raw string, keys []string) bool { 65 lowerCased := strings.ToLower(raw) 66 for i := 0; i < len(keys); i++ { 67 if strings.Contains(lowerCased, keys[i]) { 68 return true 69 } 70 } 71 return false 72 73 } 74 75 func getBidType(bidAdm string) openrtb_ext.BidType { 76 if bidAdm != "" && containsAny(bidAdm, []string{"<?xml", "<vast"}) { 77 return openrtb_ext.BidTypeVideo 78 } 79 return openrtb_ext.BidTypeBanner 80 } 81 82 // MakeBids make the bids for the bid response. 83 func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { 84 85 if response.StatusCode == http.StatusNoContent { 86 // no bid response 87 return nil, nil 88 } 89 90 if response.StatusCode == http.StatusBadRequest { 91 return nil, []error{&errortypes.BadInput{ 92 Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), 93 }} 94 } 95 96 if response.StatusCode != http.StatusOK { 97 return nil, []error{&errortypes.BadServerResponse{ 98 Message: fmt.Sprintf("Invalid Status Returned: %d. Run with request.debug = 1 for more info", response.StatusCode), 99 }} 100 } 101 102 var bidResp openrtb2.BidResponse 103 104 if err := json.Unmarshal(response.Body, &bidResp); err != nil { 105 return nil, []error{&errortypes.BadServerResponse{ 106 Message: fmt.Sprintf("Unable to unpackage bid response. Error: %s", err.Error()), 107 }} 108 } 109 110 var bids []*adapters.TypedBid 111 112 for _, sb := range bidResp.SeatBid { 113 for i := range sb.Bid { 114 115 sb.Bid[i].ImpID = sb.Bid[i].ID 116 117 bids = append(bids, &adapters.TypedBid{ 118 Bid: &sb.Bid[i], 119 BidType: getBidType(sb.Bid[i].AdM), 120 }) 121 } 122 } 123 adsResp := adapters.NewBidderResponseWithBidsCapacity(len(bids)) 124 adsResp.Bids = bids 125 if bidResp.Cur != "" { 126 adsResp.Currency = bidResp.Cur 127 } else { 128 adsResp.Currency = "USD" 129 } 130 131 return adsResp, nil 132 133 }