2014-05-13 17:57:46 +00:00
|
|
|
|
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
namespace MonoTorrent
|
|
|
|
{
|
|
|
|
public class MagnetLink
|
|
|
|
{
|
2019-12-22 22:08:53 +00:00
|
|
|
public RawTrackerTier AnnounceUrls
|
|
|
|
{
|
2014-05-13 17:57:46 +00:00
|
|
|
get; private set;
|
|
|
|
}
|
|
|
|
|
2019-12-22 22:08:53 +00:00
|
|
|
public InfoHash InfoHash
|
|
|
|
{
|
2014-05-13 17:57:46 +00:00
|
|
|
get; private set;
|
|
|
|
}
|
|
|
|
|
2019-12-22 22:08:53 +00:00
|
|
|
public string Name
|
|
|
|
{
|
2014-05-13 17:57:46 +00:00
|
|
|
get; private set;
|
|
|
|
}
|
|
|
|
|
2019-12-22 22:08:53 +00:00
|
|
|
public List<string> Webseeds
|
|
|
|
{
|
2014-05-13 17:57:46 +00:00
|
|
|
get; private set;
|
|
|
|
}
|
|
|
|
|
2019-12-22 22:08:53 +00:00
|
|
|
public MagnetLink(string url)
|
2014-05-13 17:57:46 +00:00
|
|
|
{
|
2019-12-22 22:08:53 +00:00
|
|
|
Check.Url(url);
|
|
|
|
AnnounceUrls = new RawTrackerTier();
|
|
|
|
Webseeds = new List<string>();
|
2014-05-13 17:57:46 +00:00
|
|
|
|
2019-12-22 22:08:53 +00:00
|
|
|
ParseMagnetLink(url);
|
2014-05-13 17:57:46 +00:00
|
|
|
}
|
|
|
|
|
2019-12-22 22:08:53 +00:00
|
|
|
void ParseMagnetLink(string url)
|
2014-05-13 17:57:46 +00:00
|
|
|
{
|
2019-12-22 22:08:53 +00:00
|
|
|
string[] splitStr = url.Split('?');
|
2014-05-13 17:57:46 +00:00
|
|
|
if (splitStr.Length == 0 || splitStr[0] != "magnet:")
|
2019-12-22 22:08:53 +00:00
|
|
|
throw new FormatException("The magnet link must start with 'magnet:?'.");
|
2014-05-13 17:57:46 +00:00
|
|
|
|
|
|
|
if (splitStr.Length == 1)
|
|
|
|
return;//no parametter
|
|
|
|
|
2019-12-22 22:08:53 +00:00
|
|
|
string[] parameters = splitStr[1].Split('&', ';');
|
2014-05-13 17:57:46 +00:00
|
|
|
|
2019-12-22 22:08:53 +00:00
|
|
|
for (int i = 0; i < parameters.Length; i++)
|
2014-05-13 17:57:46 +00:00
|
|
|
{
|
2019-12-22 22:08:53 +00:00
|
|
|
string[] keyval = parameters[i].Split('=');
|
2014-05-13 17:57:46 +00:00
|
|
|
if (keyval.Length != 2)
|
2019-12-22 22:08:53 +00:00
|
|
|
throw new FormatException("A field-value pair of the magnet link contain more than one equal'.");
|
2014-05-13 17:57:46 +00:00
|
|
|
switch (keyval[0].Substring(0, 2))
|
|
|
|
{
|
|
|
|
case "xt"://exact topic
|
|
|
|
if (InfoHash != null)
|
2019-12-22 22:08:53 +00:00
|
|
|
throw new FormatException("More than one infohash in magnet link is not allowed.");
|
2014-05-13 17:57:46 +00:00
|
|
|
|
|
|
|
string val = keyval[1].Substring(9);
|
|
|
|
switch (keyval[1].Substring(0, 9))
|
|
|
|
{
|
|
|
|
case "urn:sha1:"://base32 hash
|
|
|
|
case "urn:btih:":
|
2019-12-22 22:08:53 +00:00
|
|
|
if (val.Length == 32)
|
|
|
|
InfoHash = InfoHash.FromBase32(val);
|
|
|
|
else if (val.Length == 40)
|
|
|
|
InfoHash = InfoHash.FromHex(val);
|
|
|
|
else
|
|
|
|
throw new FormatException("Infohash must be base32 or hex encoded.");
|
|
|
|
break;
|
2014-05-13 17:57:46 +00:00
|
|
|
}
|
2019-12-22 22:08:53 +00:00
|
|
|
break;
|
|
|
|
case "tr"://address tracker
|
2014-05-13 17:57:46 +00:00
|
|
|
var bytes = UriHelper.UrlDecode(keyval[1]);
|
|
|
|
AnnounceUrls.Add(Encoding.UTF8.GetString(bytes));
|
2019-12-22 22:08:53 +00:00
|
|
|
break;
|
2014-05-13 17:57:46 +00:00
|
|
|
case "as"://Acceptable Source
|
2019-12-22 22:08:53 +00:00
|
|
|
Webseeds.Add(keyval[1]);
|
|
|
|
break;
|
2014-05-13 17:57:46 +00:00
|
|
|
case "dn"://display name
|
|
|
|
var name = UriHelper.UrlDecode(keyval[1]);
|
|
|
|
Name = Encoding.UTF8.GetString(name);
|
2019-12-22 22:08:53 +00:00
|
|
|
break;
|
2014-05-13 17:57:46 +00:00
|
|
|
case "xl"://exact length
|
|
|
|
case "xs":// eXact Source - P2P link.
|
|
|
|
case "kt"://keyword topic
|
|
|
|
case "mt"://manifest topic
|
2019-12-22 22:08:53 +00:00
|
|
|
//not supported for moment
|
|
|
|
break;
|
2014-05-13 17:57:46 +00:00
|
|
|
default:
|
|
|
|
//not supported
|
2019-12-22 22:08:53 +00:00
|
|
|
break;
|
2014-05-13 17:57:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|