Skip to content

Commit 3bbbbc7

Browse files
Address PR #80 review: harden verification trust model and align docs with fixed pricing
- Cross-check ext.trusted_server host/scheme against server-observed values - Enforce timestamp freshness window (±5 min) to prevent replay attacks - Add field-order warning comment on SigningPayload struct - Fix ts unit mismatch: align tests with docs (milliseconds) - Add positive-path Ed25519 round-trip test with deterministic keypair - Remove debug log leftover in fetch_jwks - Simplify APS size selection to area-based ranking (replaces CPM) - Remove CPM from /sizes endpoint response - Rename test to test_ext_bid_override_is_ignored - Docs sweep: remove bid override references across all doc pages
1 parent d0a46dc commit 3bbbbc7

10 files changed

Lines changed: 310 additions & 158 deletions

File tree

crates/mocktioneer-core/src/auction.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -241,21 +241,21 @@ pub fn build_aps_response(req: &ApsBidRequest, base_host: &str) -> ApsBidRespons
241241
let mut slots: Vec<ApsSlotResponse> = Vec::new();
242242

243243
for slot in req.slots.iter() {
244-
// Find the standard size with the highest CPM from all sizes in the slot
244+
// Find the standard size with the largest area from all sizes in the slot
245245
let best_size = slot
246246
.sizes
247247
.iter()
248248
.filter_map(|&[w, h]| {
249249
let w_i64 = w as i64;
250250
let h_i64 = h as i64;
251251
if is_standard_size(w_i64, h_i64) {
252-
let price = get_cpm(w_i64, h_i64);
253-
Some((w, h, price))
252+
let area = w_i64 * h_i64;
253+
Some((w, h, area))
254254
} else {
255255
None
256256
}
257257
})
258-
.max_by(|a, b| a.2.partial_cmp(&b.2).unwrap_or(std::cmp::Ordering::Equal));
258+
.max_by_key(|&(_, _, area)| area);
259259

260260
let Some((w, h, _)) = best_size else {
261261
// No standard sizes found, skip this slot
@@ -471,7 +471,7 @@ mod tests {
471471
}
472472

473473
#[test]
474-
fn test_price_from_ext_and_iframe_bid_param() {
474+
fn test_ext_bid_override_is_ignored() {
475475
let req = OpenRTBRequest {
476476
id: "r4".to_string(),
477477
imp: vec![OpenrtbImp {
@@ -548,12 +548,12 @@ mod tests {
548548
}
549549

550550
#[test]
551-
fn test_build_aps_response_selects_highest_cpm() {
551+
fn test_build_aps_response_selects_largest_area() {
552552
let req = ApsBidRequest {
553553
pub_id: "test".to_string(),
554554
slots: vec![ApsSlot {
555555
slot_id: "slot1".to_string(),
556-
sizes: vec![[300, 250], [970, 250]], // 970x250 has higher CPM ($4.20 vs $2.50)
556+
sizes: vec![[300, 250], [970, 250]], // 970x250 has larger area (242500 vs 75000)
557557
slot_name: None,
558558
}],
559559
page_url: None,
@@ -564,7 +564,7 @@ mod tests {
564564

565565
assert_eq!(resp.contextual.slots.len(), 1);
566566
let slot = &resp.contextual.slots[0];
567-
assert_eq!(slot.size, "970x250"); // Should pick higher CPM size
567+
assert_eq!(slot.size, "970x250"); // Should pick largest area
568568
}
569569

570570
#[test]

crates/mocktioneer-core/src/routes.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,14 @@ pub async fn handle_openrtb_auction(
239239
ForwardedHost(host): ForwardedHost,
240240
ValidatedJson(req): ValidatedJson<OpenRTBRequest>,
241241
) -> Result<Response, EdgeError> {
242+
// Determine server-observed scheme from X-Forwarded-Proto header, default to "https"
243+
let scheme = ctx
244+
.request()
245+
.headers()
246+
.get("x-forwarded-proto")
247+
.and_then(|v| v.to_str().ok())
248+
.unwrap_or("https");
249+
242250
// Capture signature verification status for metadata
243251
let signature_status = if let Some(domain) = req.site.as_ref().and_then(|s| s.domain.as_deref())
244252
{
@@ -247,6 +255,8 @@ pub async fn handle_openrtb_auction(
247255
&req.id,
248256
req.ext.as_ref(),
249257
domain,
258+
&host,
259+
scheme,
250260
)
251261
.await
252262
{
@@ -498,22 +508,19 @@ pub async fn handle_click(ValidatedQuery(params): ValidatedQuery<ClickQueryParam
498508
/// ```json
499509
/// {
500510
/// "sizes": [
501-
/// {"width": 300, "height": 250, "cpm": 2.5},
502-
/// {"width": 728, "height": 90, "cpm": 3.0},
511+
/// {"width": 300, "height": 250},
512+
/// {"width": 728, "height": 90},
503513
/// ...
504514
/// ]
505515
/// }
506516
/// ```
507517
#[action]
508518
pub async fn handle_sizes() -> Response {
509-
use crate::auction::get_cpm;
510-
511519
let sizes: Vec<serde_json::Value> = standard_sizes()
512520
.map(|(w, h)| {
513521
serde_json::json!({
514522
"width": w,
515-
"height": h,
516-
"cpm": get_cpm(w, h)
523+
"height": h
517524
})
518525
})
519526
.collect();
@@ -1002,6 +1009,7 @@ mod tests {
10021009
let first = &sizes[0];
10031010
assert!(first["width"].is_i64());
10041011
assert!(first["height"].is_i64());
1005-
assert!(first["cpm"].is_f64());
1012+
// CPM is no longer included — bid price is fixed at FIXED_BID_CPM
1013+
assert!(first.get("cpm").is_none());
10061014
}
10071015
}

0 commit comments

Comments
 (0)