Skip to content

overview

Alexander Herling edited this page Oct 12, 2026 · 10 revisions

Plugin overview

Almost everything provider-specific in rDownloader is a plugin: a signed WebAssembly component that runs in a sandbox and reaches exactly what its manifest declares. Seventy-two ship with the release, covering eleven of the twelve plugin types (the transfer type has only an example).

Plugins are .rdplug packages: a manifest, a WebAssembly component, optional translations, and an Ed25519 signature. The contract is the versioned WIT interface rdownloader:plugin@0.11.0, manifest version 3. A package built against another contract version is refused, stays listed in the plugin manager with the reason, and has to be rebuilt.

When a release raises the contract version, the bundled plugins come rebuilt with higher versions and install over the old ones. Queued and paused downloads need nothing from you: they resolve again through the current version of the same plugin, and remote jobs carry on. The one exception is a download in progress on a transfer-backend plugin: it fails with plugin.pinned_version_missing and has to be started again. No transfer backend is bundled.

Why plugins rather than compiled-in code

  • A hoster's protocol changes on its own schedule. A plugin can be replaced without a new release of the application.
  • A provider exists exactly while its plugin does. The provider list follows installing, removing and switching off plugins at once.
  • Third parties can publish resolvers for new hosters without touching the core repository. Provider metadata and translations travel in the package.
  • One service, format or destination per plugin, so each can be updated, versioned and switched off on its own.

The twelve types

Type What it does Bundled
Resolver Turns a hoster page address into a downloadable link 27
Folder crawler Turns one address that stands for many files into those files 12
OAuth provider Authorization-code with PKCE, or device code, with automatic renewal 7
Auth provider Signs an account in through the provider itself, instead of pasting an API key 5
Notification destination Delivers one message to a service 3
Post-processing step Contributes one more step to the pipeline 3
Intake parser Turns a file format or text the built-in scanner does not understand into LinkGrabber candidates 2
Metadata enricher Adds fields to a link that has just resolved 2
Stream transform Resolves an address whose bytes the application itself has to decrypt 1
Remote job Runs work at a provider that outlives the call that started it 6
Transfer backend Carries a protocol's bytes on the shared queue none (reference in the repository)
Upload destination Sends a finished package to a remote store 1

See Bundled plugins for the full list.

Capabilities

A manifest declares the plugin type, the ABI version it speaks, and every grant it asks for — web requests with their domain allowlist, account cookies, captcha solving, and the credentials it may expand.

A plugin that was not granted a capability cannot even load the interface for it, so the permission is enforced before the plugin runs. The file system and other processes have no interface at all — there is nothing to ask for.

A component that imports anything outside rdownloader:plugin — above all a wasi: interface pulled in by a dependency — is refused when it is packaged and again when it is installed.

The plugin manager shows the type, ABI version and granted permissions of every installed package before you install it.

The sandbox

Wasmtime, with:

  • no WASI access,
  • domain allowlists from the manifest,
  • cookie and secret boundaries — a plugin sees a marker, never a credential,
  • memory limits,
  • a fuel budget,
  • a timeout,
  • a maximum response size.

Credentials never reach a plugin

Across every type: the plugin writes a marker, and the application substitutes the one secret that call was granted, only towards the hosts that credential belongs to. A marker written without a grant is refused rather than sent empty. A resolver's API key, an auth provider's token, a notifier's token — none of them is visible to the plugin.

The same holds for an HTTP Basic header (Seedr, Pixeldrain) and for sign-ins that need values derived from a password (MEGA): the application builds or computes them and hands the plugin only the result.

What a plugin writes against is in the Plugin reference.

What each type may and may not do

Resolvers

Match a URL, check an account, resolve a link, check a link's availability, report a multihoster's hoster catalogue.

A link check answers online, offline or unknown — or cached: the provider holds the file in its own cache right now, which can end without notice. The LinkGrabber shows when that was measured. Among the resolvers, Premiumize answers it; a remote-job plugin can answer it too.

A provider can declare more than one credential mode, each with its own hosts — an API key is never sent to a login form, and a password never to an API host — or that it takes no account at all, like the generic XFileSharing resolver.

Transfer backends

Carry a protocol's bytes on the shared queue, under the same speed limit.

A transfer plugin never sees a path. It writes into the download's own staging file, and the application verifies the length before moving the finished file into place. A resume checkpoint is readable only by the plugin version that wrote it.

Intake parsers

Asked whether they claim an input before being shown it, so a parser for one format does not see every paste.

What they return are proposals: the same review, blocklist and routing rules apply as to a pasted link. A parser cannot queue anything, and a rewrite that changes the host or the scheme is discarded.

A failing parser costs only its own feature; intake keeps working.

Auth providers

The interface shows an address and a code, and the service polls until it is confirmed.

