production fix
This commit is contained in:
@@ -152,17 +152,12 @@ impl PimpbunnyProxy {
|
|||||||
/// (including 403 "access denied").
|
/// (including 403 "access denied").
|
||||||
///
|
///
|
||||||
/// The PHPSESSID cookie — acquired when we fetched the detail page — must be
|
/// The PHPSESSID cookie — acquired when we fetched the detail page — must be
|
||||||
/// forwarded; the server won't issue the 302 without it.
|
/// forwarded; the server won't issue the 302 without it. Uses the shared
|
||||||
async fn follow_302(url: &str, requester: &Requester) -> Option<String> {
|
/// Requester's Cloudflare-resilient client (Firefox emulation) rather than a bare
|
||||||
let client = wreq::Client::builder()
|
/// wreq::Client — an unfingerprinted client gets blocked by Cloudflare from
|
||||||
.redirect(wreq::redirect::Policy::none())
|
/// datacenter/production IPs even though it works from less-scrutinized networks.
|
||||||
.build()
|
async fn follow_302(url: &str, requester: &mut Requester) -> Option<String> {
|
||||||
.ok()?;
|
let resp = requester.get_no_redirect_raw(url).await.ok()?;
|
||||||
let mut req = client.get(url);
|
|
||||||
if let Some(cookie) = requester.cookie_header_for_url(url) {
|
|
||||||
req = req.header("Cookie", cookie);
|
|
||||||
}
|
|
||||||
let resp = req.send().await.ok()?;
|
|
||||||
if resp.status().as_u16() != 302 {
|
if resp.status().as_u16() != 302 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -188,7 +183,7 @@ impl PimpbunnyProxy {
|
|||||||
let Some(decoded) = Self::decode_encoded_url(encoded_url, &license_code) else {
|
let Some(decoded) = Self::decode_encoded_url(encoded_url, &license_code) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if let Some(location) = Self::follow_302(&decoded, requester).await {
|
if let Some(location) = Self::follow_302(&decoded, &mut *requester).await {
|
||||||
return Some(location);
|
return Some(location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,10 +197,10 @@ async fn proxy2redirect(
|
|||||||
) -> Result<impl web::Responder, web::Error> {
|
) -> Result<impl web::Responder, web::Error> {
|
||||||
let proxy = get_proxy(req.uri().to_string().split("/").collect::<Vec<&str>>()[2]).unwrap();
|
let proxy = get_proxy(req.uri().to_string().split("/").collect::<Vec<&str>>()[2]).unwrap();
|
||||||
let endpoint = req.match_info().query("endpoint").to_string();
|
let endpoint = req.match_info().query("endpoint").to_string();
|
||||||
let video_url = match proxy.get_video_url(endpoint, requester).await {
|
let video_url = proxy.get_video_url(endpoint, requester).await;
|
||||||
url if url != "" => url,
|
if video_url.is_empty() {
|
||||||
_ => "Error".to_string(),
|
return Ok(web::HttpResponse::BadGateway().finish());
|
||||||
};
|
}
|
||||||
Ok(web::HttpResponse::Found()
|
Ok(web::HttpResponse::Found()
|
||||||
.header("Location", video_url)
|
.header("Location", video_url)
|
||||||
.finish())
|
.finish())
|
||||||
|
|||||||
@@ -315,6 +315,54 @@ impl Requester {
|
|||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like [`get_raw`], but disables redirect-following so a 3xx response's
|
||||||
|
/// `Location` header can be inspected directly. Uses the same
|
||||||
|
/// Cloudflare-resilient client (Firefox emulation, shared cookie jar,
|
||||||
|
/// FlareSolverr-derived user agent) as every other request path — unlike
|
||||||
|
/// a bare `wreq::Client`, which Cloudflare is far more likely to flag,
|
||||||
|
/// especially from datacenter/production IPs.
|
||||||
|
pub async fn get_no_redirect_raw(&mut self, url: &str) -> Result<Response, wreq::Error> {
|
||||||
|
let cookie_preview = self
|
||||||
|
.cookie_header_for_url(url)
|
||||||
|
.map(|cookie| crate::util::flow_debug::preview(&cookie, 160))
|
||||||
|
.unwrap_or_else(|| "none".to_string());
|
||||||
|
#[cfg(not(feature = "debug"))]
|
||||||
|
let _ = &cookie_preview;
|
||||||
|
crate::flow_debug!(
|
||||||
|
"trace={} requester get_no_redirect_raw url={} cookies={} proxy={}",
|
||||||
|
self.debug_trace_id().unwrap_or("none"),
|
||||||
|
crate::util::flow_debug::preview(url, 120),
|
||||||
|
cookie_preview,
|
||||||
|
self.proxy
|
||||||
|
);
|
||||||
|
let mut builder = Client::builder()
|
||||||
|
.cert_verification(false)
|
||||||
|
.emulation(Emulation::Firefox136)
|
||||||
|
.cookie_provider(self.cookie_jar.clone())
|
||||||
|
.redirect(Policy::none());
|
||||||
|
if let Some(user_agent) = self.user_agent.as_deref() {
|
||||||
|
let mut headers = HeaderMap::new();
|
||||||
|
if let Ok(value) = HeaderValue::from_str(user_agent) {
|
||||||
|
headers.insert(USER_AGENT, value);
|
||||||
|
builder = builder.default_headers(headers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let client = builder.build().expect("Failed to create HTTP client");
|
||||||
|
|
||||||
|
let mut request = client.get(url).version(Version::HTTP_11);
|
||||||
|
|
||||||
|
if self.proxy {
|
||||||
|
if let Ok(proxy_url) = env::var("BURP_URL") {
|
||||||
|
let proxy = Proxy::all(&proxy_url).unwrap();
|
||||||
|
request = request.proxy(proxy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = request.send().await?;
|
||||||
|
self.store_response_cookies(url, &response);
|
||||||
|
Ok(response)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_raw_with_headers(
|
pub async fn get_raw_with_headers(
|
||||||
&mut self,
|
&mut self,
|
||||||
url: &str,
|
url: &str,
|
||||||
|
|||||||
Reference in New Issue
Block a user