-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathendpoints.rs
More file actions
97 lines (84 loc) · 3.22 KB
/
endpoints.rs
File metadata and controls
97 lines (84 loc) · 3.22 KB
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
//! HTTP endpoint handlers for auction requests.
use error_stack::{Report, ResultExt};
use fastly::{Request, Response};
use crate::auction::formats::AdRequest;
use crate::ec::EcContext;
use crate::error::TrustedServerError;
use crate::settings::Settings;
use super::formats::{convert_to_openrtb_response, convert_tsjs_to_auction_request};
use super::types::AuctionContext;
use super::AuctionOrchestrator;
/// Handle auction request from /auction endpoint.
///
/// This is the main entry point for running header bidding auctions.
/// It orchestrates bids from multiple providers (Prebid, APS, GAM, etc.) and returns
/// the winning bids in `OpenRTB` format with creative HTML inline in the `adm` field.
///
/// # Errors
///
/// Returns an error if:
/// - The request body cannot be parsed
/// - The auction request conversion fails (e.g., invalid ad units)
/// - The auction execution fails
/// - The response cannot be serialized
pub async fn handle_auction(
settings: &Settings,
orchestrator: &AuctionOrchestrator,
mut req: Request,
) -> Result<Response, Report<TrustedServerError>> {
// Read EC state before consuming the request body.
let mut ec_context = EcContext::read_from_request(settings, &req).change_context(
TrustedServerError::Auction {
message: "Failed to read EC context".to_string(),
},
)?;
// Auction is an organic handler — generate EC if needed.
if let Err(err) = ec_context.generate_if_needed(settings) {
log::warn!("EC generation failed for auction: {err:?}");
}
// Parse request body
let body: AdRequest = serde_json::from_slice(&req.take_body_bytes()).change_context(
TrustedServerError::Auction {
message: "Failed to parse auction request body".to_string(),
},
)?;
log::info!(
"Auction request received for {} ad units",
body.ad_units.len()
);
// Only forward the EC ID to auction partners when consent allows it.
// A returning user may still have a ts-ec cookie but have since
// withdrawn consent — forwarding that revoked ID to bidders would
// defeat the consent gating.
let ec_id = if ec_context.ec_allowed() {
ec_context.ec_value().unwrap_or("")
} else {
""
};
let consent_context = ec_context.consent().clone();
// Convert tsjs request format to auction request
let auction_request =
convert_tsjs_to_auction_request(&body, settings, &req, consent_context, ec_id)?;
// Create auction context
let context = AuctionContext {
settings,
request: &req,
timeout_ms: settings.auction.timeout_ms,
provider_responses: None,
};
// Run the auction
let result = orchestrator
.run_auction(&auction_request, &context)
.await
.change_context(TrustedServerError::Auction {
message: "Auction orchestration failed".to_string(),
})?;
log::info!(
"Auction completed: {} providers, {} winning bids, {}ms total",
result.provider_responses.len(),
result.winning_bids.len(),
result.total_time_ms
);
// Convert to OpenRTB response format with inline creative HTML
convert_to_openrtb_response(&result, settings, &auction_request)
}