flaresolverr life cycle

This commit is contained in:
Simon
2026-04-05 20:55:15 +00:00
parent 7b464fe796
commit bc2a73dd06

View File

@@ -1,10 +1,11 @@
use std::{collections::HashMap, env};
use serde_json::json;
use serde_json::Value;
use wreq::{Client, Proxy};
use wreq_util::Emulation;
#[derive(serde::Serialize, serde::Deserialize, Debug)]
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct FlareSolverrRequest {
pub cmd: String,
pub url: String,
@@ -64,20 +65,16 @@ impl Flaresolverr {
self.proxy = proxy;
}
pub async fn solve(
async fn post_payload(
&self,
request: FlareSolverrRequest,
) -> Result<FlareSolverrResponse, Box<dyn std::error::Error>> {
payload: Value,
) -> Result<Value, Box<dyn std::error::Error + Send + Sync>> {
let client = Client::builder().emulation(Emulation::Firefox136).build()?;
let mut req = client
.post(&self.url)
.header("Content-Type", "application/json")
.json(&json!({
"cmd": request.cmd,
"url": request.url,
"maxTimeout": request.maxTimeout,
}));
.json(&payload);
if self.proxy {
if let Ok(proxy_url) = env::var("BURP_URL") {
@@ -93,8 +90,72 @@ impl Flaresolverr {
}
let response = req.send().await?;
let body = response.json::<FlareSolverrResponse>().await?;
let body = response.json::<Value>().await?;
if body
.get("status")
.and_then(Value::as_str)
.is_some_and(|status| status.eq_ignore_ascii_case("error"))
{
let message = body
.get("message")
.and_then(Value::as_str)
.unwrap_or("FlareSolverr returned status=error");
return Err(message.to_string().into());
}
Ok(body)
}
async fn create_session(&self) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
let body = self.post_payload(json!({ "cmd": "sessions.create" })).await?;
let session = body
.get("session")
.and_then(Value::as_str)
.ok_or("sessions.create response missing `session`")?;
Ok(session.to_string())
}
async fn destroy_session(
&self,
session: &str,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let _ = self
.post_payload(json!({
"cmd": "sessions.destroy",
"session": session,
}))
.await?;
Ok(())
}
async fn solve_with_session(
&self,
request: FlareSolverrRequest,
session: &str,
) -> Result<FlareSolverrResponse, Box<dyn std::error::Error + Send + Sync>> {
let body = self
.post_payload(json!({
"cmd": request.cmd,
"url": request.url,
"maxTimeout": request.maxTimeout,
"session": session,
}))
.await?;
let typed = serde_json::from_value::<FlareSolverrResponse>(body)?;
Ok(typed)
}
pub async fn solve(
&self,
request: FlareSolverrRequest,
) -> Result<FlareSolverrResponse, Box<dyn std::error::Error + Send + Sync>> {
let session = self.create_session().await?;
let result = self.solve_with_session(request, &session).await;
if let Err(error) = self.destroy_session(&session).await {
eprintln!(
"FlareSolverr session cleanup failed for session '{}': {}",
session, error
);
}
result
}
}