22 Commits
Author SHA1 Message Date
germondai 613b41ad23 refactor(api): split index.ts into config, deps, routes, and add root status route 2026-07-09 10:40:36 +02:00
Erik Dasque 7d3204351c fix(tiers): recognize more block/error page variants, add Tier 4 captcha parity, surface proxy/timing info
Found while running trawl against a large batch of real-world URLs: several
cases where the API returned 200 with content that was actually a blocked
page, an empty challenge stub, or Firefox's own error page. Each was a
detection gap where a tier didn't recognize the failure and reported it as a
successful scrape.

- Recognize Firefox's about:neterror/about:certerror page (browser never
  reached a server), Cloudflare's static "you have been blocked" WAF-deny
  page, and a lean CF challenge stub (blank title/body, just the bootstrap
  script) — the stub check is gated on page size since the same script
  snippet also appears on ordinary, fully-loaded CF pages as bot-management
  telemetry.
- Wire the existing isBlocked() status-code check (403/429/202) into Tiers 2
  and 3 — previously only Tier 1 checked status code, so a generic non-CF WAF
  deny that escalated to a browser tier was reported as a success.
- Bring Tier 4 up to parity with Tier 3: captcha solving and the same block
  detection. Sites that need Tier 4 for IP reputation can just as easily have
  an in-page captcha widget.
- Add proxyUsed: boolean to the response, set from the actual proxy used by
  the winning tier — previously the only signal was inferring from tier === 4,
  which doesn't distinguish "no proxy" from Tier 3's datacenter proxy.
- Attach the per-tier timings array to thrown errors via a new ScrapeError,
  and return it in /scrape's error response. The array was already being
  built in memory; it just never survived the throw, so failed requests gave
  a flat error string with no way to see which tier failed or why.
- Add process-level uncaughtException/unhandledRejection handlers. One target
  site's page threw a JS error that Camoufox/Firefox reports in a shape
  playwright-core's dispatcher doesn't expect, which crashed the entire
  process and dropped every in-flight request across all clients.
- Update the native API docs for the new response fields and error shape.

All additive — no existing fields changed shape. Full existing test suite
passes (58/58), and this is rebuilt/smoke-tested against latest dev.
2026-07-07 15:58:54 +00:00
germondai da8f9261e1 feat(api): add BROWSER_CONTENT_PROCESSES env var 2026-07-06 20:09:30 +02:00
GermondandGitHub 47fc0fa647 Merge pull request #14 from CoolDotty/codex/fix-browser-process-leak
Recycle browser pool after temporary contexts
2026-07-06 19:41:42 +02:00
germondai e8129735b0 fix(api): normalize proxy field at /v1 boundary for Prowlarr input 2026-07-06 13:56:09 +02:00
CoolDotty 68ad2e0f1a Recycle browsers after temporary contexts 2026-07-06 00:47:32 -07:00
germondai da8008d200 feat(api): forward per-request proxy override to scrape handler 2026-07-06 02:29:51 +02:00
GermondandGitHub 8d69e660c3 Merge branch 'main' into fix/pr-8-hardening 2026-07-06 01:33:13 +02:00
germondai d8e0745662 feat(api): validate methods and sanitise headers at the boundary 2026-07-06 01:12:11 +02:00
germondai e05d9afee3 refactor(api): rename PORT_API env var to PORT 2026-07-05 18:06:02 +02:00
germondai 8d78a1a6e1 feat(api): configure proxy pools from env and forward overrides 2026-07-05 16:40:42 +02:00
whoshoe 5fde497e3a feat: add post method with postData parameter 2026-07-03 22:28:42 +08:00
germondai bddd70cfca fix(api): return 503 from /health while browser pool is initializing 2026-07-01 12:36:06 +02:00
germondai efaf0c96a0 feat(browser): make acquire timeout configurable, default 15s 2026-06-29 23:59:05 +02:00
germondai 6cfa87c9a5 chore(api): bump default browser pool size to 3 2026-06-29 23:12:51 +02:00
germondai 9cd79fe01e style: biome lint, format, and check pass 2026-06-29 23:10:28 +02:00
germondai 182d3dc1eb fix(api): surface browser pool exhaustion as 429 not 500 2026-06-29 22:35:01 +02:00
germondai a42b3a11af feat(api): add concurrency limiter to prevent oom under burst load 2026-06-29 22:11:50 +02:00
germondai df79859ebe chore(api): drop @elysiajs/cors, restrict api to non-browser clients 2026-06-29 20:39:52 +02:00
germondai 5c84b33808 feat(api): add CORS support and expose custom headers on /v1 and /scrape 2026-06-26 22:05:41 +02:00
germondai 77bd63c724 feat(api): make cmd optional on /v1, defaulting to request.get 2026-06-26 21:34:12 +02:00
germondai 38ff319aa1 feat: implement Hono-based API request handler 2026-06-08 08:55:00 +02:00