photoprism/internal/server
Michael Mayer 083d437ec4 Server: Add zstd compression support #5550
Negotiates zstd alongside gzip via PHOTOPRISM_HTTP_COMPRESSION as a
comma-separated preference list (e.g. "zstd,gzip"); legacy "gzip",
"none", and the empty string keep behaving as before. Bypasses
Connection: Upgrade, predicate-excluded paths, HEAD (with Vary kept),
4xx/5xx, 206, 204, and 304. Weakens strong ETags on the encoding path
so caches don't reuse a compressed body for a different coding.
2026-05-03 10:10:33 +00:00
..
limiter Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
process Server: Move process handling and shutdown to separate package #4767 2025-02-04 19:05:26 +01:00
wellknown Backend: Refactor middleware naming and improve code comments #5235 2025-09-30 23:25:53 +02:00
api.go WebDAV: Improve redirect and read/write request method handling 2026-02-10 11:45:32 +01:00
api_docs.go Backend: Remove legacy Go build tags #5330 2025-11-22 09:24:28 +01:00
autotls.go HTTP: Refactor Unix socket support #2337 #3595 2023-08-14 10:43:05 +02:00
compress.go Server: Add zstd compression support #5550 2026-05-03 10:10:33 +00:00
compress_negotiate.go Server: Add zstd compression support #5550 2026-05-03 10:10:33 +00:00
compress_negotiate_test.go Server: Add zstd compression support #5550 2026-05-03 10:10:33 +00:00
compress_predicate.go Server: Add zstd compression support #5550 2026-05-03 10:10:33 +00:00
compress_predicate_test.go Server: Add zstd compression support #5550 2026-05-03 10:10:33 +00:00
extensions.go Config: Show error if originals and storage path seem identical #1642 2024-01-21 14:22:16 +01:00
fail.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
gzip_test.go Server: Add zstd compression support #5550 2026-05-03 10:10:33 +00:00
logger.go Security: Add http rate limiter and auto tls mode #98 2022-10-11 22:44:11 +02:00
README.md Server: Add zstd compression support #5550 2026-05-03 10:10:33 +00:00
recovery.go CI: Apply Go linter recommendations to "internal/server" package #5330 2025-11-22 13:09:32 +01:00
routes.go MCP: Add "DisableMCP" option to disable /api/v1/mcp #5024 #5536 2026-04-18 11:08:58 +02:00
routes_sharing.go API: Add missing Swagger annotations and update swagger.json 2025-10-30 11:00:16 +01:00
routes_static.go Server: Fix remaining gosec/revive issues in internal/server 2026-02-26 16:01:47 +01:00
routes_test.go PWA: Use scope-relative manifest URLs for iOS path-based installs 2026-03-01 23:33:44 +01:00
routes_webapp.go PWA: Use scope-relative manifest URLs for iOS path-based installs 2026-03-01 23:33:44 +01:00
routes_webdav.go Backend: Refactor middleware naming and improve code comments #5235 2025-09-30 23:25:53 +02:00
routes_wellknown.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
security.go WebDAV: Harden response headers for interoperability #5472 2026-03-04 15:23:10 +01:00
security_test.go WebDAV: Harden response headers for interoperability #5472 2026-03-04 15:23:10 +01:00
server.go Backend: Update copyright notices 2025-01-09 10:28:17 +01:00
server_test.go WebDAV: Improve redirect and read/write request method handling 2026-02-10 11:45:32 +01:00
start.go Server: Add zstd compression support #5550 2026-05-03 10:10:33 +00:00
start_test.go Server: Use canonical host for AutoTLS HTTP redirects 2026-03-07 14:31:03 +01:00
static.go WebDAV: Improve redirect and read/write request method handling 2026-02-10 11:45:32 +01:00
sw_fallback.go Config: Add StaticBuildFile() and StaticImgFile() functions #5274 2025-10-18 09:09:56 +02:00
sw_fallback.js PWA: Include minimal no-op service worker for tests #5274 2025-10-17 20:41:22 +02:00
sw_scope_cleanup_fallback.go Frontend: Namespace local storage to run multiple nodes on a domain #98 2026-02-08 18:35:05 +01:00
sw_scope_cleanup_fallback.js Frontend: Namespace local storage to run multiple nodes on a domain #98 2026-02-08 18:35:05 +01:00
webdav.go Server: Export WebDAV response helper for PROPFIND content type #5472 2026-03-04 16:03:33 +01:00
webdav_actions_test.go CI: Apply Go linter recommendations to "internal/server" package #5330 2025-11-22 13:09:32 +01:00
webdav_auth.go Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02:00
webdav_auth_session.go Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02:00
webdav_auth_test.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
webdav_path.go WebDAV: Harden response headers for interoperability #5472 2026-03-04 15:23:10 +01:00
webdav_path_test.go WebDAV: Harden response headers for interoperability #5472 2026-03-04 15:23:10 +01:00
webdav_propfind_test.go WebDAV: Harden response headers for interoperability #5472 2026-03-04 15:23:10 +01:00
webdav_response.go Server: Export WebDAV response helper for PROPFIND content type #5472 2026-03-04 16:03:33 +01:00
webdav_secure_test.go WebDAV: Improve redirect and read/write request method handling 2026-02-10 11:45:32 +01:00
webdav_write_test.go Proxy: Define /i/ as DefaultPathPrefix for shared-domain deployments 2026-02-24 01:15:23 +01:00
zstd_test.go Server: Add zstd compression support #5550 2026-05-03 10:10:33 +00:00