A sign-in address must be on a domain the plugin's own manifest declares, and it is shown rather than opened, so a plugin cannot send you to a phishing page.

Closing the browser or restarting the service mid-sign-in loses nothing.

OAuth providers

Two ways in — a browser redirect (authorization code with PKCE) and a device code — and automatic renewal a minute before the token expires. A sign-in answer can be used only once.

  • A provider that refuses ends the sign-in.
  • A provider that cannot be reached does not — the token is kept and tried again later.
  • "Not confirmed yet" and "slow down" are waiting, not failure.
  • A provider no installed plugin claims fails at once.

Folder crawlers

Walk the folder under the plugin's own limits on depth, breadth and cycles, and hand back names, sizes and the folder each file sat in — which becomes the package suggestion. An empty, missing or unreachable folder reports a stated reason rather than producing an empty package.

Remote jobs

A magnet, a .torrent, an .nzb or an ordinary link handed to a provider account answers with an identifier, not a file. The job runs for minutes or hours, may stop half-way until somebody picks which files they want, and stays in the account afterwards.

Such a job survives a restart of the service, even with the machine switched off in between: the application keeps the entry, the remote identifier and your selection. The same content is never submitted twice — for BitTorrent the info hash identifies it — so a second attempt finds the job already running.

Ending a job is two separate actions: delete it at the provider, which cannot be undone, or remove it from the list here, which touches nothing in your account.

A remote-job plugin can also answer the cache question before anything is handed over: whether its provider holds a magnet, a stored .torrent, an NZB or a hoster link ready right now. The LinkGrabber asks one account per provider before the online check. The question only reads — nothing is created at the provider — and it can raise a link to cached, never turn one offline. TorBox answers for torrents, Usenet and web downloads, Premiumize's transfers plugin for magnets.

Stream transforms

A few providers encrypt every file on the client: the key rides in the link's fragment, and a plain download returns ciphertext.

A stream-transform plugin answers with the address and a description of the transform — a named cipher and integrity check with their parameters. The application does the decryption:

  • The plugin describes, the application computes. A cipher the application does not know is a refusal, never a fallback.
  • Decryption happens while writing, so there is no second pass and no second copy on disk.
  • The key is a secret from the moment it arrives. It goes into the vault and is never logged or displayed.
  • The provider's integrity value is checked before the file is put in place. A mismatch — a wrong key, say — fails the attempt and keeps the partial file.

A resume whose transform differs starts over. A download whose connection boundaries do not line up with the provider's falls back to a single connection — slower, never wrong.

Metadata enrichers

Add and never replace. An enricher cannot rewrite a file name, a size or a provider.

Off by default, because an enricher reaches a service outside this machine. Only links a plugin claims are sent at all.

What an enricher adds shows as chips under the package or link name in the download list and the LinkGrabber, labelled in your language (a field the interface does not know keeps its own name). Show metadata in either toolbar hides them without deleting anything.

Notification destinations

Deliver one message and report the outcome. Retries, backoff and quiet hours are the application's, the same for every destination.

A target naming a plugin that is not installed is refused when it is saved, not when an event arrives.

Post-processing steps

Run after cleanup and before a user script, switched on globally or per category — installing one changes nothing until somebody enables it. The list is ordered, so steps run in the order they were switched on. A category's empty list means "none here" and switches a globally enabled step off.

A step is given the list of files it may read; it cannot name a path. Stopping mid-step stores a checkpoint, so a restart resumes. "Nothing to do" is reported as skipped, not as a failure. A step may rename the package's files; a new name carrying a separator or a .., or one already taken, is refused.

Upload destinations

The post-processing upload target may be plugin:<plugin-id>/<destination>. Everything after the first slash belongs to the plugin's own vocabulary.

Commit before delete: under move, the local copy is removed only after the destination has confirmed, in a call of its own, that it holds each uploaded file.

A storage plugin may reach any host, because a server's address is not knowable in advance, but each upload only the host of its own destination. It is the only plugin type allowed the HTTP methods that write. Credentials come from the stored remote logins of the FTP, SFTP and WebDAV transfers, matched on host and port; the plugin gets the user name, never the password.

Versions

Installing a plugin never removes the older one. New jobs run the plugin's active version — the newest installed one, unless you activated, rolled back to or put another version under test in the plugin manager; a changed choice takes effect at the next start. See Versions: running, under test, previous.

Downloads pinned to a resolver version that is no longer installed resolve through the current version of the same plugin. A download pinned to a withdrawn version says so and waits for you to resume it.

A transfer plugin's download is bound to its version before the first byte, so a newer version installed meanwhile never continues a file an older one began. Partial data without that binding is discarded and the file starts anew, as does a bound file with no data yet whose version is no longer installed.

Related pages

Clone this wiki locally