Files

Webdav

The webdav service, like the frontend service, provides a HTTP API following the webdav protocol. It receives HTTP calls from requestors like clients and issues gRPC calls to other services executing these requests. After the called service has finished the request, the webdav service will render their responses in xml and sends them back to the requestor.

Endpoints Overview

Currently, the webdav service handles request for two functionalities, which are Thumbnails and Search.

Thumbnails

The webdav service provides various GET endpoints to get the thumbnails of a file in authenticated and unauthenticated contexts. It also provides thumbnails for spaces on different endpoints.

Generated thumbnails are cached by the webdav service itself. The cache backend defaults to file, storing entries under $OC_BASE_DATA_PATH/thumbnails/cache (override with WEBDAV_THUMBNAILS_CACHE_BACKEND and WEBDAV_THUMBNAILS_CACHE_DIR). Use the s3 backend when running multiple instances behind a load balancer so they share one cache. A backend nobody can serve, an unknown name or an s3 backend without bucket, region and credentials, fails at startup instead of serving without a cache, as long as previews are enabled. A service that is not AWS needs WEBDAV_THUMBNAILS_CACHE_S3_ENDPOINT too, and it is always addressed over https. The memory backend is bounded and drops its oldest entries; none disables caching on purpose.

Thumbnail Query String Parameters

Clients can request thumbnail previews for files by adding ?preview=1 to the file URL. Requests for files with no thumbnail available respond with HTTP status 404.

The following query parameters are supported:

Parameter Required Default Value Description
preview YES 1 generates preview
x NO 32, when y is absent too horizontal target size, absent leaves the width unconstrained, 0 is an error
y NO 32, when x is absent too vertical target size, absent leaves the height unconstrained, 0 is an error
scalingup NO 0 accepted for compatibility but ignored; not forwarded to the generator
a NO none accepted for compatibility but ignored; this service has never honored it, so the chain below decides
c NO none accepted for compatibility but ignored; the cache key holds the file's checksum, so a changed file gets a new thumbnail without it
processor NO none, the chain below decides preferred thumbnail processor

Thumbnail Resolution

WEBDAV_THUMBNAILS_RESOLUTIONS is a ladder of edge lengths, not a list of boxes. Its largest entry is also the largest thumbnail this service asks a generator for, which is why it tops out at 2048: fill and stretch enlarge a small source to fill the box, so a higher rung lets a tiny image cost whatever that box costs. Each axis of a request is rounded up to the next length on the ladder, on its own, so a thumbnail never comes back in a different orientation than it was asked for. The largest length is the cap: a request above it, and an axis left unconstrained, get that one.

Example with the default ladder (16, 32, 64, 128, 192, 256, 320, 384, 448, 512, 640, 768, 1024, 1280, 1920, 2048):

Requested: 18x12
Returned: 32x16

Entries written as WidthxHeight are still accepted and contribute both of their sides to the ladder, each capped at 2048, the largest box the built-in generator accepts by default. A configuration written for the old box list, which reached 7680x4320, keeps working that way. A larger length has to be a plain one, with the generator's THUMBNAILS_MAX_OUTPUT_WIDTH and THUMBNAILS_MAX_OUTPUT_HEIGHT raised to match.

Rounding onto the ladder is also what the cache is keyed on, so requests that produce the same image share one entry.

The response is therefore not exactly the requested box: rounding up makes it larger, and an aspect-preserving operation makes it smaller on one axis. A client has to scale what it gets instead of trusting its own numbers.

Thumbnail Processors

Normally, an image might get cropped when creating a preview, depending on the aspect ratio of the original image. This can have negative impacts on previews as only a part of the image will be shown. When using an optional processor in the request, cropping can be avoided by defining on how the preview image generation will be done. The following processors are available:

  • resize resizes the image to the specified width and height and returns the transformed image (distorts to the exact box).
  • fit-in scales the image down to fit within the specified maximum width and height, preserving aspect ratio and never upscaling. The result is smaller than the box on one axis, it is not padded to it.
  • fill: creates an image with the specified dimensions and fills it with the scaled source image. To achieve the correct aspect ratio without stretching, the source image will be cropped.

