browser extension - degoya/rDownloader GitHub Wiki
A Manifest V3 extension for Chrome/Edge and Firefox, built from a shared codebase. It is the companion for NAS and Docker setups, where no desktop capture agent can be installed next to the browser.
It does two things the agent cannot: it intercepts regular browser downloads, and it is the way a widget captcha gets answered. Without the agent it also answers Click'n'Load and takes local files β NZBs, torrents and link containers β so an rDownloader on a NAS needs nothing else on the computer.
It carries the same version number as the service; the popup shows it.
From the stores: Chrome and Edge install it from the Chrome Web Store, Firefox from Firefox Add-ons. Updates arrive through the store. A store may list an older version for a while after a release, until its review is through; an older extension keeps working with a newer service.
Without the store, and your own build: the release's rdownloader-chrome.zip and
rdownloader-firefox.zip, or artifacts/browser-extensions/ after scripts/build-extension.sh,
hold the bundles. Unzip the Chrome one and load the folder in chrome://extensions with developer
mode on (Load unpacked). In Firefox, the manifest in about:debugging#/runtime/this-firefox loads an unsigned
build temporarily β it is gone after a restart, because release Firefox keeps only add-ons
Mozilla signed.
Pairing uses a capture token from Settings β Clients & API β Browser β the same kind the desktop agent uses; the pairing card offers the raw token. Enter it in the extension's options page along with the server address, press Test connection, then Save.
Which addresses need a permission. The manifest holds http://127.0.0.1:8710/* and
http://localhost:8710/* from the moment the extension is installed β and, for
Click'n'Load, http://127.0.0.1:9666/* and
http://localhost:9666/* β and nothing else. Every
other address β including a loopback one on a different port β is asked for when you press
Save, so you approve exactly the address you configured. An address the browser cannot parse,
such as an unbracketed ::1, is named as invalid rather than failing silently.
What Firefox shows at installation. The add-on declares what it sends: browsing activity, website activity and website content as required, authentication information as optional β asked for only when a site's cookies are to be handed over. All of it goes only to the rDownloader you configured; What the extension sends lists it.
Over plain HTTP the token is visible on the network. For a remote server, put a TLS reverse proxy in front.
Firefox 156 and Chrome 153, and nothing below. The manifests declare those floors, so an older browser refuses to install the extension rather than running something untested. How the extension is tested: Support matrix.
- Context menu β send a link, the current page, or selected text.
- Popup β send the current page, or every link from the clipboard; see and answer waiting widget captchas; hand a hoster session to an account that asked for it; allow the site you are on to hand its files over; read the version.
- Package name from the page title when you send the current page.
- Share a site's session for a single domain, so an authenticated page can be fetched.
- Hand a hoster session to a provider account that asked for it with Take over from browser.
- Answer a widget captcha on the hoster's own page.
- Intercept regular browser downloads.
- Hand over NZB, torrent, ZIP and link-container files from a site you allow, which only the browser could load.
- Answer Click'n'Load on a site you allow when no desktop agent runs; see Click'n'Load without the desktop agent.
- Send local files with Send file to rDownloaderβ¦; see Sending a local file.
Localised in German, English, French and Spanish. A browser notification and a badge report success or failure, and nothing it does fails silently.
Every hand-over is announced once, by the extension. The context menu, an intercepted download, a file and Click'n'Load each end in one notification; what you send from the popup is reported in the popup's own status line instead. rDownloader recognises these hand-overs, so neither an open rDownloader tab nor the desktop agent announces the same links a second time. The popup reports what really happened: how many links went to the LinkGrabber, that a page lists releases for you to choose in the LinkGrabber, or Sending failed with the reason β a failure never reads as success.
A reCAPTCHA, hCaptcha or Cloudflare Turnstile widget is bound to the hoster's domain and cannot be rendered inside rDownloader. Either a configured solver answers it, or you do β and the extension is how.
- Once paired, the extension asks rDownloader every 30 seconds whether a widget is waiting. A new one is announced with a notification and a badge, and listed in the popup. Once no captcha waits any more, the notification goes away.
- Answer on the hoster's page asks the browser for permission for that page's origin only and opens the hoster's own page in a new tab. The extension reads the widget's answer and changes nothing on the page.
- You solve the widget as you would on any site. The answer goes to rDownloader, the tab closes, and the permission is released.
- Closing the tab without answering declines the captcha, and the download fails immediately instead of waiting out its timeout. Decline in the popup does the same.
A page that shows no captcha ends the wait. A browser already signed in at the hoster is usually redirected past the login form, so there is nothing to answer. If no widget appears within 15 seconds, the sign-in stops with a message naming the hoster and the two ways out: take the session over with Take over from browser at the account, or sign out of the hoster in the browser and test the account again. The hoster's tab stays open, and closing it declines nothing.
The notification, not the closing tab, tells you the outcome: accepted, could not be handed over (with the reason), declined, rDownloader was not told that it was declined (with the reason), or no longer waiting.
The answer is never stored, never shown in a notification and never logged, in the extension or on the server.
The captcha prompt in the web interface shows whether an extension is connected. The desktop agent opens no window for these widgets β Turnstile refuses an embedded browser β so the extension is the only way to answer one by hand.
When you start a download in the browser, the extension can hand it to rDownloader instead:
- The browser download is paused first.
- It is only removed once the server has accepted it.
- A failed handoff resumes it in the browser β an unreachable server loses nothing.
Interception can be switched off globally, and any single download can be kept in the browser through the notification's action.
Downloads started by rDownloader itself, or from the server's own web interface, are never intercepted.
A service that does not answer is reported as unreachable; "too old" means a service that answered but does not know the extension's capture contract.
Credential-bearing headers never leave the browser with an intercepted download: cookies,
Authorization and comparable headers are dropped in the extension and again on the server. The
one hand-over that carries cookies is a file from a site you allowed,
and those are used for one fetch and kept nowhere. Only harmless headers are kept β at most 32 per
link, each capped at 4,096 characters.
The handoff carries the address, not the file: rDownloader fetches it again, without the browser's cookies or session. Some downloads only the browser can fetch, so unless you allow the site, the extension leaves them alone:
-
NZB, torrent and ZIP files and link containers are never intercepted, and nothing is said
about it. They are recognised by the type the browser reports (
application/x-nzb,application/x-bittorrent,application/zip,application/x-zip-compressed, and for containersapplication/dlc,application/x-dlc,application/x-ccf,application/x-rsdf) or by a.nzb,.torrent,.zip,.dlc,.ccf,.rsdf,.rdlinksor.crawljobending on the file name, the address or an observedContent-Disposition. Fetched again by rDownloader, a container would only be downloaded, not imported. A Newznab indexer's cart (NNTmux's/getnzb/β¦) answers only the signed-in session, and a one-time link is already spent by the time the extension hears of the download. -
A download the extension observed as a
POST(below).
Everything else is handed over.
To get those files into rDownloader anyway:
- Allow the site in the popup β the direct way.
- Point a watched folder at the browser's download folder. It picks up
.nzband.torrentfiles once the browser has finished them β.partand.crdownloadfiles are not candidates β and routes them like any other intake. A watched folder does not take.zip: unpack an indexer's ZIP into that folder, or upload the NZBs in the LinkGrabber. - For a Newznab indexer's cart, subscribe to the cart's RSS feed instead β a
subscription polls the feed itself, so the browser is not involved at
all. Add it as a subscription of kind Feed or podcast with the cart feed's address from the
indexer's RSS page; its entries carry the indexer's key (
r=β¦), so they download without a browser session. The key sits in the feed address in plain text, and log masking does not recogniser=.
For a site you allow, its NZB, torrent, ZIP and link-container downloads go to rDownloader after all β an indexer's cart, a one-time link, a download behind a session. The same consent lets the extension answer Click'n'Load on that site.
- Open the popup on that site and press Hand NZB, torrent and ZIP files from to
rDownloader. The browser asks for access to that one host and for
cookiesβ Firefox also for sharing authentication information. - From then on such a download from that site is taken by rDownloader. Take over browser downloads has to be on.
The same button in the popup β Keep files from in the browser again β takes the consent back, and the options page lists every allowed site under Sites that hand files over, each with Revoke. Without a consent nothing changes: the file stays in the browser, as above.
rDownloader takes the file in one of two ways, and never fetches it a second time:
- Firefox hands over the bytes it received. The extension copies the response as it arrives and holds it back from the browser until rDownloader has it. Taken, the browser's empty download is removed; refused, the browser receives every byte and finishes the download as usual.
-
The address with that host's cookies β in Chrome, and in Firefox when its copy breaks off.
The extension hands over the cookies the browser would send to the download's address, with the
address, the referrer and the user agent. rDownloader fetches the file once, sends the
cookies only to that address's own scheme, host and port β a redirect elsewhere goes without
them β and keeps them nowhere. The browser has usually fetched the file already, so an
indexer counts this as a second download.
The address, and every address a redirect leads to, may lie in your own network but never on
this machine; such a hand-over is refused with
capture.fetch_address_refused.
Known limit in Firefox: Firefox may drop the copy of a response it turns into a download (Mozilla bug 1787119). The address hand-over then takes its place.
rDownloader accepts an NZB, a .torrent, a ZIP of NZBs, as NNTmux's cart hands one
out β one import per NZB inside, and the whole ZIP refused if one NZB in it is broken β or a link
container (.dlc, .ccf, .rsdf, .rdlinks, .crawljob). An NZB lands as an import in the
LinkGrabber, a torrent as a LinkGrabber package, a container through the
LinkGrabber's container import. A container only its
content type announced is handed over with the matching ending added. A DLC or CCF needs DLC
import switched on in the settings; otherwise the browser keeps it and the notice says why.
Anything else β a ZIP of photos, an expired session's login page β is refused and stays in the
browser without a notice; any other failure says why and leaves the browser its copy. The
browser's copy is removed only after rDownloader took the file. An NZB that also reaches a watched
folder on the browser's download folder is still one import.
Repeating such a request needs its body, and the extension does not read request bodies β it does not ask for that permission.
A POST the extension observed is kept by the browser, which finishes it, and the notification
says why.
A default installation cannot tell a POST from a GET. The browsers' download API does not
name the method, and the extension observes requests only for addresses it holds host access for β
normally none. Such a download is handed over as a GET, and a site that answers a GET
differently gets the wrong request. If a download from a form does not arrive, keep it in the
browser through the notification's action.
Where the extension does hold host access for the address but finds no matching request among
the last fifty it observed, the download is kept by the browser and says so: it may have been a
form request that must not be repeated as a GET.
A hoster page with a Click'n'Load button asks http://127.0.0.1:9666/ whether a downloader
listens, and shows its button only if one answers. Without the desktop agent β
rDownloader on a NAS, a computer without the agent β nothing does. The extension answers in its
place:
- Only on the sites you allowed under Files from a site you allow; every other page is left alone.
- The agent first. The extension checks the port whenever a page looks for it and once a minute. While anything answers there β the desktop agent or another Click'n'Load program β the extension answers nothing and hands nothing over.
- The page sees its button as usual. Its links go to the LinkGrabber with the package name and the
first password, and a notification says how many arrived, or why rDownloader refused them. The
page's key (
jk) is never run in the browser: rDownloader reads or evaluates it in its own sandbox. The page hears success either way. - Accept Click'n'Load without the desktop agent in the options switches it off; it is on by default and needs the pairing. A page that posts with a header of its own still needs the agent.
Send file to rDownloaderβ¦ β in the popup, in a page's context menu and in the toolbar button's
own menu β opens a page of the extension with Drop files here and or choose filesβ¦. Drop
or choose one or several NZBs, torrents, ZIPs of NZBs and link containers (.dlc, .ccf,
.rsdf, .rdlinks, .crawljob); each goes to rDownloader like a file from an allowed site, and
the whole selection ends in one notice: how many went over, which were refused and why. A file of
another type is refused before it is sent and named in that notice. A sealed .rdlinks cannot be
opened this way, since the page asks for no passphrase; import it in the LinkGrabber. Nothing here
needs the desktop agent.
Share session for this site with rDownloader, in the page's context menu only, asks the browser
for the cookies permission together with a host permission for that one site β in Firefox, in
the same prompt, also for sharing authentication information β reads the cookies
the browser would send to the page you are looking at, and posts them to rDownloader.
The profile arrives disabled and has to be approved in the web interface. No cookie value is ever shown in a notification or written to a log.
What is read is what the browser would send to that address, including cookies a parent domain
set (a login cookie is usually set on .hoster.com while you are on www.hoster.com).
By default the share also covers the site's subdomains, and the permission it asks for says so; a share without them reads only the page's own cookies and asks for less.
The service cannot read your browser's cookies. So where a provider accepts a cookie session β DDownload, KatFile and FileJoker β a provider account offers Take over from browser in Settings β Accounts, and the request goes to the extension:
- The account says it is waiting for the extension, and whether one has checked in recently. Without one, the session cannot arrive. Withdraw request takes it back.
- The extension announces the request with a notification, and its popup lists it under Requested sessions, naming the site and the account.
-
Hand over this session is your consent. The browser then asks for the
cookiespermission and that one site β Firefox also for sharing authentication information; both are released again after the read. Decline tells rDownloader the session will not come. - The cookies arrive, are stored encrypted with the account, and the account is checked at once.
The site is always the one the provider's plugin declares β neither a page nor the popup can name
another. Only cookies of that host, or of a domain above it, are sent, and only to your paired
rDownloader; the service refuses the whole set if a single cookie lies outside the site or is set
for a public suffix such as com. A browser with no cookies for the site says so: sign in there
first. When the service refuses a handover, the popup names the reason. A request nobody answers
expires after five minutes and does not survive a restart.
Intercepted browser downloads count as their own intake source in the routing rules, so they can be sent to a different category from links you send through the context menu.
Everything the extension sends goes only to the rDownloader you paired it with β never to us or anyone else β and only when you or a page you allowed hands something over:
- Addresses β the links, pages and selected links you send from the context menu, the popup or the clipboard, and the downloads it takes over, with the download's referrer and the browser's user agent.
- Page content handed over β text you select and send, whose links rDownloader extracts; on a site you allowed, a Click'n'Load request's fields: the encrypted links, the key, the package name and the archive passwords; NZB, torrent and container files from an allowed site or chosen under Sending a local file.
- Cookies of one site β only for a session share, a session handover to an account or a file hand-over from a site you allowed, each after the browser's permission prompt for that site.
In Firefox, no cookie leaves the browser without your consent to share authentication
information. It is asked for in the same prompt as the site's cookies, checked again before
every cookie read, and given back together with the cookies permission. Declined or taken back β
in about:addons β Permissions and data β a session share and a handover end as refused, and a
file hand-over says its consent is incomplete. Chrome has no such category; there the permission
prompt for the site is the consent.
Granted on installation: activeTab, contextMenus, storage, notifications, clipboardRead,
downloads, webRequest, alarms, scripting β menu entries, settings, notices, the clipboard
action, pausing and observing a download, and polling for captchas after the browser has put the
extension to sleep.
Asked for only when you use the feature, and revocable at any time:
| Optional | Why |
|---|---|
cookies |
Sharing a site's session for one origin you pick, or handing a hoster session to an account for the one site its provider declares; never for all sites, and given back after a handover. Kept while a site is allowed to hand files over, which reads the cookies for one download address at a time. Firefox asks for the optional consent to share authentication information with it |
| Host permissions | Reaching a server the manifest does not already cover; per captcha, for one hoster origin, released again once answered β opening that page to answer a widget; and each site you allow to hand files over, until you revoke it |
Granted on installation as well: the host permissions http://127.0.0.1:9666/* and
http://localhost:9666/*, so the extension can ask whether something answers the Click'n'Load
port and see a page's requests to it.
The Firefox build additionally carries webRequestBlocking and webRequestFilterResponse, which
copying a response and answering Click'n'Load take; neither reaches a site without the host grant
above. The Chrome build carries declarativeNetRequestWithHostAccess, which answers Click'n'Load
there β again only for an allowed site.
The manifest declares http://*/* and https://*/* as optional host permissions only so that a
single origin can be requested; neither is granted at install time, and every grant is for one
origin at a time.
Reference in the repository:
extension/README.md