[Proposal / discussion] Optional libvips backend for webp_transform
维护者通常 2 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 25/100
- Issue 类型
- 功能
- 描述清晰度
- 需要澄清
- 活跃度
- 活跃
- 技术栈
- cmake, cpp
- 领域
- backend, build-system
调研方向
Start with ImageTransform.cc and the proposed CMake builds, then review the libvips and ImageMagick backend trade-offs described in the issue. Done means reaching a decision on whether to pursue libvips, which plugin form to use, and how to handle licensing, RSS behavior, and the experimental/magick relationship.
由索引模型根据 Issue 内容生成。
描述
This is a proposal for discussion, not a request to merge. It summarizes an evaluation of libvips as an alternative to ImageMagick for webp_transform, including trade-offs that argue against switching. Input from the community is wanted on whether to pursue it and in what form.
Motivation: attack surface
webp_transform decodes untrusted origin bodies on ET_NET threads. The case for libvips is security, not speed.
Advisory history, counted on the same basis for both libraries:
| source | ImageMagick | libvips |
|---|---|---|
| NVD keyword match | about 860 | about 29 (many assigned by VulDB in 2026) |
| GitHub security advisories | the 100 most recent span 2026-05-30 to 2026-09-27 | 12 in total, since 2023 |
ImageMagick:
- Several recent advisories appear, from their descriptions, to be reachable through plain JPEG/PNG/WebP reads that a security policy cannot block. This has not been verified against the plugin's code path.
- XMP profile parsing: DoS, infinite loop, use-after-free, over-read
- JPEG decoder information disclosure
- 8BIM use-after-free (identify path)
Image::read()sniffs the format itself, so a coder allowlist depends on a correctpolicy.xml.
libvips:
- In a build with only jpeg/png/webp/exif enabled, one of the 12 GitHub advisories is reachable: an EXIF NULL dereference, fixed in 8.18.2.
- The rest are in tiff, heif, svg, pdf, gif, radiance, ppm-source, the vips native format, and conversion ops the plugin doesn't call.
- The plugin already knows the format from its signature check, so it can call
vips_jpegload_buffer/vips_pngload_buffer/vips_webpload_bufferdirectly. libvips never sniffs. vips_operation_block_set()can block every other loader as defence in depth.- New third-party parsers come with it: libexif (24 NVD entries, 4 in 2026; optional, though disabling it drops EXIF passthrough), lcms2 (needed only for CMYK JPEGs) and GLib.
Not a motivation: speed or output size
- Throughput and CPU are a tie. libjpeg and libwebp do the work in both.
- At matched quality, standalone per-image latency is within about ±10% across image classes (measured against ImageMagick 7.1.0-1).
- Inside traffic_server with 16 clients, throughput is the same: 88–100 rps for ImageMagick 7.1.2-32 vs 92 rps for libvips, on 8 vCPU.
- Output size at equal quality matches within 1–4%.
Memory: better per image, worse per process (open risk)
Peak memory per transcode is 28–48% lower with libvips. ImageMagick 7 (Q16 HDRI) holds pixels as floats.
| image | ImageMagick | libvips |
|---|---|---|
| 1920x1277 JPEG -> WebP | 55 MB | 29 MB |
Inside traffic_server, process RSS is worse with libvips (jemalloc linked, default settings, 8 ET_NET threads, sustained transform load):
| setup | mean RSS |
|---|---|
| ImageMagick | 411 MB |
| libvips | 631 MB |
libvips + jemalloc narenas:8 |
344 MB |
ImageMagick + jemalloc narenas:8 |
351 MB |
- Cause: libvips does pixel work on its own worker threads. jemalloc's default of 4 arenas per CPU then keeps freed memory in many arenas. Allocator tuning closes the gap, but that is a process-wide setting.
- Unknown: behaviour on hosts with many more cores.
- Hazard: capping libvips' thread pool (
VIPS_MAX_THREADS=8) hung traffic_server under load. The cause wasn't confirmed (no thread dump was taken). The plugin wouldn't set it, but it is a sharp edge.
Licensing
- libvips and GLib are LGPL-2.1+, Category X under ASF policy.
- A libvips backend can only be an optional, separately installed dependency, never bundled: "the component is only needed for optional features" (https://www.apache.org/legal/resolved.html).
webp_transformis already built only when its image library is found.
What a prototype looks like
- Interface: a small
Transcoderinterface (init(),transcode()) with ImageMagick and libvips implementations.ImageTransform.cckeeps all HTTP logic. - Builds: CMake builds
webp_transform.so(ImageMagick) and/orwebp_transform_vips.so(libvips >= 8.13 via pkg-config). - libvips settings:
vips_concurrency_set(1)vips_cache_set_max(0)vips_block_untrusted_set(TRUE)- all loaders blocked except the three buffer loaders
- sequential access with
fail_on=error - dimensions checked from the header before any pixels are decoded
- Behaviour matches the ImageMagick backend on the edge cases tested:
- oversized, truncated and mislabeled bodies pass through
- CMYK converts with lcms2 (colours differ slightly for CMYK files without an embedded profile)
- EXIF orientation is preserved
- Differences to account for:
- Error log strings differ.
webp_transform_decode_limitmatchesImageMagick.. error. - libvips writes an EXIF block, so its JPEGs have no JFIF APP0 marker.
webp_transform_invalid_inputchecks forJFIF. - Output quality must be explicit, because libvips has no source-quality estimate. This fits the quality proposal in #13772.
- Error log strings differ.
Related: experimental/magick
plugins/experimental/magick runs ImageMagick command lines (MagickCommandGenesis), which can't be ported to libvips. A libvips webp_transform would not remove ImageMagick from builds that enable experimental plugins.
Questions for discussion
- Is reduced attack surface worth an LGPL optional dependency (libvips + GLib) and a second backend to maintain?
- If yes, should libvips be an alternative build of the same plugin, a separate plugin, or eventually the only backend?
- Can we accept the RSS behaviour under default jemalloc settings, or would we need guidance or tuning? Data from larger hosts would help.
- Should
experimental/magickstay as is, independent of this?
Method
- Host: 8 vCPU (Ice Lake), EL9, gcc 11.
- Libraries: ImageMagick 7.1.2-32 (Q16 HDRI, OpenMP, open policy; standalone latency also on 7.1.0-1); libvips 8.18.7 (meson, jpeg/png/webp/exif/lcms2 only).
- Codecs: libwebp 1.2.0, libpng 1.6.37, libjpeg-turbo 2.0.90.
- Corpus:
- 36 web JPEGs (500–1920 px)
- 24 Kodak PNGs
- 8 RGBA logos
- 28 WebP
- edge cases
- Test: traffic_server
master(RelWithDebInfo, jemalloc 5.2.1), cache off for load runs, 16 clients for 60 s, RSS sampled every second. - Harness and full data available on request.
- 主要语言
- C++
- 星标
- 2k
- 派生
- 881
- 平均合并
- 3 天 15 小时
- 30 天内合并 PR
- 94
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
apache/trafficserver 的其他 Issue
-
VIA_SERVER_RESULT and VIA_PROXY_RESULT are never set in handle_no_cache_operation_on_forward_server_response() for 206 Partial Content and the default branch (9.2.x)可能已有人在做 @shivampwm2020 于 4 天前认领。 未关闭Bug HTTP Support
难度 2/5 1-3 小时 新手友好度 74/100
apache/trafficserver#13118 ·
维护者通常 2 天内回复
-
Branch build clones: mirror stalls, clone timeout and controller memory可能已有人在做 @bryancall 于 6 天前认领。 未关闭CI
apache/trafficserver#13839 · 已指派 1 人 ·
维护者通常 2 天内回复
-
traffic_ctl: apply --error-level to config reload results可能已有人在做 @brbzull0 于 7 天前认领。 未关闭traffic_ctl
apache/trafficserver#13832 · 已指派 1 人 ·
维护者通常 2 天内回复
-
header_rewrite: rm-destination after set-destination URL crashes traffic_server可能已有人在做 @moonchen 于 15 天前认领。 未关闭Bug Crash header_rewrite Plugins
apache/trafficserver#13800 · 已指派 1 人 ·
维护者通常 2 天内回复
-
ssl_multicert: entries without dest_ip can override the default certificate可能已有人在做 @toxicteddy00077 于 1 天前认领。 未关闭Configuration SSL
难度 4/5 3-5 天 新手友好度 48/100
apache/trafficserver#13798 · 2 条评论 · 已指派 1 人 ·
维护者通常 2 天内回复
查看 apache/trafficserver 的全部 Issue
相似的 Issue
-
(S1 - Need confirmation)
难度 2/5 1-3 小时 新手友好度 65/100
CleverRaven/Cataclysm-DDA#89194 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
moonshine-ai/moonshine#231 ·
-
bug
难度 2/5 1-3 小时 新手友好度 74/100
维护者通常 1 天内回复
-
documentation good first issue M7: multi-node no hardware needed
难度 1/5 1 小时以内 新手友好度 95/100
GageLawton/noise-cancellation#299 ·
维护者通常 1 天内回复