autoconnect_web/
routes.rs

1use actix_web::{web, HttpRequest, HttpResponse};
2use uuid::Uuid;
3
4use autoconnect_settings::AppState;
5use autopush_common::notification::Notification;
6
7use crate::error::ApiError;
8
9/// Handle WebSocket WebPush clients
10pub async fn ws_route(
11    req: HttpRequest,
12    body: web::Payload,
13    app_state: web::Data<AppState>,
14) -> Result<HttpResponse, ApiError> {
15    Ok(autoconnect_ws::ws_handler(req, body, app_state).await?)
16}
17
18/// Deliver a Push notification directly to a connected client
19#[allow(unused_mut)]
20pub async fn push_route(
21    uaid: web::Path<Uuid>,
22    mut notif: web::Json<Notification>,
23    app_state: web::Data<AppState>,
24) -> HttpResponse {
25    trace!(
26        "⏩ in push_route, uaid: {} channel_id: {}",
27        uaid,
28        notif.channel_id,
29    );
30    #[cfg(feature = "reliable_report")]
31    {
32        notif
33            .record_reliability(
34                &app_state.reliability,
35                autopush_common::reliability::ReliabilityState::IntAccepted,
36            )
37            .await;
38        notif
39            .record_reliability(
40                &app_state.reliability,
41                autopush_common::reliability::ReliabilityState::Transmitted,
42            )
43            .await;
44    }
45    // Attempt to send the notification to the UA using WebSocket protocol, or store on failure.
46    // NOTE: Since this clones the notification, there is a potential to
47    // double count the reliability state.
48    #[cfg(feature = "reliable_report")]
49    let lnotif = notif.clone_without_reliability_state();
50    #[cfg(not(feature = "reliable_report"))]
51    let lnotif = notif.clone();
52    let result = app_state.clients.notify(uaid.into_inner(), lnotif).await;
53    if result.is_ok() {
54        #[cfg(feature = "reliable_report")]
55        notif
56            .record_reliability(
57                &app_state.reliability,
58                autopush_common::reliability::ReliabilityState::Accepted,
59            )
60            .await;
61        HttpResponse::Ok().finish()
62    } else {
63        #[cfg(feature = "reliable_report")]
64        notif
65            .record_reliability(
66                &app_state.reliability,
67                autopush_common::reliability::ReliabilityState::Errored,
68            )
69            .await;
70        HttpResponse::NotFound().body("Client not available")
71    }
72}
73
74/// Notify a connected client to check storage for new notifications
75pub async fn check_storage_route(
76    uaid: web::Path<Uuid>,
77    app_state: web::Data<AppState>,
78) -> HttpResponse {
79    trace!("⏩ check_storage_route, uaid: {}", uaid);
80    let result = app_state.clients.check_storage(uaid.into_inner()).await;
81    if result.is_ok() {
82        HttpResponse::Ok().finish()
83    } else {
84        HttpResponse::NotFound().body("Client not available")
85    }
86}