ImagePipe.Source behaviour (image_pipe v0.1.0)

Copy Markdown View Source

Behaviour for source adapters, and the shape of the :sources option of ImagePipe.config/1.

Configuring sources

:sources is a keyword list of sources. Each has a name, an adapter, the image paths it serves, and the adapter's options:

sources: [
  media: [
    adapter: ImagePipe.Source.File,
    match: [prefix: "media"],
    options: [root: "/srv/images", root_id: "media"]
  ],
  web: [
    adapter: ImagePipe.Source.HTTP,
    match: [scheme: ["http", "https"]],
    options: [allowed_hosts: ["assets.example.com"]]
  ]
]

Building a configuration with an invalid source raises ArgumentError. The source's name appears in telemetry events as :source_name.

Adapters

An adapter's callbacks receive its own validated options and a set of runtime limits, never the rest of the configuration. Writing one is covered in Writing a custom source.

Errors

An adapter fails a request by returning {:error, {:source, reason}}. Each reason below gives the listed status, as it does for the built-in adapters:

  • :not_found - 404.
  • {:bad_status, code} - the origin's HTTP status. 401, 403, 404, and 410 give 404. Any other status gives 502.
  • :body_too_large - 413.
  • :receive_timeout - 504.
  • :unreadable and :credentials_unavailable - 500.

Any other reason gives 502. To choose the status, lead the reason with a class: {:source, {class, detail}}, where class is :bad_request (400), :not_found (404), :payload_too_large (413), :unsupported_media (415), :server_error (500), :not_implemented (501), :bad_gateway (502), or :gateway_timeout (504). The detail never reaches the response body. Error responses lists every status.

Summary

Callbacks

Fetches the original's bytes as an ImagePipe.Source.Response, with exactly one of stream or path. A stream is subject to the :max_body_bytes limit.

Receives the options returned by validate_options/1 and returns the identifier structs resolve/3 accepts with them, from ImagePipe.Plan.Source.Path, ImagePipe.Plan.Source.URL, and ImagePipe.Plan.Source.Object. A source whose match rules would route another identifier to the adapter fails configuration.

Describes an image without fetching it.

Checks the source's :options when the configuration is built. The options it returns are passed to resolve/3 and fetch/3. An error fails the configuration with ArgumentError.

Types

error()

@type error() :: {:source, atom() | tuple()}

Callbacks

fetch(t, keyword, keyword)

@callback fetch(ImagePipe.Source.Resolved.t(), keyword(), keyword()) ::
  {:ok, ImagePipe.Source.Response.t()}
  | {:not_modified, ImagePipe.Source.Origin.t()}
  | {:error, error()}

Fetches the original's bytes as an ImagePipe.Source.Response, with exactly one of stream or path. A stream is subject to the :max_body_bytes limit.

The third argument holds runtime limits: :max_body_bytes, the transport timeouts, and the telemetry prefix. {:not_modified, origin} answers a revalidation of origin headers the adapter returned before.

identifiers(options)

@callback identifiers(options :: keyword()) :: [module()]

Receives the options returned by validate_options/1 and returns the identifier structs resolve/3 accepts with them, from ImagePipe.Plan.Source.Path, ImagePipe.Plan.Source.URL, and ImagePipe.Plan.Source.Object. A source whose match rules would route another identifier to the adapter fails configuration.

resolve(t, keyword, keyword)

@callback resolve(ImagePipe.Plan.Source.t(), keyword(), keyword()) ::
  {:ok, ImagePipe.Source.Resolved.t()} | {:error, error()}

Describes an image without fetching it.

The first argument is the requested image as one of the structs from identifiers/1, with the source's matching prefix or custom scheme removed. The returned ImagePipe.Source.Resolved holds:

  • identity - a keyword list that names the original, with atom keys and strings, numbers, booleans, nil, non-module atoms, or lists of them as values. It must include everything that selects different bytes, or two originals share cache entries.
  • internal_cache, http_cache, and cache_semantics - built with ImagePipe.Source.CacheSettings.fields/2.
  • fetch - any data fetch/3 needs.

The third argument holds runtime limits. Return {:error, {:source, reason}} for a source the adapter can't serve. The status each reason gives is listed under errors. Any other return value fails the request with 500.

validate_options(keyword)

@callback validate_options(keyword()) :: {:ok, keyword()} | {:error, term()}

Checks the source's :options when the configuration is built. The options it returns are passed to resolve/3 and fetch/3. An error fails the configuration with ArgumentError.