Files
http2pic/CLAUDE.md
Chris 7360d0b08a
All checks were successful
Build Container / docker (push) Successful in 4m13s
feat: add fullpage and maxheight parameters for enhanced screenshot options
2026-04-24 15:43:08 +02:00

3.1 KiB
Raw Permalink Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project

http2pic - PHP website renderer that takes screenshots of URLs and returns them as images. Live at https://http2pic.haschek.at/

Architecture

Entry point: web/index.php - PSR-4 router with two paths:

  • /api - Chrome/Chromium screenshot via Selenium WebDriver (php-webdriver). Params: url, viewport (WIDTHxHEIGHT), js (true/false), fullpage (true/false), maxheight (130000, default 15000). Connects to localhost:4444 ChromeDriver, sets window size, takes screenshot as PNG. In fullpage mode, resizes window to full scrollHeight (capped at maxheight) instead of hiding overflow.
  • default - renders src/templates/index.html.php (landing page).

Legacy class: src/http2pic.class.php - Old wkhtmltoimage-based renderer (deprecated, not used in production). Supports PNG/JPG, viewport, resize, URL reachability check, file caching.

Helpers: src/helpers.php - renderTemplate(), addToLog(), getUserIP().

Config: src/config.inc.php - set at build time by start.sh from URL env var.

Running

Docker (production):

docker compose up -d

Services: Caddy (:80), PHP-FPM, ChromeDriver (:4444). Volumes: ./cache and ./logs. Configured via URL env var.

Dev container: .devcontainer/ - same stack, run ./devcontainer/start.sh. Forward port 8080.

Quick test:

php -S localhost:8080 -t web/
# Then visit http://localhost:8080/api?url=<target>

Key files

File Purpose
web/index.php API + template router
src/http2pic.class.php Legacy wkhtmltoimage renderer
src/helpers.php Template render, logging, IP helper
src/config.inc.php Runtime config (URL, API_KEY, BLOCK_PRIVATE_IPS)
docker/Caddyfile Reverse proxy, PHP-FPM, file server
docker/start.sh Boots PHP-FPM, ChromeDriver, writes config
docker-compose.yml Production compose

API Key

Set API_KEY env var in docker-compose to require authentication on all /api requests. Leave unset (default) for open access.

# via header (preferred — not logged in access logs)
curl -H "X-API-Key: your-secret-key" "http://host/api?url=https://example.com"

# via query param
curl "http://host/api?key=your-secret-key&url=https://example.com"

SSRF Protection

Set BLOCK_PRIVATE_IPS=true to reject requests to LAN, loopback, and cloud metadata IPs. Recommended when hosting publicly. Default is off (allows local/LAN addresses).

Note: DNS rebinding attacks can bypass this protection (attacker-controlled DNS can return a public IP during validation and a private IP when Chrome actually connects). Full protection requires a network-level egress firewall.

Caveats

  • web/index.php has a var_dump($cmd) debug statement left in http2pic.class.php:181 - remove before shipping.
  • Legacy http2pic.class.php has a variable scoping bug: line 109 uses $url instead of $this->params['url'].
  • Cache dir permissions must be 777 (set by start.sh).
  • ChromeDriver must be running on localhost:4444 for the API to work.