- Go 98.6%
- Dockerfile 1.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| animated.go | ||
| cache.go | ||
| config.go | ||
| Dockerfile | ||
| fetcher.go | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| media.go | ||
| params.go | ||
| processor.go | ||
| README.md | ||
| urls.go | ||
| video.go | ||
fuzzyprocessor
Small Go image proxy using libvips for image transforms and ffmpeg for video thumbnails.
Routes
/proxy?url=https%3A%2F%2Fexample.com%2Fimage.png&w=768&q=70&format=webp
/proxy?url=https%3A%2F%2Fexample.com%2Fanimation.gif&w=768&q=70&format=webp&animated=true
/proxy?url=https://cdn.sanity.io/images/example.gif?w=1200&q=70&fit=max&auto=format?w=600&q=60&format=webp
/proxy?url=https%3A%2F%2Fexample.com%2Fvideo.mp4
/proxy?url=https%3A%2F%2Fexample.com%2Fimage.png
/attachments/ID/ID/FILE.PNG?w=768&q=70&format=webp
/thumbnails?url=https%3A%2F%2Fexample.com%2Fvideo.mp4&w=768&q=70&format=webp
/thumbnails/attachments/ID/ID/VIDEO.MP4?w=768&q=70&format=webp
Remote proxy and thumbnail sources use the url query parameter and must be HTTPS. The fetcher rejects private, loopback, link-local, multicast, and unspecified IP addresses after DNS resolution.
Remote proxying without transform parameters streams the original file straight through (Range requests included) for both images and videos. Anything the origin does not report as image/* or video/*, and whose URL has no known image or video extension, is rejected. Transformed output still requires at least w or h.
Animation is preserved by default with animated=true for both animated GIF and animated WebP sources; use animated=false to flatten to a normal still image output. Animated output requires format=webp or format=gif. Note that fit=cover currently flattens animated sources to a single frame.
If the remote URL has its own query params, URL-encoding it is safest. Unencoded remote URLs are also supported when fuzzyprocessor params are appended after a second ?, such as ...&auto=format?w=600&q=60.
Local CDN image paths and local CDN thumbnail paths are matched with LOCAL_CDN_PREFIXES and joined onto CDN_BASE_URL.
Config
Copy .env.example to .env and edit as needed.
LISTEN_ADDR=:8080
CDN_BASE_URL=https://spc-cdn.fursystems.org
LOCAL_CDN_PREFIXES=/attachments/,/team-icons/,/stickers/,/splashes/,/role-icons/,/icons/,/guild-profiles/,/emojis/,/embed/,/discovery-splashes/,/discover-splashes,/channel-icons/,/banners/,/avatars/,/avatar-decoration-presets/,/app-icons/,/app-assets/,/guilds/
CACHE_DIR=cache
CACHE_VERSION=v1
DEFAULT_QUALITY=80
DEFAULT_FORMAT=webp
DEFAULT_FIT=inside
MAX_DIMENSION=4096
MAX_IMAGE_BYTES=52428800proxy passthrough without transform params is only for video files
MAX_VIDEO_BYTES=26214400
FETCH_TIMEOUT_SECONDS=20
FFMPEG_PATH=ffmpeg
VIPS_PATH=vips
Runtime Dependencies
Required dependencies are libvips, ffmpeg, openslide, imagemagick
To just run fuzzyprocessor:
go run .
To build
go build .