diff --git a/README.md b/README.md new file mode 100644 index 0000000..e208364 --- /dev/null +++ b/README.md @@ -0,0 +1,192 @@ +# epub2pdf — Document → PDF Converter + +> A small, self-hosted web app that turns 27 document formats — EPUB3 ebooks, Office +> documents, TeX/LaTeX, Org, AsciiDoc, RST, Markdown, HTML, plain text, CSV/TSV, JSON, XML, +> SVG, images, and existing PDFs — into PDFs. **No file ever leaves your machine.** + +Built for people who want a private, on-premise conversion pipeline: run it behind a firewall, +on your own server, with no data egress and no account required. + +--- + +## Contents + +- [What it does](#what-it-does) +- [Features](#features) +- [How it works](#how-it-works) +- [Security](#security) +- [Quick start](#quick-start) + - [Docker (recommended)](#docker-recommended) + - [Local (no Docker)](#local-no-docker) + - [Coolify](#coolify) +- [Command line](#command-line) +- [Live sites](#live-sites) +- [Documentation](#documentation) +- [Source repository](#source-repository) +- [Attribution](#attribution) + +--- + +## What it does + +doc2pdf takes a single uploaded file and produces a single PDF. It is **self-hosted**: +you run the container on your own hardware, so nothing you upload is processed anywhere else. + +The web UI accepts a drop-and-go upload; an HTTP API and a CLI let you automate it. Every +format is detected from the file's real bytes (magic-byte detection), not its extension. + +For a complete format-by-format breakdown, the web UI tour, troubleshooting tables, and the +full settings reference, read the [USER_GUIDE.md](USER_GUIDE.md). It is the primary, +detailed documentation — this README is only the front door. + +--- + +## Features + +- **27 input formats → PDF.** EPUB3, HTML/HTML5, Markdown, Office (`.docx`, `.odt`, `.rtf`), + TeX/LaTeX, Org, AsciiDoc, reStructuredText, plain text, CSV/TSV, JSON, XML, SVG, images + (PNG/JPEG/WebP/TIFF/BMP), and existing PDF. +- **No file ever leaves your machine.** There is no data egress — uploads and generated PDFs + stay on the host that runs the app. +- **Self-hosted and private.** No account, no login, no telemetry. Deploy behind your firewall. +- **CJK support.** Ships with Noto CJK fonts so Chinese, Japanese, and Korean render correctly. +- **RTL support.** Right-to-left books render correctly for Arabic and Hebrew. +- **Faithful Office rendering.** The Office trio renders with **Rich** mode (default) through + LibreOffice — preserving fonts, page size, and colors — or falls back to **Standard** mode + through pandoc. +- **Fast and concurrency-safe.** A single gunicorn worker with 8 threads provides 4 + concurrent conversion slots. Uploads cap at 400 MB, output caps at 200 MB. +- **Tested.** 27 formats supported with 152/152 tests green. + +--- + +## How it works + +A browser upload becomes a server-side job that flows through a small, well-defined pipeline: + +```mermaid +flowchart TD + Browser[Browser — upload a file] --> API[/api/convert/] + API --> Queue[Job queue: 1 worker · 4 slots] + Queue --> Family{File family?} + Family -->|EPUB, HTML, Markdown, JSON, XML, SVG, images, text| W[WeasyPrint renderer] + Family --> Office[".docx · .odt · .rtf"] + Office --> Mode{Render mode?} + Mode -->|Rich (default)| LO[LibreOffice headless] + Mode -->|Standard| PC[Pandoc] + W --> Guards[Security guards] + LO --> Guards + PC --> Guards + Guards --> Finalize[finalize PDF tail] + Finalize --> Download[Download PDF] +``` + +Every path — whether EPUB/HTML/Markdown renders through WeasyPrint, or the Office trio renders +through LibreOffice or pandoc — passes through the same security guards before the final PDF is +written. See the [security section](#security) for details. + +--- + +## Security + +This release ships with every previously identified finding fixed. The pipeline applies these +guards before writing output: + +- **Decompression-bomb guard.** Uploads stream through a byte-counted extractor that aborts + mid-stream if extraction exceeds its budget. +- **SSRF / data-egress blocking.** Remote resources are validated before rendering, and remote + schemes (http, https, ftp, ws, wss, file) are blocked — local `data:` resources still render. +- **Stored-XSS stripping.** `