The following are legacy aliases kept for compatibility:

  • thumbnail is a legacy alias for fill (center-crop to the exact box, may upscale).
  • fit is a legacy alias for fit-in.

Naming one of them decides the behavior on its own, legacy alias or imagor name. A name nobody knows is treated like no processor at all.

To apply one of those, a query parameter has to be added to the request, like ?processor=fit-in.

Without a processor two things decide, in this order. An unconstrained axis is always fitted, because there is no box to crop to, so ?y=512 needs nothing else. Otherwise the source type decides, resize for gifs and fill for everything else.

Thumbnail Generator

The thumbnails themselves are made by a generator the webdav service POSTs to, configured with WEBDAV_THUMBNAILS_GENERATOR_URL (and WEBDAV_THUMBNAILS_GENERATOR_TIMEOUT). The built-in thumbnails service speaks the imagor image endpoint, so a real imagor can be put in its place without changing anything else. A source the generator cannot read answers 404, one that is too large 403, and WEBDAV_THUMBNAILS_MAX_INPUT_IMAGE_FILE_SIZE caps what is sent at all; OC_THUMBNAILS_MAX_INPUT_IMAGE_FILE_SIZE sets this and the generator's own cap together, so one does not send what the other refuses. A generator that refuses because it is busy answers 429 with its own Retry-After, so a client can come back instead of treating it as a missing preview. The same cap bounds an image webdav extracts itself, the cover of an audio file or the thumbnail inside a geogebra container, because a compressed entry says nothing about its size until it is read. A cropping resize asks the generator for a smart crop, so what survives is the region that carries the image; a generator without libvips answers the same request with a centre crop.

Three settings say what is made of what. Each one is merged onto the built-in defaults, which is what their ADDITIONAL says: naming one type does not take the answer away from the others, and an entry for a type the defaults already answer for replaces that one entry. The first takes bare mime types, the other two take key:value entries:

Environment variable Description
OC_THUMBNAILS_ADDITIONAL_SOURCE_TYPES Types a preview is announced and attempted for, e.g. image/vnd.microsoft.icon for a generator that reads icons. The webdav, graph and ocdav side all read this one name
OC_THUMBNAILS_ADDITIONAL_OUTPUT_TYPES The type a thumbnail is returned in, per source type, as mime:mime entries, e.g. image/vnd.microsoft.icon:image/png
OC_THUMBNAILS_ADDITIONAL_GENERATOR_FORMATS The formats the generator writes, as mime:format entries, e.g. image/webp:webp. The format is the name its own format(...) filter uses

Reading them as a chain: a source type is mapped to the type its thumbnail is returned in, and that type is asked for by the name the generator knows it under. An icon becomes image/png, which the generator is asked for as format(png). A type nobody mapped becomes a JPEG, and so does a mapping onto a type this service has no format name for: what a generator behind the URL really writes is its own business, and a wrong guess here must not keep the service from starting.

The defaults return image/png for png and icon sources, keep image/gif for a gif and return image/jpeg for everything else, so a client must read the response's Content-Type instead of assuming the type it got before.

Previews can be switched off entirely with OC_DISABLE_PREVIEWS. Search keeps working, every thumbnail path answers 404, and nothing here is read or checked: a typo in the resolutions, the cache backend or the type mapping surfaces when previews are switched back on, not before.

In the single binary nothing has to be set: the generator URL defaults to the built-in thumbnails service. A deployment that runs the services in separate containers has to point WEBDAV_THUMBNAILS_GENERATOR_URL at its thumbnails service or at an imagor, because 127.0.0.1 does not reach it from there. MIGRATION.md says what else an existing deployment has to change.

The webdav service provides access to the search functionality. It offers multiple REPORT endpoints for getting search results.

See the search service for more details about search functionality.

Scalability

The webdav service persists generated thumbnails to its thumbnail cache (file backend by default). When running multiple instances behind a load balancer, point WEBDAV_THUMBNAILS_CACHE_BACKEND at a shared s3 bucket so all instances read and write the same cache; otherwise each instance keeps its own on-disk cache.