Repository navigation
transfer plugin
A transfer backend carries the bytes of a protocol rDownloader does not speak itself. Links with the URL schemes it declares are routed to it, and it runs on the same queue, under the same speed limit, with the same resume rules as the built-in HTTP, FTP and SFTP transfers. It moves bytes; where they land and whether the download counts as finished is the application's decision.
| Scaffold | rdownloader plugin new --type transfer |
plugin_type |
transfer |
| World | transfer-plugin |
| Exports |
probe, run
|
| Template | sdk/templates/transfer |
| Contract | Interface transfer |
-
You move bytes; the application decides where they land and whether they count. You never
see a path and never promote a file:
sinkwrites into this transfer's own part file, and the length is checked againstprobewithout you. -
sink.committed()is the truth about what reached the disk. Resume from it, not from your checkpoint: the checkpoint is your notes, and it may lag behind after a crash. - A connection is a number the host owns. Every socket is closed when the invocation ends, so a leaked handle costs nothing — but closing early frees a slot. Reads are paced by the transfer's bandwidth limit before the bytes reach you.
The scaffold asks for net_stream: raw TCP or TLS to the hosts and ports it lists. There is no
wildcard port — a backend free to reach any port on a host it named would be a port scanner with
a manifest. sink is granted by the type itself, and net_http may be added for a protocol that
needs a side channel over HTTPS.
A transfer backend carries a [transfer] section instead of a provider: its slug (the namespace
of its messages) and the schemes whose links it serves. A [provider] section is refused for
this type.
Ask for exactly what you use: the install preview shows every grant, and a component importing an interface its manifest does not grant cannot be instantiated. Every capability is listed under Capabilities.
Two rules to keep: check should-stop between reads, or the execution budget stops you without
a checkpoint; and report resumable: false when your protocol cannot continue a file, so the host
starts over instead of trusting a resume. The host records size and modification time on the first
attempt and refuses a continuation whose file changed.
plugin new reads its templates from sdk/templates, so run it from a checkout of the repository:
git clone https://github.com/degoya/rDownloader.git
cd rDownloader
rdownloader plugin new --type transfer --out ../myprotocol
cd ../myprotocolWithout an installation of rDownloader, the packaging tool rd-pack —
cargo build --profile release-test -p rd-pack in the checkout — takes the same arguments:
target/release-test/rd-pack plugin new --type transfer --out ../myprotocol.
The directory name becomes the crate name and the plugin's slug (--name sets another). The
scaffold gets its own plugin id, its own copy of the contract in wit/rdownloader.wit and its own
Ed25519 key pair: plugin-signing.key, whose public half is already in manifest.toml. Keep that
file out of version control.
-
src/lib.rsreads your addresses, your protocol's reply lines and the checkpoint. The scaffold speaks a deliberately small line protocol over TLS so that what you read is the contract; replace it with yours. -
src/guest.rsholdsprobe(size and modification time, asked before the first byte) andrun(connect, resume fromsink.committed(), write, stop on request). -
manifest.toml:[transfer] schemes,[capabilities.net_stream] hostsandports,max_concurrent_downloads. -
locales/en.json: the English text of every failure code you report.
Change description and author under [metadata], and read the comment at the top of
src/lib.rs: it states what the host promises this type.
cargo testThe unit tests need no WebAssembly toolchain: only src/guest.rs is wasm32-specific. Give every
answer of your provider you read a test of its own.
cargo build --release --target wasm32-unknown-unknown
wasm-tools component new target/wasm32-unknown-unknown/release/myprotocol.wasm -o target/myprotocol.wasmThis needs the wasm32-unknown-unknown target and wasm-tools 1.261.0, the version the bundled
plugins are made with: cargo build makes a core module that carries the world src/guest.rs
generates, and wasm-tools component new turns it into the component. The plugin is built
without WASI: a component importing anything outside rdownloader:plugin is refused — see
Building without WASI.
rdownloader plugin package --manifest manifest.toml \
--component target/myprotocol.wasm \
--locales locales --key plugin-signing.key --output myprotocol.rdplug
rdownloader plugin conformance myprotocol.rdplug --jsonconformance answers whether this application would run the package; it has to be clean before
you publish. For a key that outlives the scaffold, rdownloader plugin keygen --role plugin --output ./keys writes a pair: the Base64 in the .pub file goes into public_key, and key_id
gets a name of your own. In CI, RDOWNLOADER_PLUGIN_SIGNING_KEY holding the private key's PEM
text replaces --key. Details:
Packaging, signing and distribution.
For a first try without signing, package with --development instead of --key and start
rdownloader serve --plugin-development-mode, the only mode that accepts an unsigned package.
Install a signed package under Settings → Plugins → Add as an upload, or with
rdownloader plugin install myprotocol.rdplug --root data/plugins. Review before installing shows
every permission and the signing key; a key this installation has not seen asks to be trusted —
compare its fingerprint. The message after installing says whether the plugin runs at once or
after the next restart; see Installing and trust.
Queue a link with your scheme, for example through the LinkGrabber; the transfer shows in the download queue like any other. An upgrade of the backend takes effect the next time a job starts.
Publish the .rdplug together with your key's fingerprint, or — so that people get your new
versions in the Catalogue — in a plugin repository of your own: a signed index built with
rdownloader plugin index build and a repository-role key. A repository only delivers: every
package in it still needs your plugin key, approved by the person installing it. See
A repository index and
Running a plugin repository.
The SDK's reusable CI workflow,
sdk/ci/plugin.yml, builds,
checks the imports, packages and runs conformance on every push and pull request; it signs only
on a push to the default branch or a tag, so a pull request never sees the key.
- Transfer backends in the plugin reference — what the host does with each call, in full
-
Interface
transfer— every function and type, generated from the contract - Developing a plugin — the tools, translations, errors and what every type shares
-
The
transfertemplate on GitHub
Getting started
- Installation
- Building from source
- Translating rDownloader
- First run
- Your first download
- The interface
Using rDownloader
- The download queue
- Download history
- The LinkGrabber
- Site rules
- Hosters and accounts
- Usenet and NZB
- BitTorrent
- Video and audio downloads
- Image galleries
- Livestream recording
- FTP, SFTP and WebDAV
- Object storage
- Subscriptions
- Remote jobs
- Storage, categories and rules
- Watched folders
- Post-processing
- Bandwidth and power
- Notifications
- Automation
- Statistics
- Keyboard and accessibility
Integrations
- Browser extension
- Desktop capture agent
- Command line client
- REST API
- MCP server
- Automation tool compatibility
Operating
- Docker and NAS
- Synology NAS
- Reverse proxy
- Accounts, sessions and permissions
- Sign in with an identity provider
- External tools
- Backup and restore
- Updates
- Security and privacy
- Diagnostics and maintenance
- Troubleshooting
- Defaults and limits
- Support matrix
Plugins
Plugin development
- Developing a plugin
- Resolver
- Transfer backend
- Intake parser
- Intake parser with mirrors
- Folder crawler
- Remote job
- Sign-in
- OAuth sign-in
- Metadata enricher
- Notification destination
- Post-processing step
- Upload destination
- Stream transform
- Plugin reference
- Packaging, signing and distribution
- Running a plugin repository
Reference