MagnetUri
Parsing and formatting of magnet: URIs: a pure-Kotlin port of parse_magnet_uri and make_magnet_uri from libtorrent's src/magnet_uri.cpp.
The grammar handled is BitTorrent's flavour of the magnet scheme:
magnet:?xt=urn:btih:<40-hex|32-base32> v1 info-hash
&xt=urn:btmh:1220<64-hex> v2 info-hash (BEP 52)
&dn=<display name> (URL-encoded)
&tr=<tracker url> (URL-encoded, repeatable)
&ws=<web seed url> (URL-encoded, repeatable, BEP 19)
&x.pe=<host:port> peer (repeatable)
&dht=<host:port> DHT node (repeatable)
&so=<index ranges> select-only file indices (BEP 53)Faithful details carried over from the C++:
A parameter name may carry a
.<number>suffix (e.g.tr.1); the suffix is stripped only when every character after the period is a digit, sox.pekeeps its.pe.Names are matched case-insensitively (ASCII).
For
xt, the value is URL-decoded only if it actually contains a%.A
trvalue must URL-decode cleanly and pass isValidTrackerUrl to be accepted.The link must contain at least one usable info-hash, otherwise parsing fails with LibtorrentError.MISSING_INFO_HASH_IN_URI. A malformed info-hash fails with LibtorrentError.INVALID_INFO_HASH, and a non-
magnet:?input with LibtorrentError.UNSUPPORTED_URL_PROTOCOL.
Types
Result of parseMagnetUriOrNull: exactly one of link / error is non-null.
Functions
libtorrent's is_valid_tracker_url (src/parse_url.cpp). Rejects empty URLs, any URL containing a control character or space (RFC 3986 + CRLF-injection defence), and anything not beginning (case-insensitively) with http://, https://, or udp://. The remaining structural check from the C++ (parse_url_components succeeding) is reproduced by parseUrlComponentsOk.
Format a magnet: URI for info: a port of make_magnet_uri(torrent_info const&) (which forwards to make_magnet_uri(add_torrent_params const&)) in src/magnet_uri.cpp.
Format a magnet: URI from explicit pieces: the analogue of make_magnet_uri(add_torrent_params const&) for callers that do not have a TorrentInfo. At least one of infoHashV1 / infoHashV2 must be non-null or "" is returned. dhtNodes are emitted as dht=host:port and peers verbatim as x.pe=… (already in host:port text form), matching the C++.
Parse a magnet: uri into a MagnetLink. Throws TorrentException on any of the fatal conditions libtorrent flags through error_code (bad scheme, malformed info-hash, or no info-hash at all). Mirrors the throwing overload parse_magnet_uri(string_view) in src/magnet_uri.cpp.
Non-throwing variant: returns a Result whose Result.error is set when parsing failed (and Result.link is null), or whose Result.link is the parsed link and Result.error is null on success. Mirrors the parse_magnet_uri(string_view, add_torrent_params&, error_code&) overload.