-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathendpoints.rs
More file actions
103 lines (91 loc) · 3.41 KB
/
endpoints.rs
File metadata and controls
103 lines (91 loc) · 3.41 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
//! HTTP endpoint handlers for auction requests.
use error_stack::{Report, ResultExt};
use fastly::{Request, Response};
use crate::auction::formats::AdRequest;
use crate::consent;
use crate::cookies::handle_request_cookies;
use crate::edge_cookie::get_or_generate_ec_id;
use crate::error::TrustedServerError;
use crate::geo::GeoInfo;
use crate::platform::RuntimeServices;
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,
runtime_services: &RuntimeServices,
mut req: Request,
) -> Result<Response, Report<TrustedServerError>> {
// 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()
);
// Generate EC ID early so the consent pipeline can use it for
// KV Store fallback/write operations.
let ec_id =
get_or_generate_ec_id(settings, &req).change_context(TrustedServerError::Auction {
message: "Failed to generate EC ID".to_string(),
})?;
// Extract consent from request cookies, headers, and geo.
let cookie_jar = handle_request_cookies(&req)?;
#[allow(deprecated)]
let geo = GeoInfo::from_request(&req);
let consent_context = consent::build_consent_context(&consent::ConsentPipelineInput {
jar: cookie_jar.as_ref(),
req: &req,
config: &settings.consent,
geo: geo.as_ref(),
ec_id: Some(ec_id.as_str()),
kv_store: settings
.consent
.consent_store
.as_deref()
.map(|_| runtime_services.kv_store()),
});
// 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, runtime_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)
}