forked from prebid/prebid-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit from asweeney and bokelley
- Loading branch information
Showing
31 changed files
with
7,899 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
language: go | ||
go: | ||
- 1.8.1 | ||
- master | ||
|
||
install: | ||
- glide update | ||
|
||
script: | ||
- ./validate.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
FROM alpine | ||
MAINTAINER Brian O'Kelley <[email protected]> | ||
ADD prebid-server prebid-server | ||
ADD static/* static/ | ||
EXPOSE 8000 | ||
ENTRYPOINT ["/prebid-server"] | ||
CMD ["-v", "1", "-logtostderr"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,36 @@ | ||
# prebid-server | ||
Server side component to offload prebid processing to the cloud | ||
|
||
# How it works | ||
The client (typically prebid.js) sends a JSON request to Prebid Server at `/auction`. See static/pbs_request.json for the format. | ||
Prebid Server forms OpenRTB requests, sends them to the appropriate adapters, concatenates the responses, and returns them | ||
to the client. | ||
|
||
A few key points: | ||
* No ranking or decisioning is performed by Prebid Server. It just proxies requests. | ||
* No ad quality management (malware, viruses, deceptive creatives) is performed by Prebid Server | ||
* Prebid Server does no fraud scanning and does nothing to prevent bad traffic. | ||
|
||
# User synching | ||
Prebid Server provides a `/setuid` endpoint that allows adapters to push in their user IDs. These are stored in a cookie named, | ||
creatively, `uids`. To see stored cookies, call `/getuids`. To set an optout cookie, call `/optout`. When an adapter doesn't | ||
have a synched cookie, a `no_cookie` response is returned with a usersync URL that the client should call via asynchronous pixel | ||
or equivalent. If Prebid Server doesn't have a cookie set, a preemptive `no_cookie` response is returned to allow the client | ||
to ask for user consent and drop a cookie. | ||
|
||
# Logging | ||
Prebid Server does no server-side logging. It can stream metrics to an InfluxDB endpoint, which are aggregated as a time series. | ||
Prebid Server has no user profiling or user-data collection capabilities. | ||
|
||
# Data integration | ||
Prebid Server has three primary data objects that it needs to manage: | ||
* Accounts represent publishers, and are used for metrics aggregation and terms of service adherence. Requests without an | ||
active account will be rejected. | ||
* Domains are compared to the HTTP Referer header; all unknown/unapproved domains will be rejected. | ||
* Configs are used for server-side configuration of adapters, primarily for use with mobile apps where managing configs | ||
client-side is ineffective. | ||
|
||
# Up Next | ||
* Refine adapters and openrtb protocol (support burl? validation of responses?) | ||
* Support Prebid mobile SDK | ||
* Video and native |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package adapters | ||
|
||
import ( | ||
"context" | ||
"crypto/tls" | ||
"github.com/prebid/prebid-server/pbs" | ||
"github.com/prebid/prebid-server/ssl" | ||
"net/http" | ||
"time" | ||
) | ||
|
||
type Adapter interface { | ||
Name() string | ||
FamilyName() string | ||
GetUsersyncInfo() *pbs.UsersyncInfo | ||
Call(ctx context.Context, req *pbs.PBSRequest, bidder *pbs.PBSBidder) (pbs.PBSBidSlice, error) | ||
} | ||
|
||
type HTTPAdapterConfig struct { | ||
IdleConnTimeout time.Duration | ||
MaxConns int | ||
MaxIdleConnsPerHost int | ||
MaxConnsPerHost int | ||
} | ||
|
||
type HTTPAdapter struct { | ||
Transport *http.Transport | ||
Client *http.Client | ||
} | ||
|
||
var DefaultHTTPAdapterConfig = &HTTPAdapterConfig{ | ||
MaxConns: 50, | ||
MaxConnsPerHost: 10, | ||
MaxIdleConnsPerHost: 3, | ||
IdleConnTimeout: 60 * time.Second, | ||
} | ||
|
||
func NewHTTPAdapter(c *HTTPAdapterConfig) *HTTPAdapter { | ||
ts := &http.Transport{ | ||
MaxIdleConns: c.MaxConns, | ||
MaxIdleConnsPerHost: c.MaxConnsPerHost, | ||
IdleConnTimeout: c.IdleConnTimeout, | ||
TLSClientConfig: &tls.Config{RootCAs: ssl.GetRootCAPool()}, | ||
} | ||
|
||
return &HTTPAdapter{ | ||
Transport: ts, | ||
Client: &http.Client{ | ||
Transport: ts, | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
package adapters | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"github.com/prebid/prebid-server/pbs" | ||
"io/ioutil" | ||
"net/http" | ||
"net/url" | ||
|
||
"golang.org/x/net/context/ctxhttp" | ||
|
||
"github.com/prebid/openrtb" | ||
) | ||
|
||
type AppNexusAdapter struct { | ||
http *HTTPAdapter | ||
URI string | ||
usersyncInfo *pbs.UsersyncInfo | ||
} | ||
|
||
/* Name - export adapter name */ | ||
func (a *AppNexusAdapter) Name() string { | ||
return "AppNexus" | ||
} | ||
|
||
// used for cookies and such | ||
func (a *AppNexusAdapter) FamilyName() string { | ||
return "adnxs" | ||
} | ||
|
||
func (a *AppNexusAdapter) GetUsersyncInfo() *pbs.UsersyncInfo { | ||
return a.usersyncInfo | ||
} | ||
|
||
type appnexusParams struct { | ||
PlacementId string `json:"placementId"` | ||
invCode string `json:"invCode"` | ||
member string `json:"member"` | ||
} | ||
|
||
func (a *AppNexusAdapter) Call(ctx context.Context, req *pbs.PBSRequest, bidder *pbs.PBSBidder) (pbs.PBSBidSlice, error) { | ||
anReq := makeOpenRTBGeneric(req, bidder, a.FamilyName()) | ||
for i, unit := range bidder.AdUnits { | ||
var params appnexusParams | ||
err := json.Unmarshal(unit.Params, ¶ms) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if params.PlacementId == "" { | ||
return nil, errors.New("Missing placementId param") | ||
} | ||
anReq.Imp[i].TagID = params.PlacementId | ||
// TODO: support member + invCode | ||
} | ||
|
||
reqJSON, err := json.Marshal(anReq) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if req.IsDebug { | ||
bidder.Debug.RequestURI = a.URI | ||
bidder.Debug.RequestBody = string(reqJSON) | ||
} | ||
|
||
httpReq, err := http.NewRequest("POST", a.URI, bytes.NewBuffer(reqJSON)) | ||
httpReq.Header.Add("Content-Type", "application/json;charset=utf-8") | ||
httpReq.Header.Add("Accept", "application/json") | ||
|
||
anResp, err := ctxhttp.Do(ctx, a.http.Client, httpReq) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if req.IsDebug { | ||
bidder.Debug.StatusCode = anResp.StatusCode | ||
} | ||
|
||
if anResp.StatusCode == 204 { | ||
return nil, nil | ||
} | ||
|
||
if anResp.StatusCode != 200 { | ||
return nil, errors.New(fmt.Sprintf("HTTP status code %d", anResp.StatusCode)) | ||
} | ||
|
||
defer anResp.Body.Close() | ||
body, err := ioutil.ReadAll(anResp.Body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if req.IsDebug { | ||
bidder.Debug.ResponseBody = string(body) | ||
} | ||
|
||
var bidResp openrtb.BidResponse | ||
err = json.Unmarshal(body, &bidResp) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
bids := make(pbs.PBSBidSlice, 0) | ||
|
||
numBids := 0 | ||
for _, sb := range bidResp.SeatBid { | ||
for _, bid := range sb.Bid { | ||
numBids++ | ||
|
||
bidID := bidder.LookupBidID(bid.ImpID) | ||
if bidID == "" { | ||
return nil, errors.New(fmt.Sprintf("Unknown ad unit code '%s'", bid.ImpID)) | ||
} | ||
|
||
pbid := pbs.PBSBid{ | ||
BidID: bidID, | ||
AdUnitCode: bid.ImpID, | ||
BidderCode: bidder.BidderCode, | ||
Price: bid.Price, | ||
Adm: bid.AdM, | ||
Creative_id: bid.CrID, | ||
Width: bid.W, | ||
Height: bid.H, | ||
DealId: bid.DealID, | ||
} | ||
bids = append(bids, &pbid) | ||
} | ||
} | ||
|
||
return bids, nil | ||
} | ||
|
||
func NewAppNexusAdapter(config *HTTPAdapterConfig, externalURL string) *AppNexusAdapter { | ||
a := NewHTTPAdapter(config) | ||
|
||
redirect_uri := fmt.Sprintf("%s/setuid?bidder=adnxs&uid=$UID", externalURL) | ||
usersyncURL := "https://ib.adnxs.com/getuid?" | ||
|
||
info := &pbs.UsersyncInfo{ | ||
URL: fmt.Sprintf("%s%s", usersyncURL, url.QueryEscape(redirect_uri)), | ||
Type: "redirect", | ||
SupportCORS: false, | ||
} | ||
|
||
return &AppNexusAdapter{ | ||
http: a, | ||
// TODO: Get new endpoint from sweeney | ||
URI: "http://ib.adnxs.com/openrtb2?member_id=958", | ||
usersyncInfo: info, | ||
} | ||
} |
Oops, something went wrong.