-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathendpoints.rs
More file actions
116 lines (102 loc) · 3.72 KB
/
endpoints.rs
File metadata and controls
116 lines (102 loc) · 3.72 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//! HTTP endpoint handlers for auction requests.
use edgezero_core::body::Body as EdgeBody;
use error_stack::{Report, ResultExt};
use http::{Request, Response};
use crate::auction::formats::AdRequest;
use crate::consent;
use crate::cookies::handle_request_cookies;
use crate::error::TrustedServerError;
use crate::platform::RuntimeServices;
use crate::settings::Settings;
use crate::synthetic::get_or_generate_synthetic_id;
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,
services: &RuntimeServices,
req: Request<EdgeBody>,
) -> Result<Response<EdgeBody>, Report<TrustedServerError>> {
let (parts, body) = req.into_parts();
// Parse request body
let body: AdRequest =
serde_json::from_slice(&body.into_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()
);
let http_req = Request::from_parts(parts, EdgeBody::empty());
// Generate synthetic ID early so the consent pipeline can use it for
// KV Store fallback/write operations.
let synthetic_id = get_or_generate_synthetic_id(settings, services, &http_req).change_context(
TrustedServerError::Auction {
message: "Failed to generate synthetic ID".to_string(),
},
)?;
// Extract consent from request cookies, headers, and geo.
let cookie_jar = handle_request_cookies(&http_req)?;
let geo = services
.geo()
.lookup(services.client_info.client_ip)
.unwrap_or_else(|e| {
log::warn!("geo lookup failed: {e}");
None
});
let consent_context = consent::build_consent_context(&consent::ConsentPipelineInput {
jar: cookie_jar.as_ref(),
req: &http_req,
config: &settings.consent,
geo: geo.as_ref(),
synthetic_id: Some(synthetic_id.as_str()),
});
// Convert tsjs request format to auction request
let auction_request = convert_tsjs_to_auction_request(
&body,
settings,
services,
&http_req,
consent_context,
&synthetic_id,
geo,
)?;
// Create auction context
let context = AuctionContext {
settings,
request: &http_req,
client_info: services.client_info(),
timeout_ms: settings.auction.timeout_ms,
provider_responses: None,
services,
};
// Run the auction
let result = orchestrator
.run_auction(&auction_request, &context, services)
.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)
}