lmjtfy.git / apps / lmjtfy / src / events.rs

What happened on the site, kept: the Worker makes an archive::Event of every request worth keeping and hands it to the archive, which writes it as a row of events. The event itself, and what it reads from a request, is packages/archive/src/event.rs; here is only what needs the Worker: Cloudflare's account of where the request came from, and the sending.

7pub use ::archive::event::{Event, Origin};
8use worker::{Env, HttpRequest};

The request as an event, before it is known what came of it.

11pub fn of(request: &HttpRequest) -> Event {
12    let headers = request.headers();
13    let ip = headers.get("cf-connecting-ip").and_then(|value| value.to_str().ok()).unwrap_or_default().to_owned();
14    let origin = match request.extensions().get::<worker::Cf>() {
15        Some(cf) => {
16            let coordinates = cf.coordinates();
17            Origin {
18                ip,
19                country: cf.country().unwrap_or_default(),
20                region: cf.region().unwrap_or_default(),
21                region_code: cf.region_code().unwrap_or_default(),
22                continent: cf.continent().unwrap_or_default(),
23                metro: cf.metro_code().unwrap_or_default(),
24                bot: cf.verified_bot_category().unwrap_or_default(),
25                city: cf.city().unwrap_or_default(),
26                postcode: cf.postal_code().unwrap_or_default(),
27                timezone: cf.timezone_name(),
28                latitude: coordinates.map(|(latitude, _)| f64::from(latitude)),
29                longitude: coordinates.map(|(_, longitude)| f64::from(longitude)),
30                asn: cf.asn(),
31                network: cf.as_organization().unwrap_or_default(),
32                colo: cf.colo(),
33                protocol: cf.http_protocol(),
34                tls: cf.tls_version(),
35            }
36        }
37        None => Origin { ip, ..Origin::default() },
38    };
39    Event::from(request.method(), request.uri(), headers, crate::browser(headers), origin)
40}

Keeps the event. A failure loses that one row and nothing else.

43pub async fn record(env: &Env, event: Event) {
44    crate::archive::event(env, event).await;
45}

A name for how an ask ended.

48pub fn ending(ending: Option<&crate::view::Ending>) -> &'static str {
49    use crate::view::Ending;
50    match ending {
51        None => "",
52        Some(Ending::Empty) => "empty",
53        Some(Ending::NotAQuestion { .. }) => "refused",
54        Some(Ending::Answered) => "answered",
55        Some(Ending::Slow) => "slow",
56        Some(Ending::NoQuestion) => "no-question",
57        Some(Ending::Failed { .. }) => "failed",
58        Some(Ending::Offline) => "offline",
59        Some(Ending::Spent { .. }) => "spent",
60        Some(Ending::NotKept { .. }) => "not-kept",
61    }
62}