mirror of
https://github.com/ThePhaseless/Byparr.git
synced 2026-09-24 14:20:08 +01:00
FlareSolverr hardcodes the solution status ("todo: fix, selenium not
provides this info"), so clients built against it never see anything else.
Byparr handed back the real navigation code on the branch without a
challenge and 200 on the branch with one, which is neither honest nor
compatible. Always report 200.
Move the challenge handling into src/challenge.py and the response bodies
into src/content.py, leaving endpoints.py with the routes and navigation.
That also confines the import of playwright_captcha's private detection
module to a single file, so a patch release can only break one import
instead of the app and the test module at once.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
43 lines
1.3 KiB
Python
43 lines
1.3 KiB
Python
import base64
|
|
|
|
from playwright.async_api import Page
|
|
|
|
from src.models import LinkRequest
|
|
from src.utils import logger
|
|
|
|
|
|
async def build_response_content(
|
|
page: Page,
|
|
request: LinkRequest,
|
|
page_request: object,
|
|
*,
|
|
challenge_detected: bool,
|
|
page_html: str | None,
|
|
) -> tuple[str, str]:
|
|
"""Build (content_type, response_content) from the settled page."""
|
|
if request.return_only_cookies:
|
|
return "text/html", ""
|
|
|
|
if page_request and page_request.headers.get("content-type", "").startswith(
|
|
"application/pdf"
|
|
):
|
|
return await fetch_pdf_content(page)
|
|
|
|
response_content = (
|
|
page_html
|
|
if page_html is not None and not challenge_detected
|
|
else await page.content()
|
|
)
|
|
return "text/html", response_content
|
|
|
|
|
|
async def fetch_pdf_content(page: Page) -> tuple[str, str]:
|
|
"""Fetch raw PDF bytes as base64, falling back to viewer HTML on failure."""
|
|
try:
|
|
fetch_response = await page.request.fetch(page.url)
|
|
response_content = base64.b64encode(await fetch_response.body()).decode("ascii")
|
|
except Exception:
|
|
logger.exception("Failed to fetch PDF bytes, falling back to viewer HTML")
|
|
return "text/html", await page.content()
|
|
return "application/pdf", response_content
|