Skip to main content

px_perimeterx/infrastructure/
handler.rs

1use crate::application::solve_px::SolvePx;
2use async_trait::async_trait;
3use px_detector::{Detected, Detector, RegexDetector};
4use px_errors::AppError;
5use px_harvester::Harvester;
6use px_pipeline::{ChallengeHandler, HandlerMetrics, HandlerOutcome, PageHtml};
7use std::sync::Arc;
8
9pub struct PerimeterxHandler {
10    detector: RegexDetector,
11    solver: SolvePx,
12}
13
14impl PerimeterxHandler {
15    pub fn new(harvester: Arc<dyn Harvester>) -> Self {
16        Self {
17            detector: RegexDetector::new(),
18            solver: SolvePx::new(harvester),
19        }
20    }
21}
22
23#[async_trait]
24impl ChallengeHandler for PerimeterxHandler {
25    fn name(&self) -> &'static str {
26        "perimeterx"
27    }
28
29    async fn detects(&self, page: &PageHtml) -> Result<bool, AppError> {
30        Ok(matches!(self.detector.detect(&page.html), Detected::Yes(_)))
31    }
32
33    async fn solve(&self, page: &PageHtml) -> Result<HandlerOutcome, AppError> {
34        let out = self.solver.execute(&page.url).await?;
35        let metrics = HandlerMetrics {
36            detect_us: 0,
37            solve_ms: out.solve_ms,
38            bytes_read: 0,
39        };
40        Ok(HandlerOutcome::solved_with_ua(
41            self.name(),
42            out.cookies,
43            Vec::new(),
44            metrics,
45            out.user_agent,
46        ))
47    }
48}