PhotoPrism — HTTP Server

Last Updated: March 4, 2026

Overview

internal/server wires Gin, middleware, and configuration into the PhotoPrism HTTP/HTTPS/WebDAV servers. It owns startup/shutdown orchestration, route registration, and helpers for recovery/logging. Subpackages (process, limits, etc.) are kept lightweight so CLI commands and workers can embed the same server behavior without duplicating boilerplate.

Constraints

  • Uses the configured config.Config to decide TLS, AutoTLS, Unix sockets, proxies, compression, and trusted headers.
  • Middleware must stay small and deterministic because it runs on every request; heavy logic belongs in handlers.
  • Panics are recovered by Recovery() which logs stack traces and returns 500.
  • Startup supports mutually exclusive endpoints: Unix socket, HTTPS with certs, AutoTLS (with redirect listener), or plain HTTP.

Goals

  • Provide a single entrypoint (Start) that configures listeners, middleware, and routes consistently.
  • Keep health/readiness endpoints lightweight and cache-safe.
  • Ensure redirect and TLS listeners include sensible header and idle limits.

Non-Goals

  • Managing Docker/Traefik lifecycle (handled by compose files).
  • Serving static files directly; templates are loaded via Gin and routed by routes_webapp.go.

Package Layout (Code Map)

  • start.go — main startup flow, listener selection (HTTP/HTTPS/AutoTLS/Unix socket), graceful shutdown.
  • routes_webapp.go — Web UI routes and shared method helpers (MethodsGetHead).
  • recovery.go — panic recovery middleware with stack trace logging.
  • logger.go — request logging middleware (enabled in debug mode).
  • security.go — security headers and trusted proxy/platform handling.
  • webdav_*.go & tests — WebDAV handlers and regression tests for overwrite, traversal, and metadata flags.
  • webdav_path.go — shared helper to classify built-in and path-proxied WebDAV routes.
  • process/ — light wrappers for server process metadata.
  • internal/api — registers REST endpoints consumed by registerRoutes.
  • internal/config — supplies HTTP/TLS/socket settings, compression, proxies, and base URI paths.
  • internal/server/process — exposes process ID for logging.
  • pkg/http/header — shared HTTP header constants used by health endpoints.

Configuration & Safety Notes

  • Compression: configured via PHOTOPRISM_HTTP_COMPRESSION / --http-compression as a comma-separated preference list. Supported tokens are zstd, gzip, and none (empty value also disables compression). The default ships as zstd,gzip so capable clients receive zstd while everyone else falls back to gzip; unknown tokens are ignored with a startup warning. See specs/platform/http-compression.md for the negotiation rules and exclusion list.
  • Trusted proxies/platform headers are read from config; keep the list tight.
  • If no trusted proxy ranges are configured (or the configured ranges are invalid), proxy trust is disabled and client IP resolution falls back to the TCP peer address.
  • HTTP hardening defaults:
    • ReadHeaderTimeout is configured via PHOTOPRISM_HTTP_HEADER_TIMEOUT / --http-header-timeout (default 15s).
    • MaxHeaderBytes is configured via PHOTOPRISM_HTTP_HEADER_BYTES / --http-header-bytes (default 1 MiB).
    • IdleTimeout is configured via PHOTOPRISM_HTTP_IDLE_TIMEOUT / --http-idle-timeout (default 180s).
    • Global ReadTimeout / WriteTimeout remain disabled to avoid breaking large transfers.
  • WebDAV response behavior:
    • Built-in security middleware skips browser-document headers (Content-Security-Policy, X-Frame-Options) on /originals and /import paths.
    • PROPFIND 207 Multi-Status responses normalize XML media type to application/xml; charset=utf-8.
  • AutoTLS: uses autocert and spins up a redirect listener; ensure ports 80/443 are reachable.
  • Unix sockets: optional force query removes stale sockets; permissions can be set via mode query.
  • Health endpoints (/livez, /health, /healthz, /readyz) return Cache-Control: no-store and Access-Control-Allow-Origin: *.

Testing

  • Lint & unit tests: golangci-lint run ./internal/server... and go test ./internal/server/...
  • WebDAV behaviors are covered by webdav_*_test.go; they rely on temp directories and in-memory routers, including PROPFIND 207 XML/header assertions and path classification checks.

Operational Tips

  • Prefer Start with context cancellation so graceful shutdown is triggered (server.Close()).
  • When adding routes, register them in registerRoutes and reuse MethodsGetHead for safe verbs.
  • Keep middleware light; log or enforce security at the edge (Traefik) when possible, but maintain server-side defaults for defense in depth.