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