relay_server/endpoints/
nel.rs1use axum::extract::DefaultBodyLimit;
4use axum::http::StatusCode;
5use axum::response::IntoResponse;
6use axum::routing::{MethodRouter, post};
7use relay_config::ConfigSnapshot;
8
9use crate::endpoints::common;
10use crate::extractors::{IntegrationBuilder, Mime};
11use crate::integrations::LogsIntegration;
12use crate::service::ServiceState;
13
14fn is_nel_mime(mime: Mime) -> bool {
15 let ty = mime.type_().as_str();
16 let subty = mime.subtype().as_str();
17 let suffix = mime.suffix().map(|suffix| suffix.as_str());
18
19 matches!(
20 (ty, subty, suffix),
21 ("application", "json", None) | ("application", "reports", Some("json"))
22 )
23}
24
25async fn handle(
27 state: ServiceState,
28 mime: Mime,
29 builder: IntegrationBuilder,
30) -> axum::response::Result<impl IntoResponse> {
31 if !is_nel_mime(mime) {
32 return Ok(StatusCode::UNSUPPORTED_MEDIA_TYPE);
33 }
34
35 let envelope = builder.with_type(LogsIntegration::Nel).build();
36
37 common::handle_envelope(&state, envelope)
38 .await?
39 .ignore_rate_limits();
40
41 Ok(StatusCode::OK)
42}
43
44pub fn route(config: &ConfigSnapshot) -> MethodRouter<ServiceState> {
45 post(handle).route_layer(DefaultBodyLimit::max(config.max_container_size()))
46}