示例#1
0
文件: openrtb.go 项目: jamloop/rtbkit
func (e *Exchange) ServeHTTP(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	ctx = trace.Enter(ctx, "OpenRTB")

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		trace.Error(ctx, "Errors.Read", err)
		w.WriteHeader(http.StatusNoContent)
		return
	}

	value := &jq.Value{}

	if err := value.Unmarshal(body); err != nil {
		trace.Error(ctx, "Errors.Unmarshal", err)
		w.WriteHeader(http.StatusNoContent)
		return
	}

	p := value.NewQuery()
	impid, err := p.String("imp", "@0", "id")
	if err != nil {
		trace.Error(ctx, "Errors.MissingImpressionID", err)
		w.WriteHeader(http.StatusNoContent)
		return
	}

	q := value.NewQuery()
	if err := q.FindObject("imp", "@0", "ext", "creative-ids"); err != nil {
		trace.Error(ctx, "Errors.MissingIDs", err)
		w.WriteHeader(http.StatusNoContent)
		return
	}

	allowed := make(map[string][]string)
	if q.Down() {
		for {
			if q.Down() {
				list := make([]string, 0, q.Count())
				for {
					list = append(list, q.Value())
					if q.Next() == false {
						break
					}
				}

				q.Up()
				allowed[q.Key()] = list
			}

			if q.Next() == false {
				break
			}
		}
	}

	if len(allowed) == 0 {
		trace.Leave(ctx, "NoAllowedBidders")
		w.WriteHeader(http.StatusNoContent)
		return
	}

	ids := make([]string, 0, len(allowed))
	for i := range allowed {
		ids = append(ids, i)
	}

	bidders := e.Bidders.Bidders(ids)

	bestPrice := ""
	bestPriority := ""
	best := -1
	for i := range bidders {
		if bidders[i] == nil {
			continue
		}

		price, priority := bidders[i].Bid(ctx)
		if price == "" {
			continue
		}

		if best != -1 {
			if len(priority) < len(bestPriority) {
				continue
			}

			if len(priority) == len(bestPriority) && priority < bestPriority {
				continue
			}

			if priority == bestPriority {
				if len(price) < len(bestPrice) {
					continue
				}

				if len(price) == len(bestPrice) && price < bestPrice {
					continue
				}
			}
		}

		bestPrice = price
		bestPriority = priority
		best = i
	}

	if best == -1 {
		trace.Leave(ctx, "NoAllowedBidders")
		w.WriteHeader(http.StatusNoContent)
		return
	}

	text := `{"seatbid":[{"bid":[{"impid":"%s","price":%f,"crid":"%s","ext":{"priority":%s,"external-id":%s}}]}]}`

	cpm := 0.0
	if money, err := strconv.Atoi(strings.TrimSuffix(bestPrice, "USD/1M")); err != nil {
		trace.Error(ctx, "Errors.Price", err)
		w.WriteHeader(http.StatusNoContent)
		return
	} else {
		cpm = float64(money) / 1000.0
	}

	cid := ids[best]

	augmenters := bidders[best].Augmenters
	if augmenters != nil {
		if f := augmenters.Forensiq; e.Client != nil && f != nil {
			r := &rtb.Components{}
			r.Attach("fields", value)

			score := e.forensiqRiskScore(ctx, r)
			trace.Record(ctx, "Score", score)

			if score > f.Configuration.RiskScore {
				trace.Leave(ctx, "ForensiqRiskScore")
				w.WriteHeader(http.StatusNoContent)
				return
			}
		}
	}

	crid := allowed[cid][0]

	b := string(body)
	if strings.Contains(b, cid) == false {
		log.Println(b)
		log.Println(allowed, ids, cid, crid, best)
	}

	w.Header().Set("Content-Type", "application/json")
	if _, err := fmt.Fprintf(w, text, impid, cpm, crid, bestPriority, cid); err != nil {
		trace.Error(ctx, "Errors.Response", err)
		return
	}

	//jsons.Put(value)

	trace.Leave(ctx, "Responded")
}