# Changelog of Website Screenshot and PDF (`fecklesspleb/website-screenshot`) Actor

- **URL**: https://apify.com/fecklesspleb/website-screenshot/changelog.md
- **Full Actor documentation**: https://apify.com/fecklesspleb/website-screenshot.md

## Changelog

### Unreleased

- **Fixed (security): the private-address guard now rejects every address that is not globally routable** (`not ipaddress.is_global`), which adds carrier-grade NAT `100.64.0.0/10` (for example `100.64.0.1`, `100.127.255.254`) to the blocked ranges. The existing private, loopback, link-local, reserved, multicast and unspecified checks stay, and an IPv4-mapped IPv6 address (`::ffff:a.b.c.d`) is also checked as its IPv4 address. Applies on the Apify platform to the URL itself and to every request the page makes (subresources, redirects, frames), which are aborted. The reasons are unchanged: `private, loopback and link-local addresses are not allowed` and `DNS lookup failed for <host>`. Local runs still skip the check.
- Tests: blocked `100.64.0.1`, `100.127.255.254`, `192.0.0.1`, `198.18.0.1`, `0.0.0.0`, `::ffff:10.0.0.1`, `fc00::1`, `fe80::1` and allowed `93.184.216.34` (mocked DNS).
- **Changed: minimum memory is now 512 MB (was 256 MB).** Runs at 256 MB crashed on the Apify platform with "Page.goto: Page crashed" (Python, the browser driver and Chromium together use about 250-300 MB). The default stays 1024 MB.
- **Changed: pages captured at the same time are capped by memory as `max(1, (memory MB - 256) // 384)`**: 1 page up to 1023 MB, 2 at 1024 MB (the default, was 3), 3 at 1408 MB, 4 at 2048 MB, 10 at 4096 MB. Before: `max(1, (memory MB - 192) // 128)`, which allowed 2 pages at 512 MB and 6 at 1024 MB. `maxConcurrency` (default 3, max 10) still applies on top.
- Changed: Chromium is started with `--disable-gpu` and `--no-zygote` in addition to `--disable-dev-shm-usage` (saves about 5 MB; no change to the screenshots). The viewport defaults are unchanged.
- **Fixed: a host that does not resolve (for example `https://nonexistent.invalid/`) is reported as `DNS lookup failed for <host>`**, not as "private, loopback and link-local addresses are not allowed". The private-address reason is now only used when the host really resolves to such an address.
- Changed: when robots.txt cannot be fetched, the reason now names the cause: `DNS lookup failed for <host> (while fetching robots.txt)`, `connection to <host> timed out (while fetching robots.txt)` or `connection to <host> failed (<detail>) (while fetching robots.txt)`. Before: `the site could not be reached (<ExceptionName> on robots.txt)`. Such sites are still treated as disallowed and not charged.
- Changed: browser errors get plain reasons: `net::ERR_NAME_NOT_RESOLVED` becomes `DNS lookup failed for <host>`; refused, reset, closed or failed connections become `connection to <host> failed (<ERR_CODE>)`; timeouts become `connection to <host> timed out`; a crashed page becomes `the browser page crashed, usually because it ran out of memory; try a higher memory setting`. Other errors keep their first line (at most 200 characters), as before.
- Tests: offline tests for the DNS, connection and timeout reasons, the private-address check (mocked DNS) and the memory-to-concurrency formula.
