forked from prebid/prebid-server
-
Notifications
You must be signed in to change notification settings - Fork 1
/
bidders.go
123 lines (105 loc) · 3.83 KB
/
bidders.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
package openrtb_ext
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"net/http"
"strings"
"github.com/mxmCherry/openrtb"
"github.com/xeipuuv/gojsonschema"
)
const schemaDirectory = "static/bidder-params"
type BidderName string
const (
BidderAppnexus BidderName = "appnexus"
BidderFacebook BidderName = "audienceNetwork"
BidderIndex BidderName = "indexExchange"
BidderLifestreet BidderName = "lifestreet"
BidderPubmatic BidderName = "pubmatic"
BidderPulsepoint BidderName = "pulsepoint"
BidderRubicon BidderName = "rubicon"
BidderConversant BidderName = "conversant"
)
// BidderMap stores all the valid OpenRTB 2.x Bidders in the project. This map *must not* be mutated.
var BidderMap = map[string]BidderName{
"appnexus": BidderAppnexus,
"audienceNetwork": BidderFacebook,
"indexExchange": BidderIndex,
"lifestreet": BidderLifestreet,
"pubmatic": BidderPubmatic,
"pulsepoint": BidderPulsepoint,
"rubicon": BidderRubicon,
"conversant": BidderConversant,
}
func (name BidderName) MarshalJSON() ([]byte, error) {
return []byte(name), nil
}
func (name *BidderName) String() string {
if name == nil {
return ""
} else {
return string(*name)
}
}
// The BidderParamValidator is used to enforce bidrequest.imp[i].ext.{anyBidder} values.
//
// This is treated differently from the other types because we rely on JSON-schemas to validate bidder params.
type BidderParamValidator interface {
Validate(name BidderName, ext openrtb.RawJSON) error
// Schema returns the JSON schema used to perform validation.
Schema(name BidderName) string
}
// NewBidderParamsValidator makes a BidderParamValidator, assuming all the necessary files exist in the filesystem.
// This will error if, for example, a Bidder gets added but no JSON schema is written for them.
func NewBidderParamsValidator(schemaDirectory string) (BidderParamValidator, error) {
filesystem := http.Dir(schemaDirectory)
fileInfos, err := ioutil.ReadDir(schemaDirectory)
if err != nil {
return nil, fmt.Errorf("Failed to read JSON schemas from directory %s. %v", schemaDirectory, err)
}
schemaContents := make(map[BidderName]string, 50)
schemas := make(map[BidderName]*gojsonschema.Schema, 50)
for _, fileInfo := range fileInfos {
bidderName := strings.TrimSuffix(fileInfo.Name(), ".json")
if _, isValid := BidderMap[bidderName]; !isValid {
return nil, fmt.Errorf("File %s/%s does not match a valid BidderName.", schemaDirectory, fileInfo.Name())
}
schemaLoader := gojsonschema.NewReferenceLoaderFileSystem(fmt.Sprintf("file:///%s", fileInfo.Name()), filesystem)
loadedSchema, err := gojsonschema.NewSchema(schemaLoader)
if err != nil {
return nil, fmt.Errorf("Failed to load json schema at %s/%s: %v", schemaDirectory, fileInfo.Name(), err)
}
fileBytes, err := ioutil.ReadFile(fmt.Sprintf("%s/%s", schemaDirectory, fileInfo.Name()))
if err != nil {
return nil, fmt.Errorf("Failed to read file %s/%s: %v", schemaDirectory, fileInfo.Name(), err)
}
schemas[BidderName(bidderName)] = loadedSchema
schemaContents[BidderName(bidderName)] = string(fileBytes)
}
return &bidderParamValidator{
schemaContents: schemaContents,
parsedSchemas: schemas,
}, nil
}
type bidderParamValidator struct {
schemaContents map[BidderName]string
parsedSchemas map[BidderName]*gojsonschema.Schema
}
func (validator *bidderParamValidator) Validate(name BidderName, ext openrtb.RawJSON) error {
result, err := validator.parsedSchemas[name].Validate(gojsonschema.NewBytesLoader(ext))
if err != nil {
return err
}
if !result.Valid() {
errBuilder := bytes.NewBuffer(make([]byte, 0, 300))
for _, err := range result.Errors() {
errBuilder.WriteString(err.String())
}
return errors.New(errBuilder.String())
}
return nil
}
func (validator *bidderParamValidator) Schema(name BidderName) string {
return validator.schemaContents[name]
}