Class: Oximg::Server::UrlBuilder
- Inherits:
-
Object
- Object
- Oximg::Server::UrlBuilder
- Defined in:
- lib/oximg/server/url_builder.rb
Overview
Builds URLs for the two routes an oximg server mounts. Nothing here talks to the server: a URL is pure arithmetic over the config, so a Rails view can emit thousands of them without leaving the process.
Validation mirrors the server's own bounds and fails closed on the
same inputs. That is not defence — the server validates regardless —
it is so a typo surfaces at the call site with a name, instead of as
a 400 in an tag nobody is watching.
Constant Summary collapse
- MAX_DIMENSION =
The server's cap on either axis (src/main.rs); 0 means "unconstrained" on the positional route only.
8192- FORMATS =
Tokens the positional route's @fmt suffix accepts. "jxl" is reserved by the server for a future encoder and answers 400, so it is not offered here.
%w[jpg jpeg png webp avif].freeze
- OPTION_FORMATS =
The options route additionally understands format=auto, which means "negotiate, else the source's own format".
(FORMATS + %w[auto]).freeze
- UNSAFE =
Everything outside RFC 3986's unreserved set gets percent-encoded. "/" stays literal so S3-style prefixes remain readable, and "@" so the format token survives; both are legal in a path segment, and the server signs the decoded form either way.
%r{[^A-Za-z0-9\-._~/@]}
Instance Method Summary collapse
-
#initialize(config) ⇒ UrlBuilder
constructor
A new instance of UrlBuilder.
-
#options(source, width: nil, height: nil, quality: nil, format: nil) ⇒ Object
The Cloudflare-Images-compatible options route,
{prefix}/width=750,quality=80/{file}. -
#resize(source, width: 0, height: 0, format: nil) ⇒ Object
The positional route:
/resize/{w}/{h}/{file}, where the source is fitted within the box and never enlarged.
Constructor Details
#initialize(config) ⇒ UrlBuilder
Returns a new instance of UrlBuilder.
33 34 35 |
# File 'lib/oximg/server/url_builder.rb', line 33 def initialize(config) @config = config end |
Instance Method Details
#options(source, width: nil, height: nil, quality: nil, format: nil) ⇒ Object
The Cloudflare-Images-compatible options route,
{prefix}/width=750,quality=80/{file}. Requires the server to
have OXIMG_OPTIONS_PREFIX set and the same prefix configured
here. Options are emitted in a fixed order: the signature covers
the list verbatim, so a stable order is also a stable cache key.
61 62 63 64 65 66 67 68 69 |
# File 'lib/oximg/server/url_builder.rb', line 61 def (source, width: nil, height: nil, quality: nil, format: nil) prefix = @config. unless prefix raise ConfigurationError, "options_prefix is not configured (set it to the server's OXIMG_OPTIONS_PREFIX)" end build("#{prefix}/#{option_list(width, height, quality, format)}/", source_path(source)) end |
#resize(source, width: 0, height: 0, format: nil) ⇒ Object
The positional route: /resize/{w}/{h}/{file}, where the source
is fitted within the box and never enlarged. A zero axis is
unconstrained — width: 750 alone is exactly what an
srcset w descriptor means.
builder.resize("photos/a.jpg", width: 750)
builder.resize("photos/a.jpg", width: 750, height: 500, format: :webp)
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/oximg/server/url_builder.rb', line 44 def resize(source, width: 0, height: 0, format: nil) w = dimension(width, "width") h = dimension(height, "height") if w.zero? && h.zero? raise ArgumentError, "at least one of width/height must be non-zero" end file = source_path(source) file = "#{file}@#{token(format, FORMATS, "format")}" unless format.nil? build("/resize/#{w}/#{h}/", file) end |